点击div.b或页面其他区域时控制div.c的.vis类显示异常排查
问题:实现指定的div交互效果
需求说明
需要实现一组如下结构的div列表:
<div class="a"> <div class="b"></div> <div class="c"></div> </div> <div class="a"> <div class="b"></div> <div class="c"></div> </div> <div class="a"> <div class="b"></div> <div class="c"></div> </div>
交互要求:
- 点击
div.b时,为同一父级div.a下的div.c添加.vis类; - 点击另一个
div.b时,为其同级div.c添加.vis类,并移除上一个被点击div.c的.vis类; - 点击页面非
div.b区域时,移除所有div.c的.vis类。
原代码问题
编写的代码未达到预期效果:需要点击两次才能为div.c添加.vis类;点击新的div.b时,上一个div.c的.vis类未被移除,导致多个div.c同时拥有该类。原代码如下:
window.onclick = function(window) { if(window.target.className === 'b'){ $(".b").each(function() { $(".b").on("click", function(){ $(this).siblings(".c").addClass("vis"); }) }) } else { $(".c").removeClass("vis"); } }
问题分析
- 事件绑定时机错误:把
.b的点击事件绑定放在window.onclick回调里,第一次点击.b时才完成事件绑定,所以需要第二次点击才会触发添加类的逻辑; - 未重置全局状态:点击新的
.b时,没有先移除所有.c的.vis类,导致多个.c同时生效; - 参数命名冲突:回调函数参数用了
window,覆盖了全局的window对象,应该用event; - 类名判断不可靠:直接用
className === 'b'无法处理.b同时有多个类的情况。
修正后的代码
// 给所有.b绑定点击事件 $(".b").on("click", function(event) { // 阻止事件冒泡,避免触发window的点击事件 event.stopPropagation(); // 先移除所有.c的vis类 $(".c").removeClass("vis"); // 给当前.b的同级.c添加vis类 $(this).siblings(".c").addClass("vis"); }); // 页面其他区域点击事件 window.onclick = function(event) { // 判断点击目标不是.b元素 if (!$(event.target).hasClass('b')) { $(".c").removeClass("vis"); } };
代码解释
- 提前绑定事件:直接在页面加载完成后给所有
.b绑定点击事件,避免第一次点击仅绑定事件不执行逻辑的问题; - 全局状态重置:每次点击
.b时先移除所有.c的.vis类,确保只有当前目标的.c生效; - 阻止事件冒泡:点击
.b时阻止事件向上冒泡,避免触发window的点击事件导致刚添加的.vis类被立即移除; - 可靠的类判断:用
$(event.target).hasClass('b')判断点击目标,兼容.b有多个类的情况。
内容的提问来源于stack exchange,提问作者Astw41
相关产品推荐
相关产品推荐

