DOM事件委托之取消事件冒泡

    事件代理又叫事件委托,JavaScript高级程序设计上讲:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。     

    但如果我们不想实现事件委托,却发生了事件冒泡呢?

     在遇到父元素和子元素都有点击事件的情况下,点击父元素(父元素范围 > 子元素)是没有任何问题的,但当我们点击子元素时就不得不面临“事件冒泡”的问题了。但开心的是,事件冒泡是可以取消的。

    原本只是想解决demo中的一个小问题,解决时候发现,这不正是事件冒泡问题吗?DOM事件委托都快忘记了,正好趁此把笔记拿出来再梳理一遍。

以下是我遇到事件冒泡问题的场景

kbdX.onclick = function(keyb){
    keyi = keyb.target.innerText[0].toLowerCase()
    website = hash[keyi];
    console.log(website)
    // location.href = 'http://' +  website;
    window.open('http://' +  website, '_blank');
}
buttonXE.textContent = 'E';
buttonXE.id = keys[i][j];
buttonXE.onclick = function(keyd){
    // keyd.target是用户点击的元素
    console.log(keyd.target.id)
    keyX = keyd.target.id
    new_website = prompt('更改按键对应的导航网址')
    hash[keyX] = new_website // hash变更
    localStorage.setItem('update_website', JSON.stringify(hash));
    keyd.stopPropagation(); // 阻止冒泡事件
    location.reload(); // 页面刷新重载
    // console.log(hash)
}
divX.appendChild(kbdX);
kbdX.appendChild(buttonXE);

    显然 kbdX 是 buttonXE 的父级,当我们点击 buttonXE 时发现, kbdX点击事件同样会被触发,这就是因为发生了事件冒泡。

   

     那么先让我们来了解一下什么是事件冒泡呢?

     从外向内找监听函数,事件捕获;(网景提出) 从内向外找监听函数,事件冒泡。(IE5提出)

    同时我们还要区分target VS currentTarget :

    e.target:用户操作的元素

    e.currentTarget:程序员监听的元素

    this是ecurrentTarget,所以不推荐使用this,担当只有一个div 被监听(不考虑父子同时被监听),fn分别在捕获阶段和冒泡阶段监听click事件,用户点击的元素就是开发者监听的。 

    取消事件冒泡

    捕获不可以取消,冒泡可以 e.stopPropagation()可中断冒泡,浏览器不再向上走。

    这里我就是采用的e.stopPropagation()直接中断冒泡,阻止了 kbdX点击事件的发生。

    有些事件不可取消冒泡 ,在scroll event中,Bubble---是否冒泡,Cancelable---开发者是否可以取消冒泡

    举例:如何阻止冒泡 scroll事件不可取消冒泡,阻止scroll默认动作没用,因先有滚动才有滚动事件;要阻止滚动,可阻止wheel和touchstart的默认动作;注意需要找准滚动条所在元素;若滚动条还能用,用CSS让滚动条display: none

     CSS使用overflow: hidden可以直接取消滚动条 此时JS依然可以修改scrollTop

 

     当然我们也可以自定义事件,这就属于DOM事件委托的拓展了,以后学习到会再整理。

    

    

原文地址:https://www.cnblogs.com/lynn-z/p/13262705.html