jQuery中如何从select标签遍历选择器定位到对应button标签?
问题背景
现有大量结构一致的商品组件,需要实现「选择尺码下拉框时,自动把选中值同步到同组件内加入购物车按钮的data-item-custom1-value属性」的效果,为避免冗余不采用给每个元素单独设置ID的方案。
初始实现代码无法正确定位目标按钮,代码如下:
$('.shirtSize').on('change', function() { $(this).parent().children("button").attr("data-item-custom1-value", this.value); });
对应组件HTML结构:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="product-item-content"> <span> <select class="shirtSize"> <option>S</option> <option>M</option> <option>L</option> <option>XL</option> </select> </span> <span> <select class="shirtColor"> <option>White</option> <option>Blue</option> </select> </span> <span> <button class="mini-btn">Add To Cart</button> </span> </div>
失效原因
原代码的DOM遍历逻辑不符合实际层级:
$(this).parent()拿到的是包裹尺码下拉框的直接父级<span>元素- 这个span的直接子元素只有
.shirtSize下拉框本身,不存在button节点,因此无法定位到目标按钮 - 目标按钮实际位于外层
.product-item-content容器下的第三个同级span内,和下拉框的父span是兄弟节点关系
正确实现代码
使用closest()方法先向上查找当前组件的最外层公共容器,再在容器内部查找目标按钮,该写法兼容多实例场景,不会跨组件误操作其他按钮:
$('.shirtSize').on('change', function() { $(this) // 向上遍历找到当前商品的最外层公共容器 .closest('.product-item-content') // 在当前商品容器范围内查找目标加购按钮 .find('button.mini-btn') // 赋值自定义属性,优先使用data方法更符合jQuery规范 .data('item-custom1-value', this.value); });
方案说明
closest()方法会逐级向上匹配最近的符合选择器的祖先元素,相比连续调用多次parent()容错性更高,后续如果调整DOM层级(比如给select额外套一层包裹标签),只要公共容器.product-item-content不变,代码就不会失效- 如果需要同步修改DOM节点上可见的
data-item-custom1-value属性(比如供其他原生JS脚本读取属性节点),可以把.data()替换为.attr("data-item-custom1-value", this.value),效果一致 - 同组件下的颜色下拉框如果需要同步值到按钮,也可以复用这套遍历逻辑,不需要额外调整选择器
内容的提问来源于stack exchange,提问作者jmozzart
相关产品推荐
相关产品推荐

