DOM事件

作者: 陈裔松的技术博客 | 来源:发表于2018-12-10 17:42 被阅读0次

    基本概念

    事件就是文档或浏览器窗口中发生的一些特定的交互瞬间
    DOM事件的级别,准确的说,是DOM标准定义的级别,分为以下几个:

    DOM0:element.onClick=function(){}
    // 只能绑定一个事件处理函数,如果绑定了多个事件处理,取最后一个
    // 事件冒泡机制

    DOM2:element.addEventListener('click',function(){},false)
    // 可以绑定多个事件处理函数
    // 添加了事件捕获机制
    // 最后一个参数false代表事件在冒泡阶段执行,true代表事件在捕获阶段执行

    DOM3:element.addEventListener('keyup',function(){},false)
    // DOM3相对于DOM2,事件类型增加了许多,比如鼠标事件,键盘事件等。

    好奇:为什么么有DOM1呢?这是因为DOM1标准制定的时候,没有设计跟事件相关的东西,所以在说DOM事件级别的时候,直接就跳过DOM1。但是DOM1标准是存在的。

    事件模型

    事件模型分为捕获和冒泡两个过程

    事件流

    浏览器为当前页面与用户做交互(比如点击鼠标左键)的过程中,这个交互(鼠标左键点击)是怎么传到页面上,就是事件流。
    事件流分为三个阶段,捕获 => 目标阶段 => 冒泡

    • 第一阶段是捕获
    • 第二阶段是目标阶段
      事件通过捕获到达目标元素(比如点击某一个按钮),就是目标阶段。
    • 第三阶段是冒泡
      事件从目标元素上传到window对象,就是冒泡。

    描述DOM事件捕获的具体流程

    window => document => html => body => ... => 目标元素
    【知识点】
    取得body标签的方法:document.body
    取得html标签的方法:document.documentElement

    Event对象的常见应用

    • event.preventDefault()
      概念:阻止浏览器默认事件
      举例:比如对一个a标签的点击事件设置event.preventDefault(),就会阻止跳转行为。

    • event.stopPropagation()
      概念:该方法作用在后续节点上,目的在执行完绑定到当前元素上的所有事件处理程序之后,停止执行所有后续节点的事件处理程序,也就是阻止冒泡。
      举例:比如子元素绑定了一个点击事件,父元素也绑定了一个点击事件。我们想要点击子元素的时候做一件事,点击父元素的时候做另外一件事。如果不做阻止冒泡,在点击子元素的时候,父元素也会被响应,这不是想要的结果。

    • event.stopImmediatePropagation()
      概念:该方法作用在当前节点以及事件链上的所有后续节点上,执行完当前事件处理程序之后,停止当前节点以及所有后续节点的事件处理程序的运行
      举例:比如某个元素绑定了点击事件A和事件B,当点击发生的时候,事件A和事件B都会响应。如果希望事件A响应而事件B不响应,该怎么做呢?这时候只需要在事件A的响应函数中,写上event.stopImmediatePropagation()即可。此方法常用于事件的优先级处理上。

    • event.currentTarget和event.target
      event.currentTarget:返回绑定事件的元素
      event.target:返回触发事件的元素
      用一个例子解释这两个属性会比较清楚。
      当点击第一个子元素1的时候,显示的内容是:<li>1</li> 和 UL
      当点击第二个子元素2的时候,显示的内容是:<li>2</li> 和 UL

        <ul id="ul">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
        </ul>
        <script>
            const ul = document.getElementById('ul');
            ul.addEventListener('click',function(event){
                console.log(event.target)
                console.log(event.currentTarget.nodeName)
            });
        </script>
    

    自定义事件

    • 创建自定义事件:new Event('eventName') / new CustomEvent('custom',{detail:{data}})
    • 绑定自定义事件:与绑定其他事件的方法一致
    • 触发自定义事件:dom.dispatchEvent(eve);
        <button id="button1">按钮1</button>
        <script>
            var button1 = document.getElementById('button1');
    
            var eve = new Event('custom');
            button1.addEventListener('custom',function(){
                console.log('我是一个自定义事件');
            });
            
            button1.dispatchEvent(eve);
        </script>
    
        <script>
            var button2 = document.getElementById('button2');
    
            var eve = new CustomEvent('custom',{
                detail:{
                    name:'song'
                }
            });
            button2.addEventListener('custom',function(event){
                console.log('我是一个自定义事件:',event.detail.name);
            });
            
            button2.dispatchEvent(eve);
        </script>
    

    封装一个事件绑定函数

    通过fn.call(target, e)使回调函数中的this指向event.target,从而达到和addEventListener一样的效果。
    a.matches(b)的意思是判断a字符串中是否包含b字符串,如果包含返回true,反之返回false。

    <ul id="ul">
        <li id="liFirst">1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>
    
    <script type="text/javascript">
        function bindEvent(elem, type, selector, fn) {
            if (fn == null) {
                fn = selector;
                selector = null;
            }
            elem.addEventListener(type, function (e) {
                var target;
                target = e.target;
                if (selector) {
                    // 代理
                    if (target.matches(selector)) {
                        fn.call(target, e);
                    }
                } else {
                    // 不是代理
                    fn.call(target, e);
                }
            });
        }
    
        var liFirst = document.getElementById('liFirst');
        bindEvent(liFirst, 'click', function (e) {
            e.stopPropagation();
            console.log(this.innerHTML); // 1
        });
    
        var ul = document.getElementById('ul');
        bindEvent(ul, 'click', 'li', function (e) {
            console.log(this.innerHTML); // 点击哪个,显示哪个
            // target: <li>2<li>
            // selector: li
        });
    </script>
    

    鼠标事件

    • onload:页面加载事件
    • onclick:鼠标点击事件
    • onmouseover:鼠标滑过事件
    • onmouseout:鼠标离开事件
    • onfocus:获得焦点时触发
    • onblur:失去焦点时触发
    • onchange:域的内容改变时发生
    • onsubmit:表单中的确认按钮被点击时发生(加在表单上,而不是按钮上)
    • onmousedown:鼠标按钮在元素上按下时触发
    • onmousemove:在鼠标指针移动时发生
    • onmouseup:在元素上松开鼠标按钮时触发
    • onresize:当调整浏览器窗口的大小时触发
    • onscroll:拖动滚动条滚动时触发

    键盘事件

    • onkeydown:在用户按下一个键盘按钮时发生
    • onkeypress:在键盘按键被按下并释放一个键时发生
    • onkeyup:在键盘按键被松开时发生
      知识点:keyCode,就是返回onkeypress / onkeydown / onkeyup事件触发的键的代码

    相关文章

      网友评论

          本文标题:DOM事件

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