2017-08-22
已经不是第一次碰到这个问题了。关于 eq()、first()等对子元素或者通过索引进行操作的选择器,有空格和无空格,eq()是否包含其本身,虽然想想觉得这个问题也太简单了有什么好说的,然而实际使用的时候总是会出现各种懵逼情况
“卧槽怎么选的是这个元素?”
“尼玛这个事件怎么就是不对?”
所以在这里还是做一个测试兼记录。
首先来看今天的例子,两个大盒子boxContent组成,每个boxContent里有一个title和checkbox的div盒子
具体结构如下
<div class="control-group">
<div class="boxContent">
<div class="title">配电箱1</div>
<div class="checkbox" style="display: inline-block">
<label class="checkbox-inline" style="display: inline-block">
<input type="checkbox" value="">
推送1
</label>
</div>
<input type="submit" class="btn unbund" name="" value="解绑">
</div>
<div class="boxContent">
<div class="">配电箱1</div>
<div class="checkbox" style="display: inline-block">
<label class="checkbox-inline" style="display: inline-block">
<input type="checkbox" value="">
推送2
</label>
</div>
<input type="submit" class="btn unbund" name="" value="解绑">
</div>
</div>
eq()&&first()
- 执行
输出结果为var selectHtml = $('.bundBox .checkbox :eq(1)'); console.log(selectHtml);
也就是一个input按钮,说明选中的是checkbox中的第二个节点input
- 执行
结果为一个label标签,也就是选中了checkbox下的第一个子元素节点.var selectHtml = $('.bundBox .checkbox :first()'); console.log(selectHtml)
所以说,first()输出的是选中集合的第一个节点,eq(0)输出的是选中集合下索引为0的节点(不包括集合本身),所以两种选择器本质上一致,都是获取了第一个checkbox的内容
- 如果我们把第一个BoxContent的结构中再加一层label>input结构,
<div class="boxContent">
<div class="title">配电箱1</div>
<div class="checkbox" style="display: inline-block">
<label class="checkbox-inline" style="display: inline-block">
<input type="checkbox" value="">
推送1
</label>
<label class="checkbox-inline" style="display: inline-block">
<input type="checkbox" value="">
推送小小1
</label>
</div>
<input type="submit" class="btn unbund" name="" value="解绑">
</div>$('.bundBox .checkbox :eq(0)'):第一个label标签
$('.bundBox .checkbox :eq(1)'):第一个input标签
$('.bundBox .checkbox :eq(2)'):第二个label标签
$('.bundBox .checkbox :eq(3)'):第二个input标签
那么$('.bundBox .checkbox :eq(4)')呢?
这个应该好理解,但是容易被忽略。$('.bundBox .checkbox :eq(4)')就开始查找第二个checkbox类
承上结论可得,$('.bundBox .checkbox :last()')输出的也是第二个input标签,当然实际结果也是如此
所以这种对子元素查找的方式和层级无关,是从远到近依次对子元素进行查找
html()是否包括其自身结构
- 执行
由第一部分可知我们查找的依然是label标签,输出结果为一个html结构,控制台输出如下var selectHtml = $('.bundBox .checkbox :eq(0)').html();//多了一个html console.log(selectHtml)
和你预想的一样吗。别错以为它输出了Input,其实输出的依然是label标签,只不过此时我们想要的是label的html结构,从上图可知,html()的输出是不包括其本身结构的
到目前为止选中的都是第一个checkbox,如果改成把选择器.checkbox :eq(2),那么输出的结果为则第二个checkbox的label标签。
神奇的空格
现在有一个有意思的现象
- 我们来执行以下语句,去掉了checkbox和选择器之间的空格
打印台输出了包括它自身的整个checkbox盒子!var selectHtml = $('.bundBox .checkbox:eq(0)'); console.log(selectHtml)
为了让结果更加直观,我还是使用输出html()
var selectHtml = $('.bundBox .checkbox:eq(0)').html();
console.log(selectHtml);输出的是checkbox下的所有的结构
<label class="checkbox-inline" style="display: inline-block">
<input type="checkbox" value="">
推送1
</label>这是比较神奇的地方,现在输出的是第一个checkbox下的所有内容,也就是说在指定元素和选择器eq(0)之间没有空格的时候,查找的是指定元素本身,而且从其自身开始计算索引。
- 那么first()是啥情况,执行如下语句
打印台输出checkbox下的html结构,和eq(0)的结果完全一致。var selectHtml = $('.bundBox .checkbox:first()').html(); console.log(selectHtml)<label class="checkbox-inline" style="display: inline-block"> <input type="checkbox" value=""> 推送1 </label> - 来一个直观的有无空格的对比,在编辑器中输入如下
控制台输出结果var selectHtml1 = $('.bundBox .checkbox :eq(0)').html();//有空格 var selectHtml2 = $('.bundBox .checkbox:eq(0)').html();//无空格 console.log(selectHtml1); console.log(selectHtml2);
那么你猜,var selectHtml2 = $('.bundBox .checkbox:eq(1)')会输出什么?
答案是整个第二个checkbox
结论:
element first()相当于element eq(0),element last()相当于element eq(lastIndex)- 在一个父元素中查找子元素时和层级无关,从近到远依次查找
element.html()输出的结构不包括element本身element:eq(0)不带空格查找的是第一个类名为element的节点,依次向后查找类名为element的节点。.element :eq(0)查找的是类名为element的第一个子元素节点,查完当前类所有子节点后,再继续查找下一个element类,索引递增
恭喜你没被绕晕!