DOM相关

作者: zhenghongmo | 来源:发表于2019-12-16 18:09 被阅读0次

1. DOM事件模型

DOM事件模型

前半部分,事件从最外面的父div依次传递到最里面的后代div,1-2-3-4这部分我们叫捕获过程。
之后事件又从最里层的后代div逐层传出,4-3-2-1这部分我们叫冒泡过程。

  • addEventListener第三个参数可以不传,默认是false,这个参数控制是否捕获触发。
    所以我们只传两个参数时,这个事件是冒泡传递触发的,
    当第三个参数存在且为true时,事件是捕获传递触发的。
x.addEventListener('click', function(){
  console.log('冒泡')
})

x.addEventListener('click', function(){
  console.log('捕获')
},true)

  • 事件冒泡
  • 事件捕获
  • 如果这个元素是被点击的元素,那么捕获不一定在冒泡之前,顺序是由监听顺序决定的
  • 扩展
    阻止冒泡和捕获: w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true
    取消默认事件: w3c的方法是e.preventDefault(),IE则是使用e.returnValue = false;

2. 移动端触摸事件

  • touchstart touchmove touchend touchcancel
  • 模拟 swipe 事件:记录两次 touchmove 的位置差,如果后一次在前一次的右边,说明向右滑了。

3. 事件委托

  • 假设父元素有4个儿子,我不监听4个儿子,而是监听父元素,看触发事件的元素是哪个儿子,这就是事件委托
  • 可以监听还没有出生的儿子(动态生成的元素)。省监听器。
<ul>
    <li><span>点击<span></li>
    <li>点击</li>
</ul>

---------------------------------------------------
//错误版
 ul.addEventListener('click', function(e){
     if(e.target.tagName.toLowerCase() === 'li'){
         fn() // 执行某个函数
     }
 })

//高级版
var elementUl = document.querySelector('ul');
function fn(event) {
    var el = event.target;
    while (el.tagName !== 'LI') {
        if (el === elementUl){
            el =null;
            break;
        }
        el = el.parentNode;//返回當前元素的父节点
    }

    if (el) {
        console.log(el)
    }
}
elementUl.addEventListener('click', fn);

//答案总结
 function delegate(element, eventType, selector, fn) {
     element.addEventListener(eventType, e => {
       let el = e.target
       while (!el.matches(selector)) {
         if (element === el) {
           el = null
           break
         }
         el = el.parentNode
       }
       el && fn.call(el, e, el)
     })
     return element
   }
思路是点击 span 后,递归遍历 span 的祖先元素看其中有没有 ul 里面的 li

相关文章

网友评论

      本文标题:DOM相关

      本文链接:https://www.haomeiwen.com/subject/mfvdnctx.html