zoukankan      html  css  js  c++  java
  • JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数

    本篇体验JavaScript事件的基本面,包括:

     

    事件必须在页面元素加载之后起效
    点击事件的一个简单例子
    为元素注册多个点击事件
    获取事件参数

    跨浏览器事件处理


    □ 事件必须在页面元素加载之后起效

     

    有这样一段简单的代码:

    <head>
    
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    
        <title></title>
    
        <style>
    
            #box {
    
                background: blue;
    
                height: 100px;
    
                 100px;
    
                left: 50px;
    
                top: 50px;
    
            }
    
        </style>
    
    </head>
    
    <body>
    
        <div id="box"></div>
    
    </body>

    现在,我们想给id为box的div添加事件,创建一个script.js文件。

    (function() {
    
        var ele = document.getElementById("box");
    
        ele.onclick = function() {
    
            this.style.background = "red";
    
        };
    
    }());
    

    是一个匿名函数,只要被引用,自动运行。

     

    如果把script.js放在head区域。

    <head>
    
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    
        <title></title>
    
        ......
    
        <script src="script.js"></script>
    
    </head>

    点击页面蓝色区域会报错:Cannot set property 'onclick' of null

     

    找不到需要实施onclick事件的元素。如果我们把script.js放在body区域底部,又会怎样呢?

    <body>
    
        <div id="box"></div>
    
        <script src="script.js"></script>
    
    </body>

    点击页面蓝色区域背景色变成红色。

     

    由此可以看出:事件必须在页面元素加载完毕之后才可以实施。

     

    以上,通过把JavaScript代码放在需要实施事件元素的下方,保证了先加载元素,再执行事件,这很好。而实际上,通过window的onload方法也可以保证所有页面元素加载完毕再执行事件。

     

    修改script.js的代码为:

    (function () {
    
        window.onload = function() {
    
            var ele = document.getElementById("box");
    
            ele.onclick = function () {
    
                this.style.background = "red";
    
            };
    
        };
    
    }());
    

    把script.js代码放在head部分。点击页面蓝色区域背景色变成红色。

     

    □ 点击事件的一个简单例子

     

    <head>
    
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    
        <title></title>
    
        <style>
    
            .on {
    
                background-color: white;
    
                color: black;
    
            }
    
            .off {
    
                background-color: black;
    
                color: white;
    
            }
    
        </style>
    
        <script src="script.js"></script>
    
    </head>
    
    <body class="on">
    
        <h1>Hello World</h1>
    
        <p>欢度国庆</p>
    
        <button id="open">开</button>
    
        <button id="close">关</button>
    
    </body>
    

     

    script.js的代码为:

    (function () {
    
        window.onload = function() {
    
            var openBtn = document.getElementById("open");
    
            var closeBtn = document.getElementById("close");
    
            openBtn.onclick = function() {
    
                document.body.className = "on";
    
            };
    
            closeBtn.onclick = function() {
    
                document.body.className = "off";
    
            };
    
        };
    

     

    一切运行正常。但,如果我们在script.js中给开按钮再注册一个事件。

    (function () {
    
        window.onload = function() {
    
            var openBtn = document.getElementById("open");
    
            var closeBtn = document.getElementById("close");
    
            openBtn.onclick = function() {
    
                document.body.className = "on";
    
            };
    
            closeBtn.onclick = function() {
    
                document.body.className = "off";
    
            };
    
            openBtn.onclick = function() {
    
                alert('hello');
    
            };
    
        };
    
    }());
    

    2
    当点击"开"按钮后,弹出alert。由此可以看出:每次只能为元素注册一个onclick事件。

     

    □ 为元素注册多个点击事件

     

    使用addEventListener方法,可以为元素同时注册多个点击事件。

     

    修改script.js代码如下:

    (function () {
    
        window.onload = function() {
    
            var openBtn = document.getElementById("open");
    
            var closeBtn = document.getElementById("close");
    
            var open = function() {
    
                document.body.className = "on";
    
            };
    
            var close = function() {
    
                document.body.className = "off";
    
            };
    
            //第三个参数设置成false,表示允许事件冒泡
    
            openBtn.addEventListener("click", open, false);
    
            openBtn.addEventListener("click", function() { alert('hello'); }, false);
    
            closeBtn.addEventListener("click", close, false);
    
        };
    
    }());
    

     

    当然,也可以移除注册的事件。

            //移除EventListner事件
    
            openBtn.removeEventListener("click", open, false);

     

    注意:在IE8下没有addEventListner,应该使用attachEvent。

    openBtn.attachEvent("onclick", function(evt)){
    
        alert(evt.srcElement);//相当于target属性
    
        document.body.className = "on";
    
    };

    ○ attachEvent只有2个参数
    ○ 事件名称是onclick,而不是click
    ○ event.srcElement相当于event.target

     

    如果在IE8下注销事件。

    openBtn.detachEvent("onclick",函数名称);

     

    □ 获取事件参数

     

    在每次发生事件的时候,所有的事件参数信息都被放在了一个event变量中。修改script.js代码为:

    (function () {
    
        window.onload = function() {
    
            var openBtn = document.getElementById("open");
    
            var closeBtn = document.getElementById("close");
    
            var open = function (e) {
    
                alert(e.type + " " + e.target);
    
                document.body.className = "on";
    
            };
    
            var close = function (e) {
    
                alert(e.type + " " + e.target);
    
                document.body.className = "off";
    
            };
    
            //第三个参数设置成false,表示允许事件冒泡
    
            openBtn.addEventListener("click", open, false);
    
            closeBtn.addEventListener("click", close, false);
    
        };
    
    }());    
    

    可见,函数的事件参数在大多数情况下被省略了,如果想获取事件信息,这个event参数还是很有用的。   

    □ 跨浏览器事件处理

     

    正因为,在不同的浏览器下事件处理方式不同,比如在chrome下接收addEventListener方法,而在IE8下接收attachEven方法,我们有必要针对跨浏览器提供一个通用的事件处理机制。

     

    创建eventUtiltiy.js文件。

    var eventUtility = {
    
        addEvent: function(ele, type, fn) {
    
            if (typeof addEventListener !== "undefined") {
    
                ele.addEventListener(type, fn, false);
    
            } else if (typeof attachEvent !== "undefined") { //比如在IE8下
    
                ele.attachEvent("on" + type, fn);
    
            } else {
    
                //获取属性通过obj.属性名称,等同于obj[属性名称]
    
                //执行事件通过obj.事件名称,等同于obj[事件名称]
    
                ele["on" + type] = fn;
    
            }
    
        },
    
        removeEvent: function(ele, type, fn) {
    
            if (typeof removeEventListener !== "undefined") {
    
                ele.removeEventListener(type, fn, false);
    
            } else if (typeof detachEvent !== "undefined") {
    
                ele.detachEvent("on" + type, fn);
    
            } else {
    
                ele["on" + type] = null;
    
            }
    
        },
    
        getTarget: function(event) {
    
            if (typeof event.target !== "undefined") {
    
                return event.target;
    
            } else {
    
                return event.srcElement;
    
            }
    
        },
    
        preventDefault: function(event) {
    
            if (typeof event.preventDefault !== "undefined") {
    
                event.preventDefault();
    
            } else {
    
                event.returnValue = false;
    
            }
    
        },
    
        getCharCode: function(event) {
    
            if (typeof event.charCode === "number") {
    
                return event.charCode;
    
            } else {
    
                return event.keyCode;
    
            }
    
        }
    
    };
    

     

    页面部分。

    <head>
    
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    
        <title></title>
    
        <style>
    
            .on {
    
                background-color: white;
    
                color: black;
    
            }
    
            .off {
    
                background-color: black;
    
                color: white;
    
            }
    
        </style>
    
        
    
    </head>
    
    <body class="on">
    
        <h1>Hello World</h1>
    
        <p>欢度国庆</p>
    
        <button id="open">开</button>
    
        <button id="close">关</button>
    
        <script src="eventUtility.js"></script>
    
        <script src="script.js"></script>
    
        
    
    </body>
    

     

    script.js部分。

    (function () {
    
            var openBtn = document.getElementById("open");
    
            var closeBtn = document.getElementById("close");
    
            var open = function () {
    
                //alert(e.type + " " + e.target);
    
                document.body.className = "on";
    
            };
    
            var close = function () {
    
                //alert(e.type + " " + e.target);
    
                document.body.className = "off";
    
            };
    
            
    
            eventUtility.addEvent(openBtn, "click", open);
    
            eventUtility.addEvent(closeBtn, "click", close);
    
    }());
    

     

     

    “JavaScript进阶系列”包括:

    JavaScript进阶系列01,函数的声明,函数参数,函数闭包

    JavaScript进阶系列02,函数作为参数以及在数组中的应用

    JavaScript进阶系列03,通过硬编码、工厂模式、构造函数创建JavaScript对象

    JavaScript进阶系列04,函数参数个数不确定情况下的解决方案

    JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数

    JavaScript进阶系列06,事件委托

    JavaScript进阶系列07,鼠标事件

  • 相关阅读:
    python的复制,深拷贝和浅拷贝的区别(转)
    linux下ffmpeg安装(转)
    Linux下的tar压缩解压缩命令详解(转)
    centos7安装python-pip(转)
    爬山算法和模拟退火算法简介
    协方差、协方差矩阵定义与计算
    七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)
    Canny边缘检测算法原理及其VC实现详解(二)
    Canny边缘检测算法原理及其VC实现详解(一)
    perforce变量配置与使用
  • 原文地址:https://www.cnblogs.com/darrenji/p/4005638.html
Copyright © 2011-2022 走看看