DOM成分querySelectorAll大概让您意料之外的特点表现

DOM成分querySelectorAll可能让您意料之外的性状表现

2015/11/07 · HTML5 ·
DOM,
querySelectorAll

初藳出处:
张鑫旭   

1: dom对象的innerText和innerHTML有怎么着差距

innerText:
经过innerText读取值时,它会据守由表及里的各种将子文书档案树中的全部子文本节点拼接起来。在写入值时,会删除元素的享有字节点,插入富含文本节点与相应的文本值。

innerHTML:
在读方式下,innerHTML重回调用成分的全体子节点(包含成分,注释,文本节点)的呼应html标签。在写情势下,innerHTML会依赖钦命的值
创造新的DOM树,然后新建的DOM树会完全替换调用成分以前的全体子节点。

querySelector和querySelectorAll是W3C提供的新的查询接口

在观念的 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>

正是下面这样的呈现(为了方便观察,我加了边框背景象和文字):

澳门葡京 1

先是说点大家都晓得的热热身。

  • 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,如下截图:
澳门葡京 2

好了,上面都以分明的,好,上边开端显得点风趣的。

世家看下下边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");

澳门葡京 3

叩问:上边八个语句重回的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;

大家只要有问号,能够在调节台测量检验下,下图正是笔者本人测量检验的结果:

澳门葡京 4

缘何会那样?

首先个切合大家的接头,不表明。那下三个讲话,为何重回的NodeList长度是3呢?

首先,遍历该NodeList会发觉,查询的多个dom元素为:div.lonelydiv.outerdiv.inner.

出人意料,奇怪,怎么会是3个呢?

DOM成分querySelectorAll大概让您意料之外的特点表现。jQuery中有个find()方法,大家非常大概受到这一个方式影响,诱致现身了意气风发部分体会的难题:

JavaScript

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

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

假若运用find方法,则是1个极度;由于组织和功用相仿,我们很当然疑问原生的querySelectorAll也是其意气风发套路。真是太错特错!!

要解释,为何NodeList长度是3,只要一句话就足以了,笔者特意加粗标红:

CSS选拔器是独立于任何页面包车型客车!

怎么看头啊?举例说你在页面很深的三个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.

2: elem.children和elem.childNodes的区别

elem.children:它回到钦赐成分的子成分集结,只回去html节点,不回来文本节点。
elem.childNodes:它是正经属性,重临钦点成分的子成分集结,满含HTML节点,全数属性,文本节点。

复制代码 代码如下:

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

宽容性如下:

澳门葡京 5

本身写此文时候是15年四月尾,近年来大概就FireFox浏览器援助,作者测度,今后,会协理更扩大的。为啥吧?

因为Web
Components供给它,能够兑现真正独立包装,不会受外部影响的HTML组件。

关于:scope日前支撑尚浅,机缘未到,小编就没供给乱张开了,点到截止。

3:查询成分有二种多管闲事的艺术?ES5的因素选取情势是如何?

查询成分
1.document.getElementsByTagName形式重回全体钦命HTML标签的因素,再次回到结果中,各样成员的大器晚成后生可畏正是它们在文档中冒出的生机勃勃风度翩翩。
澳门葡京,2.document.getElementsByClassName方式重回叁个看似数组的对象,包罗了拥有class名字相符钦定条件的要素。
3.document.getElementsByName艺术用于选拔具有name属性的HTML成分,如<form>、<img>等。
4.getElementById方法重临相称钦赐id属性的要三秋点。

//返回当前文档的所有p元素节点
var els = document.getElementsByTagName('td');
//返回所有class=classname的所有元素。
var els = document.getElementsByClassName('classname');
//返回name属性为name的所有元素。
var els = document.getElementsByName('name');
//返回id为xxx元素。
var el = document.getElementById('xxx');

ES5的因素选取方式:
1.document.querySelector办法接收三个CSS选用器作为参数,再次回到相称该选择器的成分节点。假若有三个节点满足相称原则,则赶回第叁个门户差不离的节点。
2.document.querySelectorAll办法重回全数般配给定选取器的节点。

// 返回当前文档中第一个类名为 "myclass" 的元素
var el = document.querySelector(".myclass");

// 返回一个文档中所有的class为"xx"或者 "xxx"的div元素
var els = document.querySelectorAll(".xx, .xxx");

module dom {
[Supplemental, NoInterfaceObject]
interface NodeSelector {
Element querySelector(in DOMString selectors);
NodeList querySelectorAll(in DOMString selectors);
};
Document implements NodeSelector;
DocumentFragment implements NodeSelector;
Element implements NodeSelector;
};
[html]
从接口定义能够见到Document、DocumentFragment、Element都完毕了NodeSelector接口。即那三种档案的次序的要素都具备者七个情势。querySelector和querySelectorAll的参数须是符合css selector
的字符串。不一致的是querySelector重临的是三个指标,querySelectorAll重临的叁个聚众(NodeList卡塔尔。

querySelector 和 querySelectorAll
的施用特别的简便,就如标题谈到的风流倜傥致,它和 CSS
的写法完全相通,对于前端开拓人士的话,那是难度大致为零的一遍学习。假使大家有一个id 为 test 的 DIV,为了获得到那个成分,你大概会像上面那样:

三、结语依旧要的

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

多谢阅读,应接纠错,接待调换!

1 赞 1 收藏
评论

澳门葡京 6

4:怎么着创造三个成分?怎么样给成分设置属性?怎么着删除属性

创造新因素
1.document.createElement(卡塔尔(英语:State of Qatar),该措施创造新的因素,那几个点子只选择三个参数,正是要成立的新的要素标签字。如:

var div =document.createElement("div");

由于新因素未被加到文书档案树中,因而不会潜移暗化浏览器的显得,要用,appendChild(卡塔尔,大概insertBefore(卡塔尔(英语:State of Qatar)把新因素增加到文书档案中。
2.运用document.createTextNode(卡塔尔(英语:State of Qatar)来制造新的公文节点,那个情势接收多个参数,即要插入节点中的文本。
3.还是能运用appendChild(卡塔尔(قطر‎方法向节点增多最后贰个子节点或许用insertBefore(卡塔尔(قطر‎在钦定的本来就有个别子节点从前插入新节点。(也不通晓那多个算不算新成立八个成分卡塔尔国
怎样给成分设置属性
行使setAttribute(卡塔尔(قطر‎ 方法增加内定的品质,并为其赋钦赐的值。
生机勃勃旦那个钦命的性子已存在,则仅设置/改过值。

    <input type="text" >   
<script>
     document.getElementsByTagName("input") [0].setAttribute("class","test");
</script>

澳门葡京 7

Paste_Image.png

删除属性
动用removeAttribute(卡塔尔 方法删除钦点的性情

  <input type="text" >   
<script>
  document.getElementsByTagName("input")[0].removeAttribute("class","test");
</script>

澳门葡京 8

Paste_Image.png

脚下 IE8/9及Firefox/Chrome/Safari/Opera 的流行版已经支撑它们。

  document.getElementById("test");

5:如何给页面成分增添子成分?如何删除页面成分下的子成分?

应用appendChild(卡塔尔国方法向节点增添最后叁个子成分也许用insertBefore(卡塔尔(قطر‎在钦命的本来就有的子节点以前插入新节点,这么些艺术平时与创设新节点的createElement(卡塔尔和createTextNode(卡塔尔(قطر‎方法合作使用。

1.
<body>
<ul id="demo">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

<script>
    var newLi=document.createElement("li");
    document.getElementById("demo").appendChild(newLi);
</script>
</body>

2.
<body>
<ul id="demo">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

<script>
    var newLi=document.createElement("li");
    var li=document.getElementsByTagName("li");
    document.getElementById("demo").insertBefore(newLi,li[1]);//插到第二个li的前面
</script>
</body>

澳门葡京 9

Paste_Image.png

澳门葡京 10

Paste_Image.png

删去子成分
1.使用element.remove()方法,

<div id="rele">删除元素</div>
<script>
   var rele=document.getElementById("rele");
    rele.remove();
</script>

2.removechild
函数足以去除父成分的钦命子成分,即使此函数删除子节点成功,则赶回被删除的节点,不然再次来到null。

<body>
<ul id="demo">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

<script>
   var ul=document.getElementById("demo");
    var lis=ul.getElementsByTagName("li");
    ul.removeChild(lis[0]);
</script>
</body>

澳门葡京 11

Paste_Image.png

归来第三个li

澳门葡京 12

Paste_Image.png

如想获取页面class属性为”red”的因素,除了使用document.getElementsByClassName(‘red’卡塔尔还足以选取document.querySelector(‘.red’卡塔尔(英语:State of Qatar)和document.querySelectorAll(‘.red’卡塔尔(قطر‎。

现行反革命大家来试试看使用新办法来获取这么些 DIV:

6: element.classList有哪些措施?怎样决断三个因素的 class 列表中是包括有些 class?怎样加多叁个class?怎么样删除三个class?

classList 属性再次来到元素的类名,该属性用于在要素中丰硕,移除及切换 CSS
类,有以下那几个办法:
1.add(class1, class2,
…卡塔尔:该措施在要素中增加三个或多个类名。假若钦赐的类名已存在,则不会添加。

 <style>
        .myDiv{
            width: 200px;
            height: 200px;
            background: #2b2b2b;
        }
        .myDiv2{
            background: #ff0000;
        }
    </style>
</head>
<body>
  <div>测试</div>
<script>
   document.getElementsByTagName("div")[0].classList.add("myDiv","myDiv2");
</script>
</body>

未增加此前:

澳门葡京 13

Paste_Image.png

丰富其后:

澳门葡京 14

Paste_Image.png

2.contains(class卡塔尔国:该措施重回布尔值,剖断钦命的类名是不是留存。
true – 成分包已经包蕴了该类名
false – 成分中不真实该类名

  <div class="myDiv">测试</div>
<script>
  console.log( document.getElementsByTagName("div")[0].classList.contains("myDiv"));//true
</script>```
3.item(index):返回类名在元素中的索引值。索引值从 0 开始。如果索引值在区间范围外则返回 null。

<body>
<div class=”myDiv myDiv2″>测试</div>
<script>
console.log(
document.getElementsByTagName(“div”)[0].classList.item(0));//myDiv
</script>
</body>

4.remove(class1, class2, ...):移除元素中一个或多个类名

<style>
    .myDiv{
        width: 200px;
        height: 200px;
        background: #00ff00;
    }
    .myDiv2{
        background: #ff0000;
    }
</style>

</head>
<body>
<div class=”myDiv myDiv2″>测试</div>
<script>
document.getElementsByTagName(“div”)[0].classList.remove(“myDiv2”);
</script>

未移除之前:

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/5572128-fa338b4aa641813a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
移除之后:

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/5572128-3b446202f5922a8b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

5.toggle(class, true|false): 在元素中切换类名。

<style>
.myDiv{
width: 200px;
height: 200px;
background: #00ff00;
}
.myDiv2{
background: #ff0000;
}
</style>
</head>
<body>
<div class=”myDiv”>测试</div>
<button onclick=”toggle(卡塔尔国”>点小编切换</button>
<script>
function toggle(){
document.getElementsByTagName(“div”)[0].classList.toggle(“myDiv2”);
}

</script>

使用classList.contains()判断是否包含某个class。
使用classList.add()添加class。
使用classList.remove()删除元素的一个class。

## 7: 如何选中如下代码所有的li元素? 如何选中btn元素?

<div class=”mod-tabs”>
<ul>
<li>list1</li>
<li>list2</li>
<li>list3</li>
</ul>
<button class=”btn”>点我</button>
</div>

选中li:

var lis=document.getElementsByTagName(“li”);

var lis=document.querySelectorAll(“li”);

选中btn:
  1. var btn=document.getElementsByClassName(“btn”);

var btn=document.querySelector(‘.btn’)

但Element.querySelector和Element.querySelectorAll的兑现存不当,如下

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

[code]
<div id=”d1″>
<p><a
href=”;
</div>
<script type=”text/javascript”>
function $(id){return document.getElementById(id);}
var d1 = $(‘d1’);
var obj1 = d1.querySelector(‘div a’);
var obj2 = d1.querySelectorAll(‘div a’);
alert(obj1); // ->
alert(obj2.length); // -> 1
</script>

得到文书档案中 class=”example” 的率先个

在支撑那五个点子的浏览器能够见到个别弹出了“
“1”。表明查询到了想要的因素或因素群集。这与W3C的概念却是不合的,遵照定义应该是在要素d1范围内搜寻”div
a”,而d1内压根未有div。由此应该分别重返null,空集结。

元素:

jQuery1.4.2
及前面版本中只行使了document.querySelectorAll,未有动用Element.querySelectorAll。
jQuery1.4.3
后使用了Element.querySelectorAll,但做了修复。在选取器前加了”#__sizzle__”以强制其在钦命成分内搜寻(3903-3918行)。简化下

  document.querySelector("p.example");

复制代码 代码如下:

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

function $(id){return document.getElementById(id);}
var d1 = $(‘d1’);
var obj1 = d1.querySelector(‘div a’);
var obj2 = d1.querySelectorAll(‘div a’);
var old = d1.id, id = d1.id = “__sizzle__”;
try {
var query = ‘#’ + id + ‘ div a’;
alert(d1.querySelector( query ));
alert(d1.querySelectorAll( query ).length);
} catch(e) {
} finally {
old ? d1.id = old : d1.removeAttribute( “id” );
}

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

金玉锦绣很玄妙,钦赐范围的成分尽管有id,将其保存在old,”__sizzle__”赋值其充任有的时候id,在接收器”div
a”前钦赐查找范围为”#__sizzle__”,即d1。finally语句来最后清理,纵然钦定范围的成分自身有id将其过来为old,未有则去掉有时的id属性”__sizzle__”。

利用那四个法子无法搜索带伪类状态的成分,比方querySelector(‘:hover’卡塔尔(英语:State of Qatar)不会赢得预期结果。

相关:

  querySelectorAll

复制代码 代码如下: module dom { [Supplemental, NoInterfaceObject]
interface NodeSelector { Element querySel…

该办法重临全体满足条件的因素,结果是个nodeList集结。查找准则与前方所述一样。

elements =
document.querySelectorAll(‘div.foo’卡塔尔(قطر‎;//重临全数带foo类样式的div

但要求当心的是回去的nodeList会集中的因素是非实时(no-live)的,想要差异什么是实时非实时的回来结果,请看下例:

  <div id="container">
      <div></div>
      <div></div>
  </div>

//首先选择页面中id为container的成分

container=document.getElementById(‘#container’);
console.log(container.childNodes.length)//结果为2

//然后透过代码为其拉长一个子元素

  container.appendChild(document.createElement('div'));

//那个成分不但助长到页面了,这里的变量container也自动更新了

console.log(container.childNodes.length)//结果为3

透过地点的例子就很好地精通了怎么是会实时更新的成分。document.getElementById重临的就是实时结果,下直面其丰富一个子成分后,再一次获取具有子元素个数,已经由原来的2个立异为3个(这里不思忖有个别浏览器举个例子Chrome会把空荡荡也解析为叁个子节点卡塔尔国。

备感差距超小是啊,但倘如若有一点点复杂点的情状,原始的方法将变得非常劳苦,那时querySelector 和 querySelectorAll
的优势就发挥出来了。比如接下去那几个例子,我们就要 document 中甄选 class
为 test 的 div 的子成分 p
的首先个子成分,当然这很隐晦,但是用本文的新方式来选用这几个因素,比用讲话来描述它还要简单。

  document.querySelector("div.test>p:first-child");
  document.querySelectorAll("div.test>p:first-child")[0];

咱俩应用 querySelectorAll 给全数 class 为 emphasis 的成分加粗呈现。

  var emphasisText = document.querySelectorAll(".emphasis");
  for( var i = 0 , j = emphasisText.length ; i < j ; i++ ){
      emphasisText[i].style.fontWeight = "bold";
  }

那是原生方法,比起jquery速度快

介怀: querySelector(卡塔尔(英语:State of Qatar)方法唯有再次来到相配内定选取器的首先个因素。借使您须要再次来到全体的要素,请使用
querySelectorAll(卡塔尔 方法代替。

相关文章

发表评论

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

*
*
Website