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对象