在一个小项目中遇到了一个问题:onclick事件需要点击三次才能触发??
这个bug简直让人不能忍,然后我誓死要改好这个bug...
首先看看我的dom结构吧!
<ul>
<li>......</li>
<li>.......</li>
<li>......</li>
<li>.......</li>
..........
</ul>//就是ul里面有多个li
我所要实现的功能就是给每一个li添加相同的click事件
首先我的li 都是动态添加的,只需要写一个样式然后li里面的内容都是变量,然后循环打印。
react 里面有一个ref属性,通过给某个元素设置ref属性,然后通过refs来找到这个元素,可是我不能给这些li加这个属性,因为这样我所有动态添加的li都带上这个属性的话,最后相当于只能找到最后一个li。也就是每个元素的ref属性值不能相同,否则会覆盖。
那么,我就要换一种方式去找到我每次点击的哪个li啊。。。。
然后我就这样子去找每个点击的li。
var tips=this.refs.tip.getElementsByTagName("li");
for(let i=0;i<dateAry.length;i++){
tips[i].onclick=function(event){
var tip=this.getElementsByTagName("div")[1];
if(tip.style.display=="none"){
tip.style.display='block';
}else{
tip.style.display='none';
}
/!* var a=tip.style.display="none";
var b=tip.style.display='block';
tip.style.display=="none"?b:a;*!/
event.stopPropagation();
event.preventDefault();
}
}
也是因为这样导致我需要点击三下才能触发li的点击事件,通过测试我发现原因:
点击第一次找到了li,第二次给所点击的li添加属性 display:none 第三次改变属性display:block
一.什么是事件委托
事件委托是利用事件冒泡的原理 利用父级去触发子集的事件
如果不用事件委托,将每一个li都去添加click事件监听,非常麻烦。
另外就是如果通过js动态创建的子节点,需要重新绑定事件。
而利用事件委托的话,只需要给父级绑定一个事件监听,即可让每个li都绑定上相应的事件。
把上面的代码经过如下修改,解决了点击三次才触发li点击事件的bug!!!
var ul=this.refs.tip;
var target=event.target;
var detail=null;
if(target.tagName.toLowerCase() == 'div'){
detail=target.parentNode.childNodes[1];
if(detail.style.display=="block"){
detail.style.display='none';
}else{
detail.style.display='block';
}
}else if(target.tagName.toLowerCase() == 'img'&& target.className.toLowerCase() == 'expand_img'){
detail=target.parentNode.parentNode.nextSibling;
if(detail.style.display=="block"){
detail.style.display='none';
}else{
detail.style.display='block';
}
}
这里就写一下我的思路吧!
这里主要用到了事件代理的方式,我把点击事件绑定到ul上,然后利用event.target获取到事件源,也就是我点击了ul中的哪一个元素,因为我在li里放了上下两个div标签,上面是用户的名字,下面是用户的详细信息。在我点击用户名字的时候实现用户详细信息的而显示与隐藏。这里就得根据我所点击的事件源找到它所在li中的第二个div,也就是用户的详细信息所在的div,然后控制它的显示与隐藏。
重点就在我怎么去找这个div?
这些都在代码里,主要是通过事件源与目标div之间的关系去找及event.target的属性去筛选掉不希望触发事件的元素。
表述不太好!具体源码在:
http://www.jianshu.com/p/df695c788256