DOM元素的特性与属性,返本求源

返本求源——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。

每一个要素都有3个或多个特征,那一个特色的用途是提交相应成分或其内容的附加新闻。通过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是1个布尔值,用来指示该性子是不是被分明设置。

document.createAttribute方法可以用来成立脾性节点。例如,要为成分添加align个性可以使用如下方法:

DOM元素的特性与属性,返本求源。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

一得之见

  上一篇返本求源中,大家从DOM基础的角度出发,总括了特色与性能的关联。本文中,大家来探视dojo框架是如何处理特性与品质的。dojo框架中性格的处理位于dojo/dom-attr模块属性的拍卖为与dojo/dom-prop模块中。

1.介绍:

上篇js便签笔记最后提到了dom元素的Attribute和Property,本文不难介绍一下本人的知道。

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

 

简单易行明了,Attribute就是dom节点自带的属性,例如html中常用的id、class、title、align等:

图片 7

而Property是那么些DOM成分作为对象,其附加的情节,例如childNodes、firstChild等:

图片 8

 

  很多前端类库(比如dojo与JQuery)在论及dom操作时都会见到七个模块:attr、prop。某天代码复查时,见到一段为某节点设置文本的代码:

attr.set()

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");

 

attr.set(node, 'innerText', 'Hello World!')

  方法的函数签名为:

3.取值与赋值:

3.1. Attribute取值:

上一篇博客已经涉嫌,可以由此div1.Attributes赢得具有的天性消息,div1.Attributes将回来3个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要做1个测试,看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对象,有趣味可以精晓以下。那不是本文的要害,不做赘述。

 

  那段代码执行后并未生效,虽说innerText不是正规属性,尚未被ff接济,可用的是chrome,这几个特性是被接济的。既然突显的文书没变,那就翻开一下因素呢。

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

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了,我们揣度就能赢得答案。。。

 

图片 14

  “someAttr”代表天性名称,但偶尔也足以是有的与众不一致的属性名,如:‘textContent’:

5.总结:

正文简单介绍了DOM成分的特色(Attribute)和属性(Property),下边说一说重点条目:

  • 特色和性质二者的储存方式不一致;
  • “2.脚踏三只船”要询问;
  • DOM属性恐怕会招致循环引用内存泄漏。

 

就写到那里呢,大家认为有亟待补给的,尽管提议意见!

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

  图片 15

  以上的那么些小案例就提到到了DOM操作时常常被忽略的一个难点:性情与品质的区分

  能够看到上图中应用attr设置innerText只会在html标签中加进innerText那个自定义性子,而不可以改观文本,使用textContent却可以完毕改变文本的目的。其中原因就是因为在attr模块建立了forceProps字典,在此字典中的key全体行使prop模块来安装:

 

        forcePropNames = {
            innerHTML:    1,
            textContent:1,
            className:    1,
            htmlFor:    has("ie"),
            value:        1
        }

 

  set()方法中任重(英文名:rèn zhòng)而道远处理以下几件事:

返本求源

  • “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
    };
    

    在DOM中,特性指的是html标签上的属性,比如:

 

发表评论

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

网站地图xml地图