zoukankan      html  css  js  c++  java
  • DOM事件对象用法

    分为三个阶段:事件捕获阶段、目标阶段、事件冒泡阶段。

    事件捕获老版本浏览器(IE<=8)不支持,但是事件冒泡可以放心使用。

    12

    事件处理程序

    一共四类写法,基本都见过,看下写法就知道怎么回事儿了。

    1. HTML事件处理程序

    <input type="button" value="Click me" onclick="ShowMessage()"/>
    

    2. DOM0级事件处理程序

    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
        alert("click!");
        alert(this.id);//this指向myBtn,可继续获取myBtn的其余属性
    }
    

    3. DOM2级事件处理程序

    定义事件及删除事件的两个方法:addEventListener、removeEventListener。

    var btn = document.getElementById("myBtn");
    btn.addEventListener("click",function(){
        alert(this.id);
    },false);
    

    第三个参数:true,表示在捕获阶段触发;false,表示程序在冒泡阶段触发;

    removeEventListener()的第二个参数必须传入与addEventListener()中相同的处理函数(传入相同的函数引用,而不是形同函数!),否则不会生效。

    var handler = function handler(){
        alert(this.id);
    }
    btn.addEventListener("click", handler, false);
    btn.removeEventListener("click", handler, false);
    

    4. IE事件处理函数

    IE就是这么另类(IE8及更早版本)

    定义事件及删除事件的两个方法:attachEvent、detachEvent。因为只支持冒泡,故第三个参数没有;且第一个参数需要带上“on”!

    var handler = function handler(){
        alert(this.id);
    }
    btn.attachEvent("onclick", handler);
    btn.detachEvent("onclick", handler);
    

    事件对象

    事件触发会在handler中传入事件对象event。

    1. DOM中的事件对象

    event的成员属性及说明如下,以下属性皆为只读:

    属性/方法说明示例
    bubble 表示事件是否冒泡 event.bubble -> true/false
    cancelable 是否可以取消事件的默认行为 event.cancelable -> true/false
    currentTarget 事件函数正在处理事件的那个元素,比如委托document处理  
    defaultPrevented 为true则表示已经调用了 preventDefault()  
    eventPhase 事件处理阶段,1捕获阶段,2目标,3冒泡阶段 event.eventPhase === 1
    preventDefault() 取消默认行为 event. preventDefault();
    stopPropagation() 取消进一步冒泡捕获行为 event.stopPropagation();
    stopImmediatePropagation() 取消进一步冒泡捕获行为,并阻止任何事件处理程序被调用 event.stopImmediatePropagation();
    target 设计目标 event.target === getElementById(id)
    type 触发事件的类型 event.type === 'click'

    2. IE中事件对象

    因为IE中没有捕获,故简单了些。注意对比两个表的区别!

    属性/方法说明示例
    returnValue 取消默认行为 event. returnValue = false; //取消默认行为
    cancelBubble 取消进一步冒泡捕获行为 event.cancelBubble = true;//取消冒泡
    srcElement 设计目标 event.srcElement === getElementById(id)
    type 触发事件的类型 event.type === 'click'

    3. 跨浏览器兼容方案

    为了保证大多数浏览器的兼容,故只需要考虑冒泡阶段的实现。上面说的很清楚了,这里直接上代码。

    var EventUtil = {
        // 绑定事件
        addHandler: function addHandler(element, type, handler) {
            if (element.addEventListener) {
                element.addEventListener(type, handler, false);
            } else if (element.attachEvent) {
                element.attachEvent('on' + type, handler);
            } else {
                element['on' + type] = handler;
            }
        },
        // 解绑事件
        removeHandler: function removeHandler(element, type, handler) {
            if (element.removeEventListener) {
                element.removeEventListener(type, handler, false);
            } else if (element.detachEvent) {
                element.detachEvent('on' + type, handler);
            } else {
                element['on' + type] = null;
            }
        },
        // 获取事件对象event
        getEvent: function getEvent(event) {
            return event || window.event;
        },
        // 获取触发目标
        getTarget: function getTarget(event) {
            return event.target || event.srcElement;
        },
        // 阻止默认行为
        preventDefault: function preventDefault(event) {
            if (event.preventDefault) {
                event.preventDefault()
            } else {
                event.returnValue = false;
            }
        },
        // 取消冒泡
        stopPropagation: function stopPropagation(event) {
            if (event.stopPropagation) {
                event.stopPropagation()
            } else {
                event.cancelBubble = true;
            }
        }
    }
    

    事件的代理/委托的原理以及优缺点

    这是靠事件的冒泡机制来实现的,优点是

    1、可以大量节省内存占用,减少事件注册,比如在table上代理所有td的click事件就非常棒
    2、可以实现当新增子对象时无需再次对其绑定事件,对于动态内容部分尤为合适

    手写原生js【实现事件代理】,并要求兼容浏览器

    考核对事件对象event的了解程度,以及在IE下对应的属性名。其实此时如果你说就是用target/currentTarget,以及IE下的srcElement/this,基本就可以略过了

    绑到按钮上:

    var btn = document.getElementById("myBtn");
    btn.addEventListener("click",function(){
        console.log(event.currentTarget === this);//true
        console.log(event.target === this);//true
    },false);
    

    绑到document上:

    var btn = document.getElementById("myBtn");
    document.body.onclick = function(){
        console.log(event.currentTarget === this );//true
        console.log(document.body === this );//true
        console.log(event.target === btn);//true
    }
    

    实现事件模型

    一个bind一个trigger,分别实现绑定事件和触发事件,核心需求就是可以对某一个事件名称绑定多个事件响应函数,然后触发这个事件名称时,依次按绑定顺序触发相应的响应函数。

    大致实现思路就是创建一个类或是匿名函数,在bind和trigger函数外层作用域创建一个字典对象,用于存储注册的事件及响应函数列表,bind时,如果字典没有则创建一个,key是事件名称,value是数组,里面放着当前注册的响应函数,如果字段中有,那么就直接push到数组即可。trigger时调出来依次触发事件响应函数即可。

    事件如何派发也就是事件广播(dispatchEvent)

    这个是自定义事件及事件触发的应用(createEvent/dispatchEvent, createEventObject/fireEvent)

    一般我们在元素上绑定事件后,是靠用户在这些元素上的鼠标行为来捕获或者触发事件的,或者自带的浏览器行为事件,比如click,mouseover,load等等,有些时候我们需要自定义事件或者在特定的情况下需要触发这些事件。这个时候我们可以使用IE下fireEvent方法,高级浏览器(chrome,firefox等)有dispatchEvent方法。

  • 相关阅读:
    windows使用zip包安装mysql8.0.12
    windows使用msi包安装mysql8.0.12
    查看mysql的bin-log日志
    修改zabbix的端口号
    mysql备份脚本并保留7天
    上海坤亿
    nginx面试题
    服务器导入导出数据
    轮询和长轮询
    Python 三种读文件方法read(), readline(), readlines()及去掉换行符
  • 原文地址:https://www.cnblogs.com/holy-amy/p/7401271.html
Copyright © 2011-2022 走看看