问题
最近在项目中遇到了这样一个问题:
我需要动态改变一个div的class,改变他的样式,但是每一个class都需要绑定一个函数动作,但是通过增加删除class后就获取不到这个元素了
问题复现
html
<body>
<div class="cl1"></div>
</body>
css
.cl1{
width:100px;
height:100px;
background-color: red;
}
.cl2{
width:100px;
height:100px;
background-color: blue;
}
js
$(".cl1").click(function(){
$(this).addClass("cl2").removeClass("cl1");
});
$(".cl2").click(function(){
$(this).addClass("cl1").removeClass("cl2");//这个函数没有作用
});
//问题是:javascript一次加载完毕后,后来通过点击事件生成的节点就不会绑定动作事件
解决办法
我的想法:
1.既然绑定不到,我可以在节点转换后去绑定事件
$(".cl1").click(function(){
$(this).addClass("cl2").removeClass("cl1").click(function(){
$(".cl2").addClass("cl1").removeClass("cl2")
});
});
//这样做呢,确实是获取到了元素,但是这种无限循环的方式最终只能陷入死循环
2.通过判断class的名称去制定动作执行
$("div").click(function () {
var classname=$(this).attr("class");
if(classname=="cl1"){
$(this).addClass("cl2").removeClass("cl1")
}
else if(classname=="cl2"){
$(this).addClass("cl1").removeClass("cl2")
}
})
//经测试,这种方式是稳定并且好用的
3.增加count去判断,0执行一种情况,1执行另一种情况;这种想法和第二种本质一样,而且还要引入新的变量,会造成变量污染,可用但不推荐
扩展
百度这个问题的时候,在网上看到了有关动态节点新增不能获取的情况;在此也做一次测试;
问题复现
html和css代码同上
js代码:
$(".cl1").click(function(){
$(this).append("<button id='btn'>click me</button>");
})
$("#btn").click(function(){
console.log("yes");
})
//这里的按钮点击事件是没有用的;原因和上述大概一样,JavaScript提前加载完毕,获取不到dom节点
解决办法
1.当加载完毕后,在回调函数里进行获取
可以看到,这种办法是可以的.与上述增改样式不同,这里执行的方法有可能只是一种情况,不会陷入死循环,互相调用;所以在一定场景下可以使用;
2.判断当节点加载完毕后,在进行dom节点获取
经过各种测试,发现判断条件没有切入点:
因为我们触发这个事件,一般是点击click me这个按钮,而这个按钮的dom节点获取却无法被触发,所以这种办法以失败告终
3.查阅网上的资料
网上很多资料都是没有用的,由于jquery1.9以上废弃了很多方法,我这里使用的3.4.1最新版本截止到2019年6月4日
但是思想大概都是"委托的思想",与java里的差不多
经过测试发现可行,代码如下:
$(".cl1").on("click","button",function(){
console.log("yes");
})
//这里是网上推荐的一种方法,原理大概就是利用了捕获的思想
$(父元素).on("click",子元素,fn);其实就是利用点击父元素,去捕获子元素,进行动作
相关变形:
$(".cl1").click(function(ev){
var target=ev.target;//利用目标元素,判断,我点击后,目标元素是不是我想要的
if(target.id=="btn"){
console.log("yes")
}
})
下面是我借鉴的相关链接:
https://www.cnblogs.com/liugang-vip/p/5616484.html