微信号:FrontDev

介绍:分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯

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

2015-09-17 19:21 前端大全

(点击上方,可快速关注)


作者:木的树

网址:http://www.cnblogs.com/dojo-lzz/p/4781563.html


抛砖引玉


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


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


这段代码执行后并未生效,虽说innerText不是标准属性,尚未被ff支持,可用的是chrome,这个属性是被支持的。既然显示的文本没变,那就查看一下元素吧。



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


以上的这个小案例就涉及到了DOM操作时常常被忽略的一个问题:特性与属性的区别


返本求源


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



Property是对于某一类型特征的描述。可以这样理解,在DOM元素中可以通过点语法访问,又不是标准特性的都可以成为属性。


DOM中所有的节点都实现了Node接口。Node接口是在DOM1级中定义的,其中定义了一些用来描述DOM节点的属性和操作方法。



常见的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的形式来访问自定义特性,如:


<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特性可以使用如下方法:


ar attr = document.createAttribute('align')

attr.value = 'left'

seh.setAttributeNode(attr)


要将新创建的特性添加到元素上,必须使用元素的setAttributeNode方法。添加特性后,特性会反映在html标签上:



注意,尽管特性节点也实现了Node接口,但特性却不被认为是DOM文档树的一部分。


在所有的DOM节点中attributes属性是Element类型所独有的的属性。从技术角度来说,特性就是存在于元素的attributes属性中的节点。attributes属性属于NamedNodeMap类型的实例。元素的每一个特性节点都保存在NamedNodeMap对象中。NamedNodeMap类型拥有如下方法:


  • getNamedItem(name):返回特性名为name的特性节点

  • removeNamedItem(name):删除特性名为name的特性节点

  • setNamedItem(attr):像元素中添加一个特性节点

  • item(pos):返回位于数组pos处的节点


获取、设置、删除元素节点可以如下方式:


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三者关系应该这么画:



应用总结


基于以上DOM基础知识和实际工作经验,我将特性和属性的区别联系总结如下:


  • 属性以及公认特性可以通过点语法访问;html5规范中,data-*形式的自定义特性可以通过element.dataset.*的形式来访问,否则用getAttribute

  • 特性值只能是字符串,而属性值可以是任意JavaScript支持的类型

  • 几个特殊特性:


1.style,通过getAttrbute和setAttribute来操作这个特性只能得到或设置字符串;而已属性方式来操作就是在操作CSSStyleDeclaration对象


2.事件处理程序,通过特性方式得到和传递的都只是函数字符串;而已属性方式操作的是函数对象


3.value,对于支持value的元素,最好通过属性方式操作,而且操作不会反映在html标签上


seh.value = 10

<input type="text" name="as_q" class="box" id="searched_content" title="在此输入搜索内容。" disabled="false" data-ff="fsdf" align="left">


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


<a href="/jsref/prop_checkbox_tabindex.asp" id="tabI">tabIndex</a>

link.getAttribute('href') // "/jsref/prop_checkbox_tabindex.asp"

link.href // "http://www.w3school.com.cn/jsref/prop_checkbox_tabindex.asp"


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


<input type="text" name="as_q" class="box" id="searched_content" title="在此输入搜索内容。" disabled="false" data-ff="fsdf" align="left">

seh.disabled // true

seh.disabled = false

<input type="text" name="as_q" class="box" id="searched_content" title="在此输入搜索内容。" data-ff="fsdf" align="left">




前端大全

微信号:FrontDev

打造东半球最好的 前端技术 微信号

--------------------------------------

商务合作QQ:2302462408

投稿网址:top.jobbole.com

 
前端大全 更多文章 5个典型的JavaScript面试题(上) Limu:JavaScript的那些书 Web开发:我希望得到的编程学习路线图 JavaScript基础工具清单 常用排序算法之JavaScript实现
猜您喜欢 打破神话:数据显示你其实不需要一个联合创始人 Python Web部署方式总结 Dexposed:Android平台免Root无侵入AOP框架 Python学习之模块 Stack Overflow 2016最新架构探秘