• 高级程序设计-事件


    作者:zccst

    一、事件流
    标准:DOM事件流中,实际的目标在捕获阶段不会接收到事件。即捕获从document到body就停止了。
    在处于目标阶段,事件在div上发生,并在事件处理中被看成冒泡阶段的一部分。
    实际:在捕获阶段会涉及,结果有两个机会在目标对象上操作事件。

    二、事件处理程序(事件监听器)
    事件处理程序:HTML,DOM0级,DOM2级

    HTML:<input type="button" value="ClickMe" onclick="alert('Clicked')" />需转义特殊字符

    缺点:1)先调用后解析会报错;2)作用域链有浏览器差异性;3)html和js耦合较严重。
    DOM0级:var btn = document.; btn.onclick=function(){}; 冒泡阶段处理,删除用btn.onclick=null即可;
    DOM2级:addEventListener("click",function(){},true);//true在捕获阶段,false在冒泡阶段
    好处:可以添加多个事件处理程序
    removeEventListener();移除,但无法移除匿名函数,如果想移除需写命名函数

    IE事件处理程序:
    attachEvent("onclick",function(){}). IE8及更早版本,只支持事件冒泡

    与DOM0级事件不同的是DOM0在所属元素的作用域内运行;在attachEvent()方法情况下,在全局作用域中运行,this等于window

    var btn = document.getElementById("myBtn");

    btn.attachEvent("click",function(){ alert ( this == window); });

    也可以添加多个,不同的是执行顺序,与标准正好相反(后添加先执行)
    detachEvent也不能移除匿名函数

    注:支持IE事件处理程序的浏览器有IE何Opera。

    跨浏览器,只需关注冒泡阶段
    1,addHander(ele,type,handler) 视情况分别使用DOM0级、DOM2级防腐或IE防腐来添加事件

    var EventUtil = {
        addHandler:function(elem,type,handler){
            if(elem,addEventListener){
                elem.addEventListener(type, handler, false);
            }else if(elem.attachEvent){
                elem.attachEvent("on"+type, handler);
            }else{
                elem["on"+type] = handler;
            }
        },
        removeHandler:function(elem,type,handler){
          if(elem.removeEventListener){
          elem.removeEventListener(type, handler, false);
        }else if(elem.detachEvent){
          elem.detachEvent("on"+type, handler);
        }else{
          ele["on"+type] = null;
        }
    } }


    这两个方法会先检测是否存在DOM2级,如果是IE浏览器,最后一种可能是DOM0级方法。

    使用:
    var btn = document.
    var handler = function(){};
    EventUtil.addHandler(btn,'click',handler);

    三、事件对象

    <input type="button" value="ClickMe" onclick="alert(event.type)" />

    var btn = document.getElementById("myBtn");

    btn.onclick = function(event){

      alert(event.type);//"click"

    };

    btn.addEventListener("click",function(event){

      alert(event.type);//"click"

    }, false);


    1,标准事件对象
    event共有的成员:bubbles,cancelable(是否可以取消冒泡),currentTarget,defaultPrevented,preventDefault(),stopPropagation,target,type等

    如果直接将事件处理程序指定给了目标元素,则this == currentTarget == target(currentTarget是绑定事件处理程序的对象)

    如果事件处理程序存在于按钮的父节点中,则三者不相同。this和currentTarget指向父元素(target始终指向自身)

    preventDefault() 阻止默认行为。比如a的默认行为是点击时导航到href指定的URL。 var link = document; link.onclick=function(e){e.preventDefault();}
    stopPropagation() 停止冒泡
    eventPhase   1捕获阶段,2处于目标对象,3处于冒泡阶段。event.eventPhase

    2,IE事件对象

    cancelBubble, returnValue, srcElement, type
    DOM0级:window.event
    DOM2级:event

    preventDefault() = returnValue(默认TRUE,设置FALSE可以取消事件的默认行为)
    stopPropagation() = cancelBubble(默认FALSE,设置TRUE可以取消冒泡)
    target = srcElement

    var btn = document.getElementById("myBtn");
    btn.onclick=function(){
      //alert(window.event.srcElement === this);//TRUE,DOM0级srcElement与this相同
    }
    btn.attachEvent("onclick",function(event){
      alert(event.srcElement === this);//FALSE,DOM1级两者不相同
    });

    但DOM标准中是TRUE

    btn.addEventListener("click",function(event){
      alert(event.target === this);//TRUE
      alert(event.currentTarget === this);//TRUE
    })


    3,跨浏览器事件对象
    四个函数:

    var UtilEvent = {
        addHandler:function(elem,type,handler){},
        removeHandler:function(elem,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(event.stopPropagation){
                event.stopPropagation();
            }else{
                event.cancelBubble=true;
            }
        }
    };

    实际使用的时候

    btn.onclick=function(){
      event = UtilEvent.getEvent(event);//先用getTarget
      var target = EventUtil.getTarget(event);

      EventUtil.preventDefault(event);
    }

    四、事件类型
    DOM3规定:
    UI: load,unload,abort,error,select,resize,scroll
    焦点:blur,focus,focusin/focusout(冒泡)
    鼠标/滚轮 除了mouseenter/mouseleave不冒泡,其他都冒泡。顺序:down-up-click-down-up-click-db
    ClinetX/ClientY所有浏览器都支持
    pageX/pageY页面本身的左边和顶边计算的,而非浏览器。没有页面滚动时,两者相同。I8及更早不支持page
    ScreenX/ScreenY屏幕坐标
    相关元素:mouseover和mouseout,配对出现的。
    键盘/文本:keydown,keypress,keyup。字符键down-press-up,非字符键down-up
    合成事件
    变动事件:删除节点,添加节点
    HTML5事件:context,beforeunload
    设备事件:
    触摸与手势事件:touchstart,touchmove,touchend

    五、内存和性能
    1,事件委托
    2,移除事件处理程序 btn.onclick=null, onunload事件移除所有事件处理程序

  • 相关阅读:
    Python学习笔记(三)
    自己出的一套前端笔试题
    Vue 数组封装和组件data定义为函数一些猜测
    前端Mvvm QC 上传了测试版
    为什么我们的web前端变的越来越复杂
    grootJsAPI文档
    grootjs 简明教程
    深入grootJs(进阶教程)
    也议 js闭包和ie内存泄露原理
    此utf8 非彼utf8 ——谈http协议里的编码问题
  • 原文地址:https://www.cnblogs.com/zccst/p/3707862.html
Copyright © 2020-2023  润新知