• 第十三章 事件


    事件概念

    JS与HTML之间的交互通过事件实现。事件就是文档或浏览器窗口中发生的一些的特定交互瞬间。可以使用侦听器(处理程序)来预定事件。以便事件发生时执行相应的代码。

    事件流

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

    I 事件冒泡

    IE的事件流叫做事件冒泡,事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,逐级向上传播到较不具体的节点。

    IE9.FF、chrome、safari冒泡到window对象。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Computed Styles Example</title>
    </head>
    <body
           <div id="myDiv">Click me!</div>
    </body>
    </html>

    单击了DIV,那个这个click事件首先在div元素上发生,其次是body。click事件沿着DOM树向上传播。再每一个级节点上都会发生,直到document对象。

    II事件捕获  

     由不太具体的节点应该更早接收的事件,而最具体的节点应该最后接收到事件。用意再于事件到达预定元素之前捕获它。

    DOM流事件

    DOM2级事件:规定事件流包括三个阶段: 事件捕获阶段,处于目标阶段 和事件冒泡阶段。 

    事件捕获: 为截获事件提供机会。 然后是实际的目标接收到事件。最后一个阶段冒泡阶段,可以在这个阶段对事件做出响应

    事件处理程序

    响应某个事件的函数就叫做事件处理程序(事件侦听器)。

    HTML事件处理程序

    <input type="button" value="click Me!" onclick="alert(event.type)">

    通过event变量,可以直接访问事件对象。不用定义也不用从函数的参数列表中读取。
    在这个函数的内部,this等于事件目标的元素。

    <input type="button" value="click Me!" onclick="alert(this.type)">

    HTML事件处理程序的缺点:

    1、存在时差问题。用户再页面还没有解析事件处理程序的函数之前点击了按钮。会引发错误。

    2、作用域链再不同浏览器中会导致不同结果。JS引擎遵循的标识符解析规则略有差异,很可能再访问非限定对象成员时出错。

    3、需要修改事件时。需要修改HTML和JS俩处。

    DOM0级事件处理程序

     将一个函数赋值给一个事件处理程序属性。优势在于简单。具有跨浏览器的优势。

    每个元素都有自己的事件处理程序属性,将属性的值设为一个函数,就可以指定事件处理程序,程序中this引用当前元素。通过this访问元素的任何属性和方法,以这种方式会在事件的冒泡阶段被处理。

     var btn = document.getElementById("myBtn");
    btn.onclick = function() {
        alert(this.id);       //“myBtn”
    }

    DOM2级事件处理程序

    DOM2级定义了俩个方法用于处理指定和删除事件处理程序的操作:addEventListener()和 removeEventListener(): 接受三个参数 要处理的事件名、作为事件处理程序的函数、布尔值(true: 捕获阶段调用事件处理程序,false: 冒泡阶段调用)。

    2级事件处理程序好处在于可以绑定多个事件处理程序。

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

    removeEventListener,事件处理程序必须与传入addEvenListener()中的相同。

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

    把事件处理程序添加到冒泡阶段,可以最大限度的兼容性浏览器。需要事件到达目标之前截获的时候才添加事件捕获。

     

    IE 事件处理程序

    IE浏览器使用attachEvent()和detachEvent()接受俩个参数: 事件处理程序名称 、事件处理函数。IE的事件处理程序不是以添加他们的顺序执行,以相反的顺序被触发。

     var btn = document.getElementById("myBtn");
    var hander = function() {
           alert(this.id);
    }
    btn.attachEvent("onclick", hander, false);
    
    btn.detachEvent("onclick", hander, false)

    一个跨浏览器的事件处理程序

    var Eventil = {
        addHandler: function(element, type, handler) {
               if(element.addEventListener) {
                  element.addEventlistener(type, handler, false);
               }else if(element.attacthEvent) {
                  element.attacthEvent("on" + type, handler);
               }else{
                  element["on" + type] = handler;
               }
        },
        removeHandler: function(element, type, handler) {
               if(element.removeEvent) {
                     element.removeEvent(type, handler, false);
               }else if(element.detachEvent) {
                   element.detachEvent("on" + type, handler);
               }else {
                   element["on"+ type] = null;
               }
        }
    };
    var btn = document.getElementById("myBtn");
    var handler = function() {
         alert(this.id);
    }
    EventUtil.addEventer(btn, "click',  hander);

    事件对象

    在触发DOM上的某个事件时,会产生一个事件对象event.这个对象中包含着所有事件有关的信息。

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

    再事件处理程序内部,对象this始终等于currentTarget(事件处理程序当前正在处理的那个元素)的值,而target则只包含事件的实际目标。

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

    如果事件处理程序存在于父节点中这些值就不一样了

    document.body.onclick = function(event) {
       console.log(event.currentTarget === document.body); //true
       console.log(this === document.body);                         //this和currentTarget都等于document.body 因为事件是注册再这个元素上的
       console.log(event.target === document.getElementById("myBtn"));
    // 真正的事件目标是mybtn
    }

    preventDefault(): 用于阻止特定事件的默认行为。只有canselable(是否可以取消默认事件)属性设置为true的事件,才可以使用preventDefault()。

    stopPropagation(): 用于立即停止事件再DOM传播。

    var link = document.getElementById("links");
    link.onclick = function(event) {
        event.preventDefault();
        event.stopPropagation();
    };
    document.body.onclick = function(event) {
       console.log("Body Clicked")
    }

    event对象只存在于处理程序执行期间,事件处理程序执行完毕 立即被销毁。

    IE中的事件对象

    DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。

    var btn = document.getElementById("myBtn");
    btn.onclick = function() {
     var event = window.event;
    console.log(event.type);  //click     
    }

    事件处理程序使用attachEvent()添加的,就会有一个event对象、作为参数被传入事件处理函数。

    cancelBUbble:  默认值为false,设置为true可以取消事件冒泡。

    returnValue: 默认值为true,设置为false可以取消事件默认行为。

    srcElement: 事件的目标

    type: 被触发的事件类型

    跨浏览器的事件对象

    var EventUtil = {
        addHandler: function(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(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;
               }
        },
        
        getEvent: function(event) {
            return event ? event : window.event;
        },
        
        getTarget: function(event) {
           return event.target || event.srcElement;
       },
       
       prevenrDefault: function(event) {
         if(event.preventDefault) {
            event.preventDefault();
         }else {
            event.returnValue = false;
         }
      },
    
      stopPropagation: function(event) {
       if(event.stopPropagation) {
          event.stopPropagation();
       }else {
          event.cancelBubble = true;
       }
     }
    
    };

    事件类型

    1、Load事件

    页面完全加载后(包括图像,JS文件,CSS文件等外部资源).就会触发window上面的load事件。

    有俩种定义onload事件处理程序的方法

    第一种使用JS指定事件处理程序

    EventUtil.addHandler(window,"load", function(event) {
              console.log("loaded");
     });

    第二种为<body>元素添加一个onload特性。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Computed Styles Example</title>
    </head>
    <body onload="console.log("loading")">
    </body>
    </html>

     

    2、鼠标与滚轮事件

    客户区坐标位置(页面坐标位置

    clientX和clientY等于pageX和pageY

     屏幕坐标位置

    鼠标事件发生时。不仅会有相对浏览器的窗口位置,还有一个相对于整个电脑屏幕的位置。

    screenX和screenY属性相对整个屏幕的坐标。

    3、鼠标按钮

    对于mousedowm和mouseup ,在event对象中存在一个button属性,表示按下或释放。

    button可能的值: 0:主鼠标按钮, 1:中间鼠标按钮 , 2 次鼠标按钮

    event对象中detail属性

    detail属性对于鼠标事件,包含一个数值,表示再给定位置上发生了多少单击。

    鼠标滚轮事件

    mousewheel:通过鼠标滚轮与页面交互。再垂直方向滚动页面时,就会触发。最终冒泡到document(IE8)对象或window对象。

    wheelDelta属性: 鼠标滚轮向前滚动wheelDelta是120的倍数,向后滚是-120的倍数。多数情况只要指定滚动的方向,即检测wheelDelta的正负号。

     

    内存和性能

    事件委托:利用事件冒泡,只指定一个事件处理程序,管理一个类型的事件。

  • 相关阅读:
    关于自定义验证
    8086汇编 零碎杂项
    8086汇编 程序编译
    8089汇编 源程序
    8086 汇编 jmp 指令
    8089汇编 运算符指令
    8086汇编 栈操作
    8086汇编 段寄存器
    8086汇编 Debug 使用
    8086汇编 CPU 寄存结构
  • 原文地址:https://www.cnblogs.com/zhangbaihua/p/5607922.html
Copyright © 2020-2023  润新知