JavaScript事件

本文详细介绍了事件流的概念,包括事件冒泡与事件捕获,同时对比了不同浏览器中的事件处理方式,如DOM0级、DOM2级及IE事件处理程序,并讲解了事件委托的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事件流

事件流描述的是从页面中接收事件的顺序

事件流描述
事件冒泡IE的事件流,事件从最具体的节点开始,然后逐级向上冒泡到不具体的节点
事件捕获不具体的节点先接收到事件,具体的节点最后接收到事件
DOM事件流DOM事件流包含三个阶段:事件捕获、处于目标事件阶段、事件冒泡阶段

事件处理程序

事件处理程序包括:HTML事件处理程序、DOM0级事件处理程序、DOM2级事件处理程序和IE事件处理程序

HTML事件处理程序

在HTML代码中直接指定绑定的事件处理程序(可以是函数也可以是js代码)。例如:

<input onclick="showOn()">显示</input>
<input onclick="console.log('hello')">显示</input>
DOM0级事件处理程序

在目标元素上添加事件处理程序属性。

var ele = document.getElementById("test");
ele.onClick = function(){
    console.log("hello");
}

如果要删除DOM0级事件处理程序,将事件处理程序属性值设置为null即可。

ele.onClick = null;
DOM2级事件处理程序

DOM2级事件处理程序提供了两个方法,用于指定添加和删除事件处理程序的操作:addEventListener()removeEventListener()。方法接收三个参数:事件名、事件处理程序、一个布尔值。布尔值为true表示在事件捕获阶段调用事件处理程序,为false表示在事件冒泡阶段调用事件处理程序。

var ele = document.getElementById("test");
function show(){
    console.log("hello");
}
ele.addEventListener("click", show, false); //冒泡阶段调用
ele.removeEventListener("click", show, false);  //传入相同参数

注意: 通过addEventListener()添加的事件处理程序,只能通过removeEventListener()来移除。移除时传入相同的参数,并且通过addEventListener()添加的匿名函数无法移除。

支持: IE9、Firefox、Safar、Chrome、Opera

IE事件处理程序

IE中通过attachEvent()detachEvent()来添加和删除事件处理程序。两个方法接收两个参数:事件处理程序名称、事件处理程序函数。IE8及更早版本支持事件冒泡,通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。

var ele = document.getElementById("test");
function show(){
    console.log("hello");
}
ele.attachEvent("onclick", show);
ele.detachEvent("onclick", show);
跨浏览器的事件处理程序
var EventUtli = {
    addHandler : function(element, event, handler){
        if( element.addEventListener ){
            element.addEventListener(event, handler, false);
        }else if( event.attachEvent ){
            element.attachEvent("on"+event, handler);
        }else{
            element["on"+event] = handler;
        }
    },
    removeHandler : function(element, event, handler){
        if( element.addEventListener ){
            element.removeEventListener(event, handler, false);
        }else if( event.attachEvent ){
            element.detachEvent("on"+event, handler);
        }else{
            element["on"+event] = null;
        }
    }
};

事件对象

事件触发时,会产生一个事件对象,该对象中含有与事件有关的相关信息

DOM中事件对象

事件对象将作为一个参数传入DOM0级和DOM2级事件处理程序中,对于HTML事件处理程序,事件对象是代码中的event变量。

var ele = document.getElementById("test");
// DOM0
ele.onClick = function(event){}
// DOM2
ele.addEventListener("click", function(event){}, false);
// HTML
<input onclick="console.log('event.type')">显示</input>
IE中事件对象

访问IE中事件对象有几种方式,根据定义事件处理程序的方法有所不同。用DOM0级方法定义事件处理程序时,事件对象作为window对象的属性存在。用attachEvent()方法添加事件处理程序时,事件对象作为参数传入事件处理程序。

var ele = document.getElementById("test");
// DOM0
ele.onclick = function(){
    var event = window.event;
    console.log(event.type);
}
// attachEvent()
ele.attachEvent("onclick", function(event){
    console.log(event.type);
});
事件对象的属性和方法

DOM中:

属性/方法类型读写说明
typeString只读被触发的事件类型
bubblesBoolean只读事件是否冒泡
cancelableBoolean只读是否可以取消事件默认行为
targetElement只读事件的实际目标(触发事件的元素)
currentTargetElement只读事件处理程序当前正在处理事件的那个元素(事件绑定的元素)
eventPhaseInteget只读事件处理程序的阶段:1为捕获、2为处于目标、3表示冒泡
preventDefault()Function只读取消事件的默认行为(前提是cancelable为true)
stopImmediatePropagation()Function只读取消事件的进一步捕获或者冒泡
stopPropagation()Function只读取消事件的进一步捕获或者冒泡

IE中:

属性/方法类型读写说明
cancelBubbleBoolean读写默认为false,设置为true就可以取消事件冒泡
returnValueBoolean读写默认为true,设置为false就可以取消事件的默认行为
typeString只读被触发的事件类型
srcElementElement只读事件的目标
跨浏览器的事件对象
var EventUtli = {
    addHandler : function(element, type, handler){},
    removeHandler : function(element, type, handler){},
    getEvent : function(event){
        return event ? event : window.event;
    },
    getTarget : function(event){
        return event.target || event.srcElement;
    },
    preventDefault : function(event){
        if(event.preventDefault){
            event.preventDefault()
        }else{
            event.returnValue = false;
        }
    },
    stopPropagation : function(event){
        if(evevt.stopPropagation){
            event.stopPropagation();
        }else{
            event.cancelBubble = true;
        }
    }
};

性能和内存

事件委托

利用事件冒泡,将多个元素的同类事件绑定到更高一级的元素上,减少事件处理程序的数量。在事件处理程序中,传入事件对象event,通过event的target属性来判断事件当前冒泡到的元素。

e.g.

<!-- HTML代码 -->
<!--为li元素绑定点击事件,在控制台上显示li元素的内容-->
<ul id="all">
    <li id="a">A</li>
    <li id="b">B</li>
    <li id="c">C</li>
</ul>

未使用事件委托:

// js代码
var a = document.getElementById("a");
var b = document.getElementById("b");
var c = document.getElementById("c");

function show(){
    console.log(this.innerText);
}

a.onclick = show;
b.onclick = show;
c.onclick = show;

使用事件委托

var all = document.getElementById("all");

function show(){
    console.log(this.innerText);
}

all.onclick = function(event){
    // event.target指向事件冒泡到的元素
    if(event.target.tagName.toLowerCase() === "li"){
        show.call(event.target);
    }
}
移除事件处理程序

移除页面上带事件处理程序的元素时,事件处理程序可能无法被当成垃圾回收。在移除元素前,先移除该元素上的事件处理程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值