事件委托相关

最近在实现一个功能,就是有一串列表项,每当点击其中一个项目,该项目就需要作出相对应的状态改变。如果按照传统做法,可以循环遍历该列表,添加事件监听,但有点麻烦。在某些情况下可以采用事件委托的方式。

HTML
<div class="mon-week-day" >
     <div class="" >month</div>
     <div class="" >week</div>
     <div class="selected" >day</div>
</div>

CSS
.selected{
    color:red;
}

传统做法:循环遍历添加事件监听

var parent = document.getElementsByClassName("mon-week-day")[0];
var len = parent.children.length;
for(let i=0;i<len;i++){
    parent.children[i].addEventListener("click",function(){
       alert(this.textContent)
     })
}

这里有几点需要注意:

1.element.children和element.childNodes还是有点区别的,前者不包括文本节点,后者有

2.nodeValue对于文本节点相当于文本节点的内容,但对于element、document等值为null

二、

事件委托适用于允许事件冒泡的情况,比如click、mouseover、mousout等等(像focus&blur、mouseenter&mouseleave、load&unload就没有事件冒泡)。事件冒泡容易理解,就是从内向外触发,将触发信号逐层传播到最外层。如果我们将click事件绑定在某个父元素上,实际上也能监听到子元素。

var parent = document.getElementsByClassName("mon-week-day")[0];
parent.addEventListener("click",function(e){
    e.target.style.color = "red";
    alert(e.target);
})

这里也有几点需要注意:

1.当事件处理程序直接添加在实际目标上,那么e.target、e.currentTarget和this是等同的,都指向实际目标。但当事件处理程序添加在父节点上(事件冒泡),e.target依旧指向实际目标,但e.currentTarget和this则指向当前事件处理程序绑定的节点。所以如果将上述代码中的e.target改为e.currentTarget,就不能达到”点击某个元素,则只是该元素发生相应变化“的目的

三、问题

问题来了,如果我只是希望点击某个元素,则只是该元素发生相应变化,且在点击同一列表的其他元素时,原先的元素可以恢复初始状态,该怎么办?

当然如果能用:hover、:focus这些伪类就可以实现那自然好,实在不行,也可以用原生JS或Jquery实现。但原生JS目前我只能是循环遍历添加监听事件,考虑到要借助事件委托的话可以用Jquery的$(e.target)实现。

比如我用class来控制样式的变化

var parent = document.getElementsByClassName("mon-week-day")[0];
for(let i of parent.children){
   i.addEventListener("click",function(){  
   		for(let i of parent.children){
           i.className = "";
           //console.log(i.className);
        }//在正式改变class之前,要先将所有的class清空(同在一个起跑线上)
        this.className = "selected";
    })
}

如果用Jquery还会更简单一些

要遍历的👇
$(".mon-week-day>div").map(function(){
   $(this).on("click",function(){//this引用每次迭代的DOM元素
      $(this).siblings().removeClass();//把同胞元素的class值清空
      $(this).attr("class","selected");
   }) 
})
不用遍历的(事件委托)👇
$(".mon-week-day").on("click",function(e){
    $(e.target).siblings().removeClass();
    $(e.target).attr("class","selected");
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值