• 前端学习(50)~事件的绑定和事件对象


    绑定事件的两种方式/DOM事件的级别

    我们在之前的一篇文章《04-JavaScript/22-DOM简介和DOM操作》中已经讲过事件的概念。这里讲一下绑定(注册)事件的两种方式,我们以onclick事件为例

    DOM1的写法:onclick

        element.onclick = function () {
    
        }

    举例:

    <body>
    <button>点我</button>
    <script>
        var btn = document.getElementsByTagName("button")[0];
    
        //这种事件绑定的方式,如果绑定多个,则后面的会覆盖掉前面的
        btn.onclick = function () {
            console.log("事件1");
        }
    
        btn.onclick = function () {
            console.log("事件2");
        }
    
    </script>
    </body>

    点击按钮后,上方代码的打印结果:

    事件2

    我们可以看到,DOM对象.事件 = 函数的这种绑定事件的方式:一个元素的一个事件只能绑定一个响应函数。如果绑定了多个响应函数,则后者会覆盖前者。

    DOM2的写法:addEventListener(高版本浏览器)

        element.addEventListener('click', function () {
    
        }, false);

    参数解释:

    • 参数1:事件名的字符串(注意,没有on)

    • 参数2:回调函数:当事件触发时,该函数会被执行

    • 参数3:true表示捕获阶段触发,false表示冒泡阶段触发(默认)。如果不写,则默认为false。【重要】

    举例:

    <body>
    <button>按钮</button>
    <script>
        var btn = document.getElementsByTagName("button")[0];
    
        // addEventListener: 事件监听器。 原事件被执行的时候,后面绑定的事件照样被执行
        // 这种写法不存在响应函数被覆盖的情况。(更适合团队开发)
        btn.addEventListener("click", fn1);
        btn.addEventListener("click", fn2);
    
        function fn1() {
            console.log("事件1");
        }
    
        function fn2() {
            console.log("事件2");
        }
    
    </script>
    </body>

    点击按钮后,上方代码的打印结果:

        事件1
        事件2

    我们可以看到,addEventListener()这种绑定事件的方式:

    • 一个元素的一个事件,可以绑定多个响应函数。不存在响应函数被覆盖的情况。执行顺序是:事件被触发时,响应函数会按照函数的绑定顺序执行。

    • addEventListener()中的this,是绑定事件的对象

    • addEventListener()不支持 IE8 及以下的浏览器。在IE8中可以使用attachEvent来绑定事件(详见下一小段)。

    DOM2的写法:attachEvent(IE8及以下版本浏览器)

        element.attachEvent('onclick', function () {
    
        });

    参数解释:

    • 参数1:事件名的字符串(注意,有on)

    • 参数2:回调函数:当事件触发时,该函数会被执行

    举例:

        <body>
            <button>按钮</button>
            <script>
                var btn = document.getElementsByTagName('button')[0];
    
                btn.attachEvent('onclick', function() {
                    console.log('事件1');
                });
    
                btn.attachEvent('onclick', function() {
                    console.log('事件2');
                });
            </script>
        </body>

    在低版本的IE浏览器上,点击按钮后,上方代码的打印结果:

        事件2
        事件1

    我们可以看到,attachEvent()这种绑定事件的方式

    • 一个元素的一个事件,可以绑定多个响应函数。不存在响应函数被覆盖的情况。注意:执行顺序是,后绑定的先执行。

    • attachEvent()中的this,是window

    兼容性写法

    上面的内容里,需要强调的是:

    • addEventListener()中的this,是绑定事件的对象。

    • attachEvent()中的this,是window。

    既然这两个写法的this不同,那么,有没有一种兼容性的写法可以确保这两种绑定方式的this是相同的呢?我们可以封装一下。代码如下:

        <body>
            <button>按钮</button>
            <script>
                var btn = document.getElementsByTagName('button')[0];
    
                myBind(btn , "click" , function(){
                    alert(this);
                });
    
    
    
                //定义一个函数,用来为指定元素绑定响应函数
                /*
                 * addEventListener()中的this,是绑定事件的对象
                 * attachEvent()中的this,是window
                 *  需要统一两个方法this
                 */
                /*
                 * 参数:
                 *  element 要绑定事件的对象
                 *  eventStr 事件的字符串(不要on)
                 *  callback 回调函数
                 */
                function myBind(element , eventStr , callback){
                    if(element.addEventListener){
                        //大部分浏览器兼容的方式
                        element.addEventListener(eventStr , callback , false);
                    }else{
                        /*
                         * this是谁,由调用方式决定
                         * callback.call(element)
                         */
                        //IE8及以下
                        element.attachEvent("on"+eventStr , function(){
                            //在匿名函数 function 中调用回调函数callback
                            callback.call(element);
                        });
                    }
                }
    
            </script>
        </body>

    事件对象

    当事件的响应函数被触发时,会产生一个事件对象event。浏览器每次都会将这个事件event作为实参传进之前的响应函数。

    这个对象中包含了与当前事件相关的一切信息。比如鼠标的坐标、键盘的哪个按键被按下、鼠标滚轮滚动的方向等。

    获取 event 对象(兼容性问题)

    所有浏览器都支持event对象,但支持的方式不同。如下。

    (1)普通浏览器的写法是 event

    (2)ie 678 的写法是 window.event。此时,事件对象 event 是作为window对象的属性保存的。

    于是,我们可以采取一种兼容性的写法。如下:

        event = event || window.event; // 兼容性写法

    代码举例:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    <script>
        //点击页面的任何部分
        document.onclick = function (event) {
            event = event || window.event; ////兼容性写法
    
            console.log(event);
            console.log(event.timeStamp);
            console.log(event.bubbles);
            console.log(event.button);
            console.log(event.pageX);
            console.log(event.pageY);
            console.log(event.screenX);
            console.log(event.screenY);
            console.log(event.target);
            console.log(event.type);
            console.log(event.clientX);
            console.log(event.clientY);
        }
    </script>
    </body>
    </html>

    event 属性

    event 有很多属性,比如:

    由于pageX 和 pageY的兼容性不好,我们可以这样做:

    • 鼠标在页面的位置 = 滚动条滚动的距离 + 可视区域的坐标

    Event举例

    举例1:使 div 跟随鼠标移动

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <title></title>
        <style type="text/css">
          #box1 {
            width: 100px;
            height: 100px;
            background-color: red;
            /*
            * 开启box1的绝对定位
            */
            position: absolute;
          }
        </style>
    
        <script type="text/javascript">
          window.onload = function() {
            /*
             * 使div可以跟随鼠标移动
             */
    
            //获取box1
            var box1 = document.getElementById("box1");
    
            //给整个页面绑定:鼠标移动事件
            document.onmousemove = function(event) {
              //兼容的方式获取event对象
              event = event || window.event;
    
              // 鼠标在页面的位置 = 滚动条滚动的距离 + 可视区域的坐标。
              var pagex = event.pageX || scroll().left + event.clientX;
              var pagey = event.pageY || scroll().top + event.clientY;
    
              //   设置div的偏移量(相对于整个页面)
              // 注意,如果想通过 style.left 来设置属性,一定要给 box1开启绝对定位。
              box1.style.left = pagex + "px";
              box1.style.top = pagey + "px";
            };
          };
    
          // scroll 函数封装
          function scroll() {
            return {
              //此函数的返回值是对象
              left: window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop,
              right:
                window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft
            };
          }
        </script>
      </head>
      <body style="height: 1000px; 2000px;">
        <div id="box1"></div>
      </body>
    </html>
  • 相关阅读:
    Linux下如何查看版本信息
    linux的top命令参数详解
    浅谈Linux内存管理机制
    python3 判断字符串是否为纯空格组成的方法
    python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
    python3 json数据格式的转换(dumps/loads的使用、dict to str/str to dict、json字符串/字典的相互转换)
    python3 list列表随机选取一个元素、随机选择一个user-agent
    windows系统中,在当前目录下打开cmd命令行的两种方法
    name 'reload' is not defined解决方法
    Vue.js05:vue内联样式
  • 原文地址:https://www.cnblogs.com/Vincent-yuan/p/12513605.html
Copyright © 2020-2023  润新知