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