上层建筑——DOM成分的表征与性格(dojo/dom-attr)

返本求源——DOM成分的特点与天性

2015/09/06 · HTML5,
JavaScript ·
DOM

原来的作品出处: 木的树   

投石问路

好些个前端类库(例如dojo与JQuery)在关系dom操作时都会面到五个模块:attr、prop。某天代码复查时,看到一段为某节点设置文本的代码:

JavaScript

attr.set(node, ‘innerText’, ‘Hello World!’)

1
attr.set(node, ‘innerText’, ‘Hello World!’)

这段代码实践后未有生效,虽说innerText不是正规属性,尚未被ff援救,可用的是chrome,这几个天性是被支持的。既然显示的公文没变,那就翻开一下成分呢。
图片 1

innerText被增加到了html标签上,而换到prop模块后,成功的为节点替换文本。

如上的那一个小案例就关乎到了DOM操作时平时被忽略的贰个主题素材:性格与品质的分别

返本求源

在DOM中,性子指的是html标签上的品质,譬喻:

图片 2

Property是对于某一品类特征的描述。能够这么敞亮,在DOM成分中可以通过点语法访问,又不是职业本性的都可以成为属性。

DOM中具备的节点都达成了Node接口。Node接口是在DOM1级中定义的,在那之中定义了有的用来陈述DOM节点的脾性和操作方法。

图片 3

广泛的nodeType、nodeValue、节点关系(parentNode、childNodes、firstChild、lastChild、previousSibling、nextSibling等)都属于Node接口定义的性质。对于Node接口的切实落实者,HTMLElement不独有继续了那几个属性,还保有多少个wac标准中的多个正式本性:id、title、lang、dir、class和三个属性:attributes。

每一个要素皆有一个或多特性状,这一个特色的用处是交由相应成分或其剧情的附加音讯。通过DOM成分直接操作性格的的不二等秘书籍有多个:

  • getAttribute(attrName)
  • setAttribute(attrName, value)
  • removeAttribute(name)

那五个方式都足以操作自定义性情。然则只有公众感到的(非自定义)个性才会以属性的样式足够到DOM对象中,以属天性局操作这么些特色会被同台到html标签中。HTMLElement的八个特点都有照应属性与其对待:id、title、lang、dir、className。在DOM中以属性情局操作那多少个特色会同步到html标签中。

不过,HTML5规范对自定义个性做了拉长,只要自定义本性以”data-attrName”的样式写入到html标签中,在DOM属性中就足以由此element.dataset.attrName的情势来拜谒自定义性情,如:

XHTML

<input type=​”text” name=​”as_q” class=​”box”
id=​”searched_content” title=​”在此输入寻找内容。” disabled=​”false”
data-ff=​”fsdf”>​ seh.dataset.ff

1
2
<input type=​"text" name=​"as_q" class=​"box" id=​"searched_content" title=​"在此输入搜索内容。" disabled=​"false" data-ff=​"fsdf">​
seh.dataset.ff

要素的特色在DOM中以Attr类型来表示,Attr类型也落到实处了Node接口。Attr对象有五个属性:name、value、specified。当中,name是特点的名称,value是特点值,specified是壹个布尔值,用来提示该性子是否被显眼设置。

document.createAttribute方法可以用来成立性剧情点。比方,要为成分增加align性格能够接纳如下方法:

JavaScript

ar attr = document.createAttribute(‘align’) attr.value = ‘left’
seh.setAttributeNode(attr)

1
2
3
ar attr = document.createAttribute(‘align’)
attr.value = ‘left’
seh.setAttributeNode(attr)

要将新创造的个性增多到元素上,必需使用要素的setAttributeNode方法。加多天性后,本性会反映在html标签上:

图片 4

小心,就算性子节点也完成了Node接口,但天性却不被感到是DOM文书档案树的一有些。

在全部的DOM节点中attributes属性是Element类型所独有的的习性。从本事角度来讲,个性正是存在于成分的attributes属性中的节点。attributes属性属于NamedNodeMap类型的实例。成分的每贰个特点节点都保存在NamedNodeMap对象中。NamedNodeMap类型具备如下方法:

  • getNamedItem(name):重回天性名称为name的特点节点
  • removeNamedItem(name):删除性子名称为name的风味节点
  • setNamedItem(attr):像成分中增添八个特征节点
  • item(pos):重临位于数组pos处的节点

收获、设置、删除成分节点能够如下格局:

JavaScript

element.attributes.getNamedItem(‘align’) //获取 var attr =
document.createAttribute(‘align’); attr.value = ‘right’;
element.attributes.setNamedItem(attr); //添加
element.attributes.removeNamedItem(‘align’); //删除

1
2
3
4
5
6
7
element.attributes.getNamedItem(‘align’) //获取
 
var attr = document.createAttribute(‘align’);
attr.value = ‘right’;
element.attributes.setNamedItem(attr); //添加
 
element.attributes.removeNamedItem(‘align’); //删除

实则选用中并不提出选拔性剧情点的法门,而getAttribute、setAttribute、removeAttribute方法远比操作性情节点更利于。

DOM、attributes、Attr三者关系应该如此画:

图片 5

使用总括

听说上述DOM基础知识和事实上中国人民解放军海军事工业程高校业作经验,笔者将特色和性质的区分联系总计如下:

  1. 品质以及公众承认本性能够通过点语法访谈;html5标准中,data-*情势的自定义个性能够由此element.dataset.*的款型来访谈,不然用getAttribute
  2. 特征值只可以是字符串,而属性值能够是狂妄JavaScript援助的类型
  3. 几个奇天性状:
    1. style,通过getAttrbute和setAttribute来操作那么些性格只好获取或设置字符串;而已属性情势来操作便是在操作CSSStyleDeclaration对象
    2. 事件管理程序,通过特征格局获取和传递的都只是函数字符串;而已属天性局操作的是函数对象
    3. value,对于支撑value的要素,最好通过质量方式操作,况且操作不会显示在html标签上
    XHTML

    seh.value = 10 &lt;input type="text" name="as\_q" class="box"
    id="searched\_content" title="在此输入搜索内容。"
    disabled="false" data-ff="fsdf" align="left"&gt;

    <table>
    <colgroup>
    <col style="width: 50%" />
    <col style="width: 50%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
    <div class="crayon-num" data-line="crayon-5b8f379c97d12396477911-1">
    1
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f379c97d12396477911-2">
    2
    </div>
    </div></td>
    <td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
    <div id="crayon-5b8f379c97d12396477911-1" class="crayon-line">
    seh.value = 10
    </div>
    <div id="crayon-5b8f379c97d12396477911-2" class="crayon-line crayon-striped-line">
    &lt;input type=&quot;text&quot; name=&quot;as_q&quot; class=&quot;box&quot; id=&quot;searched_content&quot; title=&quot;在此输入搜索内容。&quot; disabled=&quot;false&quot; data-ff=&quot;fsdf&quot; align=&quot;left&quot;&gt;
    </div>
    </div></td>
    </tr>
    </tbody>
    </table>

4.  href,通过属性方式设置可以反映到html标签上,但用过点语法和getAttribute能够取到的值并不一定相同


    XHTML

    &lt;a href="/jsref/prop\_checkbox\_tabindex.asp"
    id="tabI"&gt;tabIndex&lt;/a&gt; link.getAttribute('href') //
    "/jsref/prop\_checkbox\_tabindex.asp" link.href //
    "http://www.w3school.com.cn/jsref/prop\_checkbox\_tabindex.asp"

    <table>
    <colgroup>
    <col style="width: 50%" />
    <col style="width: 50%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
    <div class="crayon-num" data-line="crayon-5b8f379c97d15903857159-1">
    1
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f379c97d15903857159-2">
    2
    </div>
    <div class="crayon-num" data-line="crayon-5b8f379c97d15903857159-3">
    3
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f379c97d15903857159-4">
    4
    </div>
    <div class="crayon-num" data-line="crayon-5b8f379c97d15903857159-5">
    5
    </div>
    </div></td>
    <td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
    <div id="crayon-5b8f379c97d15903857159-1" class="crayon-line">
    &lt;a href=&quot;/jsref/prop_checkbox_tabindex.asp&quot; id=&quot;tabI&quot;&gt;tabIndex&lt;/a&gt;
    </div>
    <div id="crayon-5b8f379c97d15903857159-2" class="crayon-line crayon-striped-line">
     
    </div>
    <div id="crayon-5b8f379c97d15903857159-3" class="crayon-line">
    link.getAttribute('href') // &quot;/jsref/prop_checkbox_tabindex.asp&quot;
    </div>
    <div id="crayon-5b8f379c97d15903857159-4" class="crayon-line crayon-striped-line">
     
    </div>
    <div id="crayon-5b8f379c97d15903857159-5" class="crayon-line">
    link.href // &quot;http://www.w3school.com.cn/jsref/prop_checkbox_tabindex.asp&quot;
    </div>
    </div></td>
    </tr>
    </tbody>
    </table>

5.  disabled和checked,对于支持这两个特性的元素来说,他们在html标签中都是无状态的,只要有独立的标签属性在以点语法访问时就返回true,如果html标签属性不存在,则以点语法访问时就是false


    XHTML

    &lt;input type=​"text" name=​"as\_q" class=​"box"
    id=​"searched\_content" title=​"在此输入搜索内容。"
    disabled=​"false" data-ff=​"fsdf" align=​"left"&gt;​
    seh.disabled // true seh.disabled = false &lt;input type=​"text"
    name=​"as\_q" class=​"box" id=​"searched\_content"
    title=​"在此输入搜索内容。" data-ff=​"fsdf" align=​"left"&gt;​

    <table>
    <colgroup>
    <col style="width: 50%" />
    <col style="width: 50%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
    <div class="crayon-num" data-line="crayon-5b8f379c97d19172676562-1">
    1
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f379c97d19172676562-2">
    2
    </div>
    <div class="crayon-num" data-line="crayon-5b8f379c97d19172676562-3">
    3
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f379c97d19172676562-4">
    4
    </div>
    <div class="crayon-num" data-line="crayon-5b8f379c97d19172676562-5">
    5
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f379c97d19172676562-6">
    6
    </div>
    </div></td>
    <td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
    <div id="crayon-5b8f379c97d19172676562-1" class="crayon-line">
    &lt;input type=​&quot;text&quot; name=​&quot;as_q&quot; class=​&quot;box&quot; id=​&quot;searched_content&quot; title=​&quot;在此输入搜索内容。&quot; disabled=​&quot;false&quot; data-ff=​&quot;fsdf&quot; align=​&quot;left&quot;&gt;​
    </div>
    <div id="crayon-5b8f379c97d19172676562-2" class="crayon-line crayon-striped-line">
     
    </div>
    <div id="crayon-5b8f379c97d19172676562-3" class="crayon-line">
    seh.disabled // true
    </div>
    <div id="crayon-5b8f379c97d19172676562-4" class="crayon-line crayon-striped-line">
     
    </div>
    <div id="crayon-5b8f379c97d19172676562-5" class="crayon-line">
    seh.disabled = false
    </div>
    <div id="crayon-5b8f379c97d19172676562-6" class="crayon-line crayon-striped-line">
    &lt;input type=​&quot;text&quot; name=​&quot;as_q&quot; class=​&quot;box&quot; id=​&quot;searched_content&quot; title=​&quot;在此输入搜索内容。&quot; data-ff=​&quot;fsdf&quot; align=​&quot;left&quot;&gt;​
    </div>
    </div></td>
    </tr>
    </tbody>
    </table>

1 赞 1 收藏
评论

图片 6

1.介绍:

上篇js便签笔记末段提到了dom成分的Attribute和Property,本文简要介绍一下本人的接头。

实际上Attribute和Property那多个单词,翻译出来都以“属性”,《js高档程序设计》书中翻译为“性子”和“属性”,以示差异。

 

简轻便单精晓,Attribute正是dom节点自带的性情,比如html中常用的id、class、title、align等:

图片 7

而Property是其一DOM成分作为靶子,其附加的从头到尾的经过,比如childNodes、firstChild等:

图片 8

 

  上一篇疏解dojo/dom-attr的文章中大家精通在少数情状下,attr模块中会交给prop模块来管理。譬喻:

  上一篇返本求源中,大家从DOM基础的角度出发,总结了特色与质量的涉嫌。本文中,大家来走访dojo框架是怎样管理性子与品质的。dojo框架中性子的管理位于dojo/dom-attr模块属性的拍卖为与dojo/dom-prop模块中。

2.“足踏三只船”:

另外,常用的Attribute,比如id、class、title等,已经被用作Property附加到DOM对象上,能够和Property同样取值和赋值。不过自定义的Attribute,就不会有这么的特种优待,比方:

<div id="div1" class="divClass" title="divTitle" title1="divTitle1">100</div>

本条div里面包车型大巴“title1”就不会形成Property。

即,只假若DOM标签中冒出的性质(html代码),都以Attribute。然后有些常用脾气(id、class、title等),会被转正为Property。能够很形象的说,这几个特征/属性,是“足踏五只船”的。

图片 9

图片 10

 

末尾注意:“class”产生Property之后叫做“className”,因为“class”是ECMA的重要字。以下代码等价:

1 var className = div1.className;
2 var className1 = div1.getAttribute("class");

 

  • textContent、innerHTML、className、htmlFor、value
  • disabled、checked等无状态性格对应于属性中的布尔变量
  • 事件的拍卖

attr.set()

3.取值与赋值:

3.1. Attribute取值:

上一篇博客曾经提到,能够因此div1.Attributes取得具备的脾性新闻,div1.Attributes将回来三个NamedNodeList类数组,在那之中蕴涵了若干个Attr类型的目的。《js高档程序设计》中提到,为了有扶助操作,建议大家用setAttribute()和getAttribute()来操作就能够。

1 <div id="div1" class="divClass" title="divTitle" align="left" title1="divTitle1"></div>
2 
3 var id = div1.getAttribute("id");              
4 var className1 = div1.getAttribute("class");
5 var title = div1.getAttribute("title");
6 var title1 = div1.getAttribute("title1");   //自定义特性

getAttribute()能够获得别的天性,不管是行业内部的依然自定义的。

只是这几个措施的浏览器宽容性有标题,有个别浏览器大概会收获属性Property的值,因而jQuery要做一个测量试验,看getAttribute()是不是是相对获取性情Attribute的值。

div1.className = 'a';
var judge = div1.getAttribute("className") === 'a';

只要上述代码创造,表明getAttribute()方法出现了难题,将不再动用。

3.2. Attribute赋值:

1 div1.setAttribute('class', 'a');
2 div1.setAttribute('title', 'b');
3 div1.setAttribute('title1', 'c');
4 div1.setAttribute('title2', 'd');

用setAttrbute()赋值,任何Attribute都足以,包蕴自定义的。何况,赋值的Attribute会立即表现到DOM元素上。

图片 11

借使是正规性格,也会更新它们关联的天性的值:

图片 12

末段注意,setAttribute()的多少个参数,都无法不是字符串。即对特色Attribute职能赋值字符串,而对品质Property就能够赋任何项目标值了。

 

3.3. Property取值:

脾性取值很简短。取任何性质的只,用“.”就足以:

1 var id = div1.id;
2 var className = div1.className;
3 var childNodes = div1.childNodes;
4 var attrs = div1.attributes;

此处再一次重申:

先是,class天性在成为属性时,名字改成了“className”,因而div1.className和div1.getAttrbute(‘class’)一样。

其次,上面代码中的div1.attributes是取的attributes这一属性,抽出来保存到attrs变量中,attrs就成了三个NamedNodeList类型的靶子,里面积攒了大多个Attr类型。

 

3.4. Property赋值:

赋值和宗旨的js对象属性赋值同样,用“.”就能够:

div1.className = 'a';
div1.align = 'center';
div1.AAAAA = true;
div1.BBBBB = [1, 2, 3];

对质量Property能够赋任何类型的值,而对特色Attribute只可以赋值字符串!

除此以外,对于属性Property的赋值在IE中或然会挑起循环援引,内部存款和储蓄器泄漏。为了防御那么些标题,jQuery.data()做了卓越管理,解耦了数据和DOM对象,风野趣能够通晓以下。那不是本文的最重要,不做赘述。

 

  那这一节,大家便来走访prop对于属性的拍卖。

  方法的函数具名叫:

4.style和onclick:

骨子里style和onclick与id、class、title同样,也是“脚踩四只船”,不过向id、class、title都是大概的字符串值,用“.”和getAttribute()获取结果一致。可是对于style和onclick这两个,就不一样样了。

4.1. 用“.”获取Style:

<div id="div1" class="divClass" style="width:100%; padding:10px;">100</div>

console.log(div1.style);

如上代码中,再次来到了一个CSSStyleDeclaration对象,这些目的中包含着体制的兼具新闻:

图片 13

 

4.2. 用getAttribute()获取style:

<div id="div1" class="divClass" style="width:100%; padding:10px;">100</div>

console.log(div1.getAttribute("style"));

上述代码重回的便是叁个简单易行的字符串:“width:百分百; padding:10px;”

 

4.3. 总结:

上面四个例子,用“.”获取的是style属性Property,我们得以给属性Property赋任何类型的值;而用getAttribute()获取的是特色Attribute,脾气Attribute中不得不存贮字符串。两个的数据结构不等同,导致重回的结果不等同。

到这里,大家就无需再演示用“.”和getAttribute()获取onclick了,大家估摸就能够获得答案。。。

 

 

require(["dojo/dom-attr"], function(domAttr){
  result = domAttr.set("myNode", "someAttr", "value");
});

5.总结:

正文简要介绍了DOM成分的特征(Attribute)和质量(Property),上面说一说入眼条目款项:

  • 特点和性子二者的囤积形式不相同;
  • “2.足踏两只船”要询问;
  • DOM属性大概会促成循环引用内部存款和储蓄器泄漏。

 

就写到这里吧,我们感到有需求补充的,纵然提议意见!

  首先是二个正经名称字典,将在设置的性质名重新命名,制止与保留字的争辨:

  “someAttr”代表性子名称,但不常候也得以是某个特殊的属性名,如:‘textContent’:

exports.names = {
        // properties renamed to avoid clashes with reserved words
        "class": "className",
        "for": "htmlFor",
        // properties written as camelCase
        tabindex: "tabIndex",
        readonly: "readOnly",
        colspan: "colSpan",
        frameborder: "frameBorder",
        rowspan: "rowSpan",
        textcontent: "textContent",
        valuetype: "valueType"
    };

  图片 14

  比较dom-attr来讲,dom-prop模块唯有五个国有函数:prop.get与prop.set

  能够看出上海教室中央银行使attr设置innerText只会在html标签中加进innerText那一个自定义本性,而不恐怕改观文本,使用textContent却可以完结退换文本的目标。其中原因正是因为在attr模块建设构造了forceProps字典,在此字典中的key全体使用prop模块来安装:

  prop.get方法的函数签字为:

        forcePropNames = {
            innerHTML:    1,
            textContent:1,
            className:    1,
            htmlFor:    has("ie"),
            value:        1
        }
// Dojo 1.7+ (AMD)
require(["dojo/dom-prop"], function(domProp){
  result = domProp.get("myNode", "someAttr");
});

  set()方法中首要性管理以下几件事:

  除了textContent属性外,其余间接以方括号语法从node中取值:node[prop];对于textContent属性,假诺成分不补助textContent,便以深度优先算法去获得成分下全体文件节点的nodevalue:

  • “someAttr”除了能够是字符串外,还足以是key-value对象,所以对于key-value对象我们第一要开展参数分解。
  • 一旦someAttr等于style,就交由dojo/dom-style模块来拍卖
  • 上篇作品中大家说过,个性值只好是字符串,所以对于函数,暗中认可是作为事件绑定到成分上,这有个别交给dojo/dom-prop来拍卖;别的对于disabled、checked等无状态的性子,在经过质量设置时,只好传递布尔值,所以那部分也提交prop来拍卖
  • 剩下的交给原生api,setAttribute来拍卖,这么些方法会自动调用value的toString方法

    exports.set = function setAttr(/DOMNode|String/ node, /String|Object/ name, /String?/ value){

        node = dom.byId(node);
        if(arguments.length == 2){ // inline'd type check
            // the object form of setter: the 2nd argument is a dictionary
            for(var x in name){
                exports.set(node, x, name[x]);
            }
            return node; // DomNode
        }
        var lc = name.toLowerCase(),
            propName = prop.names[lc] || name,
            forceProp = forcePropNames[propName];
        if(propName == "style" && typeof value != "string"){ // inline'd type check
            // special case: setting a style
            style.set(node, value);
            return node; // DomNode
        }
        if(forceProp || typeof value == "boolean" || lang.isFunction(value)){
            return prop.set(node, name, value);
        }
        // node's attribute
        node.setAttribute(attrNames[lc] || name, value);
        return node; // DomNode
    };
    
function getText(/*DOMNode*/node){
        var text = "", ch = node.childNodes;
        for(var i = 0, n; n = ch[i]; i++){
            //Skip comments.
            if(n.nodeType != 8){
                if(n.nodeType == 1){
                    text += getText(n);
                }else{
                    text += n.nodeValue;
                }
            }
        }
        return text;
    }

 

  因为innerText并非明媒正娶属性,所以那边弃之不用;以下就是get方法的源码:

attr.get()

exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){
        node = dom.byId(node);
        //转化成标准属性
        var lc = name.toLowerCase(), propName = exports.names[lc] || name;
    //处理textContent这种特殊属性
        if(propName == "textContent" && !has("dom-textContent")){
            return getText(node);
        }

        return node[propName];    // Anything
    };

  方法的函数签字为:

 

// Dojo 1.7+ (AMD)
require(["dojo/dom-attr"], function(domAttr){
  result = domAttr.get("myNode", "someAttr");
});

  prop.set方法的函数具名叫:

  为了表达方便,大家要先看一下get方法的源码:

require(["dojo/dom-prop"], function(domProp){
  result = domProp.set("myNode", "someAttr", "value");
});
exports.get = function getAttr(/*DOMNode|String*/ node, /*String*/ name){
        node = dom.byId(node);
        var lc = name.toLowerCase(),
            propName = prop.names[lc] || name,
            forceProp = forcePropNames[propName],
            value = node[propName];        // should we access this attribute via a property or via getAttribute()?

        if(forceProp && typeof value != "undefined"){
            // node's property
            return value;    // Anything
        }

        if(propName == "textContent"){
            return prop.get(node, propName);
        }

        if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){
            // node's property
            return value;    // Anything
        }
        // node's attribute
        // we need _hasAttr() here to guard against IE returning a default value
        var attrName = attrNames[lc] || name;
        return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
    };

  在attr.set方法中,比很多情况都交给prop来管理,上边大家将在看看prop中set方法的贯彻。

  1. 先获得的是多个变量:propName、forceProp、value,
  2. 假若attrName属于forceProps集结,直接回到DOM节点的天性
  3. textContent显然位于forceProps中,为啥还要单独拿出来做判断?因为有的低版本的浏览器不援救textContent,大家须要选择深度优先算法,利用文本的节点的nodeValue由父到子依次拼接文本,那或多或少jQuery与dojo的思绪都是一模一样的:

    1. dojo:

      function getText(/*DOMNode*/node){
              var text = "", ch = node.childNodes;
              for(var i = 0, n; n = ch[i]; i++){
                  //Skip comments.
                  if(n.nodeType != 8){
                      if(n.nodeType == 1){
                          text += getText(n);
                      }else{
                          text += n.nodeValue;
                      }
                  }
              }
              return text;
          }
      
    2. jQuery:图片 15

  4. set方法中涉及过,对于布尔跟函数,交给prop来设置,那么取值时当然也要从prop中来取;至于缘何要独自拿出href,在“返本求源”中已经说过,通过质量获得的href属性跟getAttribute方法获得的值并不一定同样,特别是非保加汉诺威语字符:图片 16
  5. 由prop模块该做的都做完了,所以那边剖断node中是还是不是存在该天性时,没有需求理会forceProps字典;借使存在则调用getAttribute方法。

  set方法用来为要素的天性赋值,在实际应用中须求管理以下三种状态:

 

  • 参数分解,如若三次设置四个属性,为种种属性分别安装
  • 假若someAttr是“style”,则交由dom-style模块管理
  • 就算someAttr是innerHTML,因为部分成分(tbody、thead、tfoot、tr、td、th、caption、colgroup、col)不帮忙innerHTML属性,所以需求曲线救国,这里首先将成分的子节点清除掉,然后采取dom-construct的toDom方法,将html片段转化成dom节点,作为子节点插入元素中
  • 借使someAttr是textContent,同样因为某些浏览器并不帮助该属性,曲线救国的方法是先化解成分的子节点,然后成立文本节点作为子节点插入成分中
  • 倘使value是function,则作为增添事件;对于event的拍卖特别不用使用prop模块照旧引入应用on模块来绑定事件

    exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
        node = dom.byId(node);
        var l = arguments.length;
        //分解参数
        if(l == 2 && typeof name != "string"){ // inline'd type check
            for(var x in name){
                exports.set(node, x, name[x]);
            }
            return node; // DomNode
        }
        //如果要设置style,调用dom-style来处理
        var lc = name.toLowerCase(), propName = exports.names[lc] || name;
        if(propName == "style" && typeof value != "string"){ // inline'd type check
            // special case: setting a style
            style.set(node, value);
            return node; // DomNode
        }
        //如果是innerHTML,对于不支持innerHTML的节点,采用曲线救国的方式,否则直接设置innerHTML
        if(propName == "innerHTML"){
            // special case: assigning HTML
            // the hash lists elements with read-only innerHTML on IE
            if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1,
                        table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){
                ctr.empty(node);
                node.appendChild(ctr.toDom(value, node.ownerDocument));
            }else{
                node[propName] = value;
            }
            return node; // DomNode
        }
        //如果不支持textContent,清除元素子节点后,添加文本节点
        if(propName == "textContent" && !has("dom-textContent")) {
            ctr.empty(node);
            node.appendChild(node.ownerDocument.createTextNode(value));
            return node;
        }
        //这一部分是通过prop来绑定事件,但并不建议用这种方式
        if(lang.isFunction(value)){
            // special case: assigning an event handler
            // clobber if we can
            var attrId = node[_attrId];
            if(!attrId){
                attrId = _ctr++;
                node[_attrId] = attrId;
            }
            if(!_evtHdlrMap[attrId]){
                _evtHdlrMap[attrId] = {};
            }
            var h = _evtHdlrMap[attrId][propName];
            if(h){
                //h.remove(); 如果曾经以类似的方式绑定过事件,则移除事件
                conn.disconnect(h);
            }else{
                try{
                    delete node[propName];
                }catch(e){}
            }
            // ensure that event objects are normalized, etc.
            if(value){//prop.get函数返回node,所以把handle放到_evtHdlrMap中
                //_evtHdlrMap[attrId][propName] = on(node, propName, value);
                _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value);
            }else{
                node[propName] = null;
            }
            return node; // DomNode
        }
        node[propName] = value; //直接为属性赋值
        return node;    // DomNode
    };
    

attr.has

  一经你认为那篇文章对你有帮忙,请不吝点击右下方“推荐”,谢谢~

  既然能够行使attr来set这么些属性,那在attr.has方法中,位于此字典中属性当然也要回去true,所以attr.has(node,
attrName)方法主要推断八个方面:

  • attrName是否是forceProps中的key
  • attrName是还是不是是贰个特色节点。性情节点为与成分的attributes属性中,能够通过:attributes[attrName]
    && attributes[attrName].specified 来判断

    exports.has = function hasAttr(/DOMNode|String/ node, /String/ name){

        var lc = name.toLowerCase();
        return forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name);    // Boolean
    };
    

    function _hasAttr(node, name){

        var attr = node.getAttributeNode && node.getAttributeNode(name);
        return !!attr && attr.specified; // Boolean
    }
    

  

attr.remove

  这一个方式比较轻易,直接调用了removeAttribute方法

exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){
        // summary:
        //        Removes an attribute from an HTML element.
        // node: DOMNode|String
        //        id or reference to the element to remove the attribute from
        // name: String
        //        the name of the attribute to remove

        dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name);
    };

  

  若果你以为那篇文章对你有援助,请不吝点击右下方“推荐”,谢谢~

发表评论

电子邮件地址不会被公开。 必填项已用*标注