你不知道的元素选择器

202 阅读4分钟

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

  • 执行
    var selectHtml = $('.bundBox .checkbox :first()');
    console.log(selectHtml)
    结果为一个label标签,也就是选中了checkbox下的第一个子元素节点.

所以说,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()是否包括其自身结构

  • 执行
    var selectHtml = $('.bundBox .checkbox :eq(0)').html();//多了一个html
    console.log(selectHtml)
    由第一部分可知我们查找的依然是label标签,输出结果为一个html结构,控制台输出如下

和你预想的一样吗。别错以为它输出了Input,其实输出的依然是label标签,只不过此时我们想要的是label的html结构,从上图可知,html()的输出是不包括其本身结构的

到目前为止选中的都是第一个checkbox,如果改成把选择器.checkbox :eq(2),那么输出的结果为则第二个checkbox的label标签。

神奇的空格

现在有一个有意思的现象

  • 我们来执行以下语句,去掉了checkbox和选择器之间的空格
    var selectHtml = $('.bundBox .checkbox:eq(0)');
    console.log(selectHtml)
    打印台输出了包括它自身的整个checkbox盒子!

为了让结果更加直观,我还是使用输出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()是啥情况,执行如下语句
    var selectHtml = $('.bundBox .checkbox:first()').html();
    console.log(selectHtml)
    打印台输出checkbox下的html结构,和eq(0)的结果完全一致。
    <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

结论:

  1. element first()相当于element eq(0),element last()相当于element eq(lastIndex)
  2. 在一个父元素中查找子元素时和层级无关,从近到远依次查找
  3. element.html()输出的结构不包括element本身
  4. element:eq(0)不带空格查找的是第一个类名为element的节点,依次向后查找类名为element的节点
  5. .element :eq(0)查找的是类名为element的第一个子元素节点,查完当前类所有子节点后,再继续查找下一个element类,索引递增

恭喜你没被绕晕!