Go to comments

jQuery DOM操作 查

一、查找同级兄弟元素

.next()

.prev()

.prevAll()

.nextAll()

.prevUntil()

.nextUntil()

.siblings()


 .next() 

获取前面元素的下一个兄弟元素,点击button按钮的时候,改变span标签的字体大小和字体颜色

<button>change</button>
<span class="demo">span标签</span>
<p class="dome">p标签</p>

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>

  $('button').click(function() {

    $(this).next().css({
      fontSize: '20',
      color: 'orange'
    });

  });

</script>


 .next('p')  参数在这里一般起到过滤筛选的作用

1. 关注的是下一个兄弟元素是不是p元素

2. 如果是p元素才能启到效果,不是p点击不会改变

$('button').click(function () {

  $(this).next('p').css({fontSize:'20', color: 'orange'});

});


 .prev() 

 .prev('p')  往上找一个兄弟元素节点,并且加限制条件p

<span class="demo">span标签</span>
<p class="dome">p标签</p>
<button>change</button>

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>

  $('button').click(function() {

    $(this).prev('p').css({
      fontSize: '20',
      color: 'orange'
    });
  });

</script>


 .prevAll() 

作用不仅选一个而是选一堆,只要是同级的,在下面的所有兄弟元素节点都选中(应用的比较多)


复习知识点

.attr() 和 .prop() 都能修改 checkbox 类型,但改的值不一样

.prop() 修改的值是布尔值

.attr() 修改的就是属性值,所以表单元素用 .prop()


点击第一个checkbox类型的表单(全选),下面所有兄弟节点全打钩

<div class="wrapper">
  <input type="checkbox" />全选
  <input type="checkbox" />banana
  <input type="checkbox" />apple
  <input type="checkbox" />orange
  <input type="submit" value="Login" />
</div>

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>

  $('input[type="checkbox"]').eq(0).click(function () {

    // 判断当前的checked是true,是打上勾了
    if($(this).prop('checked')){
      $(this).nextAll().prop('checked', true);
    }else{
      $(this).nextAll().prop('checked', false);
    }

  });

</script>


有一个缺陷,

最下面的 submit 类型也给设置了 checked 属性

$('input[type="checkbox"]').eq(0).click(function () {

  if($(this).prop('checked')){
    $(this).nextAll().prop('checked', true);
  }else{
    $(this).nextAll().prop('checked', false);
  }
  console.log($('input:last').prop('checked')); // 选中最后一个inpupt返回true或false

});


 .nextAll( 'input[type="checkbox"]' 添加参数过滤,加上限制条件选的更精准

$('input[type="checkbox"]').eq(0).click(function () {
  if($(this).prop('checked')){
    // 添加参数过滤,只选中checkbox类型的元素
    $(this).nextAll('input[type="checkbox"]').prop('checked', true);
  }else{
    $(this).nextAll('input[type="checkbox"]').prop('checked', false);
  }
  console.log($('input:last').prop('submit')); // 不是type="checkbox类型返回undefined
});


 .prevAll() 

.prevAll 是相反的,选中最后一个 checkbox 类型,然后循环上面的,把上面的都选上

<div class="wrapper">
  <input type="checkbox" />banana
  <input type="checkbox" />apple
  <input type="checkbox" />orange
  <input type="checkbox" />全选
  <input type="submit" value="Login" />
</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>

  // 选中最下面的checkbox类型
  $('input[type="checkbox"]').eq(3).click(function () {

    if($(this).prop('checked')){
      $(this).prevAll('input[type="checkbox"]').prop('checked', true);
    }else{
      $(this).prevAll('input[type="checkbox"]').prop('checked', false);
    }
    console.log($('input:last').prop('submit'));// undefined

  });

</script>


 .nextUntil() 

结构稍微复杂一点,但复杂的往往比简单的更精准一点。两组复选框用.nextAll()方法点击全选,水果、蔬菜两组全都被选中


 .nextUntil('h3')   Until意思到什么为止,也是加一个限制条件,到h3标签前面为止

<div class="wrapper">
  <h3>水果</h3>
  <input type="checkbox" />全选
  <input type="checkbox" />banana
  <input type="checkbox" />apple
  <input type="checkbox" />orange

  <h3>蔬菜</h3>
  <input type="checkbox" />全选
  <input type="checkbox" />土豆
  <input type="checkbox" />茄子
  <input type="checkbox" />蘑菇
  <input type="button" value="submit">
</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>

  $('input[type="checkbox"]').eq(0).click(function () {

    if($(this).prop('checked')){
      $(this).nextUntil('h3').prop('checked', true);
    }else{
      $(this).nextUntil('h3').prop('checked', false);
    }

  });
  
</script>


"蔬菜"没有绑定上事件,

看结构,h3标签下面代表一套选择,h3下面直接就是全选的 checkbox 元素,结构给我们这样选择的能力


.next() 根据前面的选择,

如果 $('h3') 选择的是一个,.next() 又找到的也是这一个下面的兄弟元素,

前面 $('h3') 选择的是两个h3,它里面也有循环操作,.next() 返回的是两个 h3 下面第一个兄弟元素的集合,

click绑定事情也是循环操作了,两个 h3 下的第一个input元素都绑定了事件,这是jQuery擅长的地方。

$('h3').next().click(function () {
  if($(this).prop('checked')){
    $(this).nextUntil('h3').prop('checked', true);
  }else{
    $(this).nextUntil('h3').prop('checked', false);
  }
  console.log($('input:last').prop('checked')); // true/false
});


结构给我们这样选择的能力,h3下面直接就是 checkbox 元素

1. next() 是根据前面 $('h3') 的选择,

2. 如果前面 $('h3') 选择的是一个h3,next() 找到的是这一个 h3 下面的兄弟元素

3. 如果 $('h3') 前面选择的是两个h3,它里面也有循环操作,next() 返回的是两个 h3 下面的第一个兄弟元素的集合,

   click绑定事情也是循环操作了,两个h3下的第一个input元素都绑定了事件,这是jQuery擅长的地方


蔬菜组下面没有 h3 标签,下面的 submit 按钮也添加了checked 属性,针对这个场景  .nextUntil('h3', 'input[type="checkbox"]')  方法还可以再填一个参数,也是加一个限制条件

第一个参数,代表到 h3 标签为止,

第二个参数,还是过滤添加一个限定条件,在这个范围内只找 "type="checkbox"

$('h3').next().click(function () {

  if($(this).prop('checked')){
    // 第二个参数加限制条件
    $(this).nextUntil('h3', 'input[type="checkbox"]').prop('checked', true);
  }else{
    $(this).nextUntil('h3', 'input[type="checkbox"]').prop('checked', false);
  }

  console.log($('input:last').prop('checked')); // 最后一个input是submit类型,没有添加checked属性所以只返回false

});


小练习

下面结构复杂一点,成哥说也没复杂到那,就是加了几个空格

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<title>小练习</title>
</head>
<body>

<div class="wrapper">
  all:<input type="checkbox"/>

  <h1>吃货清单</h1>
  all:<input type="checkbox" data="吃货清单"/>
  
  <h3>水果</h3>
  全选:<input type="checkbox" />
  香蕉<input type="checkbox" />
  苹果<input type="checkbox" />
  橙子<input type="checkbox" />
  <span></span>

  <h3>蔬菜</h3>
  全选:<input type="checkbox" />
  tomato<input type="checkbox" />
  egg<input type="checkbox" />
  potao<input type="checkbox" />
  <span></span>

  <h1>明星</h1>
  all:<input type="checkbox" data="明星清单"/>

  <h3>清新的</h3>
  全选:<input type="checkbox" />
  杨幂赵丽颖<input type="checkbox" />
  赵丽颖<input type="checkbox" />
  <span></span>

  <h3>学习好的</h3>
  全选:<input type="checkbox" />
  杨幂<input type="checkbox" />
  杨幂<input type="checkbox" />
  <span></span>
</div>

<script>

  // 选中所有input标签
  $('input').eq(0).click(function(){
    if($(this).prop('checked')){
      // 过滤一下,只选中input[type="checkbox"]标签
      $(this).nextAll('input[type="checkbox"]').prop('checked', true);
    }else{
      $(this).nextAll('input[type="checkbox"]').prop('checked', false);
    }
  });
  
  // 选中h1标签下的大组
  $('h1').next().click(function(){
    if($(this).prop('checked')){
      $(this).nextUntil('h1', 'input[type="checkbox"]').prop('checked', true);
    }else{
      $(this).nextUntil('h1', 'input[type="checkbox"]').prop('checked', false);
    }
  });
  
  // 选中h3下的小组,要加一点结构span
  $('h3').next().click(function(){
    if($(this).prop('checked')){
      $(this).nextUntil('span', 'input[type="checkbox"]').prop('checked', true);
    }else{
      $(this).nextUntil('span', 'input[type="checkbox"]').prop('checked', false);
    }
  });

</script>
</body>
</html>


全选/全不选/反选

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<title>全选,反选</title>
</head>
<body>

<div class="wrapper">
  <p><input type="checkbox" class="demo"/>banana</p>
  <p><input type="checkbox" class="demo"/>apple</p>
  <p><input type="checkbox" class="demo"/>orange</p>
  <p>
    <input type="checkbox" id="all"/>全选/全不选
    <input type="checkbox" id="reverse"/>反选
  </p>
</div>

<script>

  // 全选
  $('#all').click(function () {
    $('#reverse').prop('checked', false);
    if($('.demo').prop('checked')){
      $('.demo').prop('checked', false);
    }else{
      $('.demo').prop('checked', true);
    }
  });

  // 反选
  $('#reverse').click(function () {
    $('#all').prop('checked', false);
    $('.demo').each(function(){
      this.checked = !this.checked;
    });
  });

  // 点击列表列表checkbox元素,取消全选、反选
  $('.demo').click(function(){
    $('#all').prop('checked', false);
    $('#reverse').prop('checked', false);
  });

</script>
</body>
</html>


 .siblings() 

如果说上面的方法是获取某一个方向上的兄弟元素节点,.siblings() 方法只要是兄弟元素就可以获取


先获取到第5个p元素,然后通过.sibling()获取到它所有的兄弟元素节点

<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
<p>6</p>
<p>7</p>
<p>8</p>
<p>9</p>
<p>10</p>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>

$('p')
  .eq(4).css({backgroundColor: 'orange'})
    .siblings().css({backgroundColor: 'aqua'});

</script>


传参数"span"进行过滤,只选择"span"元素,不管在什么位置只要是兄弟节点都选中

<span>span</span>
<p>1</p>
<p>2</p>
<p>3</p>
<span>span</span>
<p>4</p>
<p>5</p>
<p>6</p>
<p>7</p>
<span>span</span>
<p>8</p>
<p>9</p>
<p>10</p>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>

$('p')
  .eq(4)
    .css({backgroundColor: 'saddlebrown'})
      .siblings('span')
        .css({backgroundColor: 'aqua'});

</script>


.siblings() 在做反选的时候经常使用到

<ul>
  <li>1</li>
  <li>2</li>
  <li class="active">3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
</ul>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>

$('li').click(function(){
  $(this).siblings().css('backgroundColor', 'burlywood')
    .end().css('backgroundColor', 'aqua');
});

</script>


二、查找父级元素

这些方法基本是一个意思,用法上也差不多,只不过提供这么多种方式,针对不同 dom 结构不同场景,进行选择性的调用

.parent()

.parents()

.offsetParent()

.closest()


 .parent() 

点击按钮获取 button 直接的上一级父级

<div class="shop" data-id="101">
  <p>苹果</p>
  <button>按钮</button>
</div>

<div class="shop" data-id="102">
  <p>香蕉</p>
  <button>按钮</button>
</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>

  $('button').click(function () {
    console.log($(this).parent().css('border', '1px solid #ccc')); // jQuery.fn.init [div.shop, prevObject: jQuery.fn.init(1)]
  });

</script>

1. $('button') 获取的是两个 button 元素,也绑定了两个事件,因为一系列的操作都是循环操作

2. 点击按钮后执行 $(this).parent() 获取到 button 对应的父级


传参数 ".demo" 进行过滤,上一级没有符合 ".demo" 条件的元素,什么都没选中返回 jQuery 空对象

$('button').click(function () {
  console.log($(this).parent('.demo')); // jQuery.fn.init [prevObject: jQuery.fn.init(1)]
});


.parent() 方法应用实例

一个商城每一个商品有自己对应的 id 值

1. 把后端传过来的数据,渲染成标签结构

2. 点击按钮获取 button 父级,获取商品 id 放到购物车的数组中。数组发送给服务器,告诉服务器用户都选了哪些商品的 id

<div class="wrapper"></div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>

  var showArrs = [{
      name: 'Nike',
      id: 101
    },
    {
      name: 'Adidas',
      id: 102
    }
  ];

  var str = ''; // 字符串拼接,声明一个空串

  showArrs.forEach(function(ele, index) {
    // 数据里的id和标签里面的data-id形成一种映射关系,
    // 点击button的时候直接获取到父级,从而获取到data-id的值,方便我们往后台去传
    str += '<div class="shop" data-id="' + ele.id + '"><p>' + ele.name + '</p><button>按钮</button></div>';
  });

  $('.wrapper').html(str); // 用.html()方法把拼接好的字符串,渲染到.wrapper里面

  var carArr = [];

  $('button').click(function() {
    carArr.push($(this).parent().attr('data-id'));
    console.log(carArr);
  });

  // 渲染的解构
  // <div class="wrapper">
  //   <div class="shop" data-id="101">
  //     <p>Nike</p>
  //     <button>按钮</button>
  //   </div>
  //   <div class="shop" data-id="102">
  //     <p>Adidas</p>
  //     <button>按钮</button>
  //   </div>
  // </div>

</script>


.parent() 方法总结

1. 不传参数只获取直接的父级,传参数确认一下是不是我们要的父级

2. $('button') 获取到的是多个 button 集合,调用 .parent() 返回的一定是多个父级

<div class="wrapper">
  <div class="shop" data-id="101">
    <p>Nike</p>
    <button>按钮</button>
  </div>
  <div class="shop" data-id="102">
    <p>Adidas</p>
    <button>按钮</button>
  </div>
</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
  // 返回两个div.shop
  console.log($('button').parent()) // jQuery.fn.init(2) [div.shop, div.shop, prevObject: jQuery.fn.init(2)]
</script>


 .parents() 

结构变了,怎么获取父级呢?可以通过两个 .parent() 获取到想要的父级

<div class="shop" data-id="101">
  <div>
    <p>Nike</p>
    <button>按钮</button>
  </div>
</div>

<div class="shop" data-id="102">
  <div>
    <p>Aaidas</p>
    <button>按钮</button>
  </div>
</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
  console.log($("button").parent().parent()); // jQuery.fn.init(2) [div.shop, div.shop, prevObject: jQuery.fn.init(2)]
</script>


下面用 parents() 方法获取所有父级,

.parents() 方法只要是 button 的父级全部获取到,为了方便我们只看第一个 button

<div class="shop" data-id="101">
  <div>
    <p>Nike</p>
    <button>按钮</button>
  </div>
</div>

<div class="shop" data-id="102">
  <div>
    <p>Aaidas</p>
    <button>按钮</button>
  </div>
</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>

console.log($('button').eq(0).parents()); // jQuery.fn.init(4) [div, div.shop, body, html, prevObject: jQuery.fn.init(1)]

// jQuery.fn.init(4) [div, div.shop, body, html, prevObject: jQuery.fn.init(1)]
// 0: div
// 1: div.shop
// 2: body
// 3: html
// length: 4
// ]

</script>


$('button') 是一个集合,获取到两个 button 的父级,两个 button 有共同的父级有body 和 html

console.log($('button').parents());// jQuery.fn.init(6) [div, div.shop, div, div.shop, body, html, prevObject: jQuery.fn.init(2)]

// [
//   0: div
//   1: div.shop
//   2: div
//   3: div.shop
//   4: body
//   5: html
//   length: 6
// ]


如果想获取类名带 .shop 的父级,填参数进行过滤

$('button').click(function () {

  console.log($(this).parents('.shop')); // jQuery.fn.init [div.shop, prevObject: jQuery.fn.init(1)]

});

.parents() 和下面的 .closest() 方法比较像


 .closest() 

ul里有li,li里有ul,结构又复杂了

<div class="wrapper">
  <ul>
    <li>
      <ul data-id='101'>
        <li>Nike</li>
        <li>200$</li>
        <li>
          <button>按钮1</button>
        </li>
      </ul>
    </li>
    <li>
      <ul data-id='101'>
        <li>Nike</li>
        <li>200$</li>
        <li>
          <button>按钮2</button>
        </li>
      </ul>
    </li>
  </ul>
</div>


希望点击 button 后获取到 ul 上的商品 data-id 怎么实现呢?

.parent() 方法要连着用两次

.parents() 方法参数用 ul 会筛选出两个 ul,ul 上没有类名,除非用属性 data-id 过滤


针对种场景用 .closest() 方法更方便一些,

该方法获取离你最近的满足条件的父级,不是直接的父级,可能是远方的父级


不传参数什么都获取不到

<div class="wrapper">
  <ul>
    <li>
        <ul data-id='101'>
          <li>Nike</li>
          <li>200$</li>
          <li>
              <button>按钮1</button>
          </li>
        </ul>
    </li>
    <li>
        <ul data-id='101'>
          <li>Nike</li>
          <li>200$</li>
          <li>
              <button>按钮2</button>
          </li>
        </ul>
    </li>
  </ul>
</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
  console.log($('button').closest());
</script>


如果参数用 button 按钮自己,获取的就是 button 自己

console.log($('button').eq(0).closest('button')); // jQuery.fn.init [button, prevObject: jQuery.fn.init(1)]


.closest() 方法和 .parents() 方法的区别

1. .closest() 是找离 button 最近的父级,从 button 自己开始找,如果 button 自己符合条件也会被选中

2. .parents() 是直接上一级,以及上上的很多级


 parents("ul")  会找到两个ul


 .closest('ul')  找离自己最近的一个 ul 父级,天生就带了一个过滤条件离自己最近的

<div class="wrapper">
  <ul>
    <li>
        <ul data-id='101'>
          <li>Nike</li>
          <li>200$</li>
          <li>
            <button>按钮1</button>
          </li>
        </ul>
    </li>
    <li>
        <ul data-id='101'>
          <li>Nike</li>
          <li>200$</li>
          <li>
            <button>按钮2</button>
          </li>
        </ul>   
    </li>
  </ul>
</div>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
  
  console.log($('button').eq(0).closest('ul'));
  console.log($('button').eq(0).closest('ul').attr('data-id')); // 101

</script>

面对的种场景选父级,干扰因素比较多,使用.closest()找离我们最近的ul,可以通过参数精确的筛选出来


 .offsetParent() 

找最近有定位的父级,和原生里的基本上是一样的,最近有定位的父级是 div.wrapper

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<title>.offsetParent()</title>
<style>
  .wrapper{
    position:relative;
  }
</style>
</head>
<body>

<div class="wrapper">
  <div class="box">
    <span>123</span>
  </div>
</div>

<script>

  console.log($('span').offsetParent()); // jQuery.fn.init [div.wrapper, prevObject: jQuery.fn.init(1)]

</script>

</body>
</html>


三、截取

 .slice() 

先获取一堆li,然后想得到从 2 到 6 的li,截取后在集中操作添加css属性

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
</ul>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
  console.log($('li').slice(1, 6).css({backgroundColor:'orange', color:'#fff'}));
</script>

第一个参数填1,索引从0计数,参数1从第2个 li 开始截

第二个参数填6,截取到第 5 个li,如果填5是不包括第5个,因为是左闭右开所以填6 [1,6)

截取返回的依旧是jQuery对象



Leave a comment 0 Comments.

Leave a Reply

换一张