JavaScript之事件

本文详细解析了DOM事件流的概念及其两种模式——事件冒泡与事件捕获,同时介绍了事件处理程序的工作机制,包括不同浏览器的事件处理方式、事件对象的特性和跨浏览器兼容性。此外,文章还讨论了内存与性能考虑、事件委托和模拟事件的实现,为开发者提供了全面的DOM事件处理指南。

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

  • 事件流(描述的是从页面中接收事件的顺序,其中IE的事件流是事件冒泡 || Netscape的事件流是事件捕获)

    ①事件冒泡:即从事件开始的具体元素,逐级沿DOM树向上传播

    ②事件捕获:即从DOM树向下逐级找到事件开始的具体元素

    ③DOM事件流:事件捕获阶段 -> 处于目标阶段 -> 事件冒泡阶段

  • 事件处理程序(表示响应某个事件的函数,以“on”开头)

    ①镶嵌在HTML页面的事件处理程序 (利用try-catch)

    ②DOM零级事件处理程序
    var btn=...; btn.onclick = function(){} 注意此处的this指向当前元素对象btn

    ③DOM2级事件处理程序

IE9+/其他主流浏览器 -> 
.addEventListener('事件名不加on''处理函数',true/false)
.removeEventListener('事件名不加on''处理函数',true/false)
此处处理函数中的this指向的是当前元素对象 ||true(在捕获阶段执行) || false(在冒泡阶段执行)

IE/opera -> 
.attachEvent('事件名加on','处理函数')
.detachEvent('事件名加on','处理函数')
此处处理函数中的this指向的是window!!!
  • 跨浏览器的事件处理程序兼容
var EventUtil = {
    addHandler:function(obj,type,fn){
        if(obj.addEventListener){
            obj.addEventListener(type,fn,false);
        }else if(obj.attachEvent){
            obj.attachEvent('on'+type,fn);
        }else{
            obj.['on'+type] = fn;
        }
    },
    removeHandler:function(obj,type,fn){
        if(obj.removeEventListener){
            obj.removeEventListener(type,fn,false);
        }else if(obj.detachEvent){
            obj.detachEvent('on'+type,fn);
        }else{
            obj.['on'+type] = null;
        }
    }
}
  • 事件对象
    ①DOM中的事件对象非IE触发DOM上某个事件,会产生一个事件对象ev,这个对象所包含的属性和方法)
    currentTarget(其事件处理程序当前正在处理事件的那个元素)
    target(事件源目标)
    其中两者的区别是: 在事件处理程序内部时,currentTarget/target/this 三者指的是同一个目标;当事件处理程序有父元素包含时,currentTarget,this指的同一个目标而target指的才是真正的目标事件源
    cancelable(表明是否可以取消事件的默认行为)
    .preventDefault() -> 取消默认事件行为
    .stopPropagation() -> 取消进一步捕获或冒泡行为

    IE下事件对象(window.event)
    事件源:srcElement
    取消默认事件行为:ev.returnValue = false
    取消事件冒泡行为:ev.cancelBubble = true

  • 跨浏览器的事件对象操作兼容

var EventUtil = {
    getEventObj:function(ev){
        return ev || window.event;
    },/*获取事件对象*/
    getTarget:function(ev){
        return ev.target || ev.srcElement;
    },/*获取事件源目标*/
    preventDefault:function(ev){
        if(ev.preventDefault()){
            ev.preventDefault();
        }else{
            ev.returnValue = false;
        }
    },/*取消默认事件*/
    stopPropagation:function(ev){
        if(ev.stopPropagation()){
            ev.stopPropagation();
        }else{
            ev.cancelBubble = true;
        }
    }/*取消冒泡事件*/
}
  • 事件类型

    ①UI事件(均在window对象上发生):load || unload || resize || scroll

    ②焦点事件(不冒泡):focusOut || focusIn || blur || DOMFocusOut || focus || DOMFocusIn

    ③鼠标事件:click || dbclick || mousedown || mouseup || mousemove || mouseout || mouseover || mouseenter || mouseleave

    ④有关鼠标位置:
    A. 客户区坐标位置(用户所看到的可视区)clientX,clientY

    B.页面坐标位置(整个文档所处的坐标位置)pageX,pageY(当没有滚动条时,page与client值相等,也可以计算page=client+scroll)

    C.屏幕坐标位置(相对于整个屏幕坐标位置) scrollX,scrollY

    D.部分修改键(shiftKey || ctrlKey || altKey || metaKey)

    ⑤相关元素(主要针对mouseover,mouseout触发 但这部分我自己在做项目中也没搞清楚 有时会造成mouseover,mouseout不停的触发 这里只提提而已)
    这里写图片描述
    –》 对mouseover事件而言,事件主目标是获得光标的元素A而相关元素就是失去光标元素B

    –》对mouseout事件而言,事件主目标是失去光标的元素A而相关元素就是获得光标的元素B

    DOM非IE通过 ev.relatedTarget(保存相关元素)
    IE -> mouseover:ev.fromElement(保存相关元素) || mouseout:ev.toElement(保存相关元素)

    ⑥滚轮事件
    A.FF -》 DOMMouseScroll (其中有个detail信息)
    B.其他浏览器 -》 mousewheel (其中有个wheelData信息)

    ⑦键盘事件
    A. keydown
    B.keyup
    c.keypress

  • 内存与性能考虑

1.每个函数都是对象,都会占用内存,内存中的对象越多性能就会越差
2.必须事先指定所有事件处理程序不然会导致的DOM访问次数增多,会延迟整个页面的交互就绪时间
3.事件委托(对“事件处理程序过多”问题的解决方案)利用事件冒泡,只需在DOM树中尽量最高德层次添加一个事件处理程序
4.移除事件处理程序(浏览器卸载页面之前移除页面中的所有事件处理程序)

  • 模拟事件
    ①模拟鼠标事件

    ②模拟键盘事件

    ③自定义事件:

ev = document.createEvent("CustomEvent");
ev.initCustomEvent(type,bubbles,ancelable,detail);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值