返本求源

DOM成分querySelectorAll大概让您想不到的性状表现

2015/11/07 · HTML5 ·
DOM,
querySelectorAll

初稿出处:
张鑫旭   

返本求源——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操作时日常被忽视的3个题材:天性与质量的不一样

返本求源

在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。

每1个要素都有三个或八个天性,这几个特色的用途是付出相应成分或其情节的叠加音讯。通过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是3个布尔值,用来指示该脾气是还是不是被强烈设置。

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类型的实例。成分的每2性情故事情节点都保存在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

一得之见

在价值观的 JavaScript 开发中,查找 DOM
往往是开发人士遭逢的首先个胃痛的题材,原生的 JavaScript 所提供的 DOM
接纳方式并不多,仅仅局限于通过 tag, name, id
等办法来寻觅,那鲜明是遥远不够的,如果想要进行更进一步纯粹的选料只好采取看起来极度麻烦的正则表明式,或许接纳有个别库。事实上,以后颇具的浏览器厂商都提供了
querySelector 和 querySelectorAll 那多个办法的支撑,甚至就连微软也派遣了
IE 8 作为协理这一风味的表示,querySelector 和 querySelectorAll 作为查找
DOM 的又一途径,极大地惠及了开发者,使用它们,你可以像使用 CSS
采纳器一样便捷地查找到你须求的节点。

一 、时间燃眉之急,废话少说

正文所在的页面藏匿了上面这几个代码:

<img id=”outside”> <div id=”my-id”> <img id=”inside”>
<div class=”lonely”></div> <div class=”outer”> <div
class=”inner”></div> </div> </div>

1
2
3
4
5
6
7
8
<img id="outside">
<div id="my-id">
    <img id="inside">
    <div class="lonely"></div>
    <div class="outer">
        <div class="inner"></div>
    </div>
</div>

就是上边那样的彰显(为了便利寓目,我加了边框背景观和文字):

图片 7

第三说点我们都知情的热热身。

  • querySelectorquerySelectorAll IE8+浏览器匡助。
  • querySelector归来的是单个DOM成分;querySelectorAll回去的是NodeList.
  • 我们一般用的多的是document.querySelectorAll,
    实际上,也支持dom.querySelectorAll.例如:
JavaScript

document.querySelector("\#my-id").querySelectorAll("img")

<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-5b8f2fbc48034065158916-1">
1
</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-5b8f2fbc48034065158916-1" class="crayon-line">
document.querySelector(&quot;#my-id&quot;).querySelectorAll(&quot;img&quot;)
</div>
</div></td>
</tr>
</tbody>
</table>

分选的就是中间那几个妹子。例如,作者在决定台出口该采纳NodeList的长度和id,如下截图:
图片 8

好了,上边都以醒目标,好,上面初始显示点有意思的。

世家看下上面2行简单的查询语句:

JavaScript

document.querySelectorAll(“#my-id div div”);

1
document.querySelectorAll("#my-id div div");

JavaScript

document.querySelector(“#my-id”).querySelectorAll(“div div”);

1
document.querySelector("#my-id").querySelectorAll("div div");

图片 9

问问:上边七个语句再次回到的NodeList的内容是不是是一样的?

给大家1分钟的光阴思考下。

//zxx: 尽管1分钟已经亡故了

好了,答案是:差距的。臆度不少人跟自个儿同一,会以为是如出一辙的。

实际上:

JavaScript

document.querySelectorAll(“#my-id div div”).length === 1;

1
document.querySelectorAll("#my-id div div").length === 1;

JavaScript

document.querySelector(“#my-id”).querySelectorAll(“div div”).length ===
3;

1
document.querySelector("#my-id").querySelectorAll("div div").length === 3;

大家只要有疑问,可以在控制台测试下,下图就是自身自个儿测试的结果:

图片 10

缘何会如此?

先是个适合大家的接头,不解释。那下二个讲话,为什么再次来到的NodeList长度是3呢?

首先,遍历该NodeList会意识,查询的多个dom成分为:div.lonelydiv.outerdiv.inner.

哪个人知,奇怪,怎么会是一个呢?

jQuery中有个find()方式,大家很大概受到那一个点子影响,导致出现了一部分体会的难点:

JavaScript

$(“#my-id”).find(“div div”).length === 1;

1
$("#my-id").find("div div").length === 1;

若是运用find方法,则是1个相当;由于社团和职能类似,大家很自然疑问原生的querySelectorAll也是那一个套路。真是太错特错!!

要解释,为何NodeList长度是3,只要一句话就可以了,作者尤其加粗标红:

CSS接纳器是单独于整个页面的!

怎么着意思呢?比如说你在页面很深的3个DOM里面写上:

<style> div div { } </style>

1
2
3
<style>
div div { }
</style>

 

整整网页,包涵父级,只假诺满意div div父子关系的要素,全体会被选中,对啊,这么些我们应该都了解的。

这里的querySelectorAll里头的采用器也一致是那也全局性情。document.querySelector("#my-id").querySelectorAll("div div")翻译成白话文就是:查询#my-id的子成分,同时满意全体页面下div div选用器条件的DOM成分们。

大家页面往上滚动看看原始的HTML结构,会意识,在大局视野下,div.lonelydiv.outerdiv.inner整套都满意div div本条采用器条件,于是,最后回到的长短为3.

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

  querySelector

二 、:scope与区域采取范围

其实,要想querySelectorAll背后拔取器不受全局影响,也是有艺术的,就是使用近日还地处试验阶段的:scope伪类,其出力就是让CSS是在某一限制内采纳。此伪类在CSS中使用是元宝,可是也足以在querySelectorAll语句中运用:

JavaScript

document.querySelector(“#my-id”).querySelectorAll(“:scope div div”);

1
document.querySelector("#my-id").querySelectorAll(":scope div div");

包容性如下:

图片 11

本身写此文时候是15年11月底,目前大致就FireFox浏览器支持,小编算计,今后,会协助更多的。为啥吧?

因为Web
Components需求它,可以兑现真正独立包装,不会受外界影响的HTML组件。

关于:scope此时此刻支撑尚浅,时机未到,作者就没必要乱展开了,点到甘休。

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

querySelector 和 querySelectorAll
的选择越发的简单,就像标题说到的一模一样,它和 CSS
的写法完全一样,对于前端开发人员的话,那是难度大致为零的一遍学习。假若我们有3个id 为 test 的 DIV,为了取得到那些成分,你只怕会像下边那样:

叁 、结语仍然要的

参考小说:querySelectorAll from an element probably doesn’t do what you
think it
does

多谢阅读,欢迎纠错,欢迎互换!

1 赞 1 收藏
评论

图片 12

  那段代码执行后不曾生效,虽说innerText不是专业属性,尚未被ff协理,可用的是chrome,这些天性是被帮衬的。既然突显的文本没变,那就翻开一下要素呢。

  document.getElementById("test");

图片 13

近期大家来试试使用新章程来得到那些 DIV:

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

  document.querySelector("#test");
  document.querySelectorAll("#test")[0];

  以上的这一个小案例就关乎到了DOM操作时日常被忽略的三个题材:天性与性格的分别

取得文档中 class=”example” 的率先个

 

元素:

 

  document.querySelector("p.example");

返本求源

获取文档中有 “target” 属性的第3个 成分:

    在DOM中,脾气指的是html标签上的质量,比如:

  document.querySelector("a[target]");

相关文章