zoukankan      html  css  js  c++  java
  • js 事件

    javaScript 与 HTML 之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些 特定的交互瞬间。可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代 码。这种在传统软件工程中被称为观察员模式的模型,支持页面的行为(JavaScript 代码)与页面的外观(HTML 和 CSS 代码)之间的松散耦合。

    1. 事件流

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

    2.事件冒泡

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

    3.事件捕获

      Netscape Communicator 团队提出的另一种事件流叫做事件捕获(event capturing)。事件捕获的思想 是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于在 事件到达预定目标之前捕获它。

    4.DOM事件流

      “DOM2级事件”规定的事件流包括三个阶段: 事件捕获阶段处于目标阶段 事件冒泡阶段。首 先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶 段,可以在这个阶段对事件做出响应。

    5.事件绑定

    (1)

    <button onclick="test()">按钮</button>
    function test(){
        console.log('点击事件');
    }

    (2)

    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
        alert("Clicked");
    };
    btn.onclick = null; //删除事件处理程序

    (3)

    “DOM2 级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener() 和 removeEventListener()。所有 DOM 节点中都包含这两个方法,并且它们都接受 3 个参数:要处 理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是 true,表示在捕获 阶段调用事件处理程序;如果是 false,表示在冒泡阶段调用事件处理程序。 

    var btn = document.getElementById("myBtn");
        var handler = function(){
            alert(this.id);
        };
    btn.addEventListener("click", handler, false);
    btn.removeEventListener("click", handler, false); //移除事件

    IE 实现了与 DOM 中类似的两个方法:attachEvent()和 detachEvent()。这两个方法接受相同 的两个参数:事件处理程序名称与事件处理程序函数。由于 IE8 及更早版本只支持事件冒泡,所以通过 attachEvent()添加的事件处理程序都会被添加到冒泡阶段。

    var btn = document.getElementById("myBtn");
    var handler = function(){
        alert("Clicked");
    };
    btn.attachEvent("onclick", handler);
    //移除事件
    btn.detachEvent("onclick", handler);

    6.跨浏览器的事件处理程序 

    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;
    } }
    };
    var btn = document.getElementById("myBtn");
    var handler = function(){
        alert("Clicked");
    };
    EventUtil.addHandler(btn, "click", handler);
    EventUtil.removeHandler(btn, "click", handler); //移除事件

    7. DOM中的事件对象

      兼容 DOM 的浏览器会将一个 event 对象传入到事件处理程序中。无论指定事件处理程序时使用什么方法(DOM0 级或 DOM2 级),都会传入 event 对象。

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

    事件对象属性:

    在事件处理程序内部,对象 this 始终等于 currentTarget 的值,而 target 则只包含事件的实 际目标。如果直接将事件处理程序指定给了目标元素,则 this、currentTarget 和 target 包含相同 的值。来看下面的例子。

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

    要阻止特定事件的默认行为,可以使用 event.preventDefault() 方法。

    event.stopPropagation() 方法用于立即停止事件在 DOM 层次中的传播,即取消进一步的事件 捕获或冒泡

    事件对象的 eventPhase 属性可以用来确定事件当前正位于事件流的哪个阶段。

      捕获阶段 :  1

      目标阶段:2

      冒泡阶段:  3

    var btn = document.getElementById("myBtn");
    btn.onclick = function(event){
        alert(event.eventPhase); //2
    };
    document.body.addEventListener("click", function(event){
        alert(event.eventPhase); //1
    }, true);
    document.body.onclick = function(event){
        alert(event.eventPhase); //3
    };

    ps: 只有在事件处理程序执行期间,event 对象才会存在;一旦事件处理程序执行完 成,event 对象就会被销毁。

    8. IE中的事件对象

      与访问 DOM 中的 event 对象不同,要访问 IE 中的 event 对象有几种不同的方式,取决于指定事 件处理程序的方法。

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

    在此,我们通过 window.event 取得了 event 对象,并检测了被触发事件的类型(IE 中的 type 属性与 DOM 中的 type 属性是相同的)。可是,如果事件处理程序是使用 attachEvent()添加的,那 么就会有一个 event 对象作为参数被传入事件处理程序函数中,如下所示。

    var btn = document.getElementById("myBtn");
    btn.attachEvent("onclick", function(event){ 
      alert(event.type); //"click" });

    在像这样使用 attachEvent()的情况下,也可以通过 window 对象来访问 event 对象,就像使用 DOM0 级方法时一样。

    事件对象属性:

    因为事件处理程序的作用域是根据指定它的方式来确定的,所以不能认为 this 会始终等于事件目 标。故而,最好还是使用 event.srcElement 比较保险。例如

    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
        alert(window.event.srcElement === this); //ture
    };
    btn.attachEvent("onclick", function(event){
        alert(event.srcElement === this); //true
    });

    returnValue 属性相当于 DOM 中的 preventDefault()方法,它们的作用都是取消 给定事件的默认行为。只要将 returnValue 设置为 false,就可以阻止默认行为。

    相应地,cancelBubble 属性与 DOM 中的 stopPropagation()方法作用相同,都是用来停止事 件冒泡的。由于 IE 不支持事件捕获,因而只能取消事件冒泡;

    stopPropagatioin() 可以同时取消事件捕获和冒泡。

    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
        alert("Clicked");
        window.event.cancelBubble = true; //阻止事件冒泡
    };

    9. 跨浏览器的事件对象

      

        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;
                }
            },
            // 事件对象
            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;
                }
            },
            //移除事件
            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;
                }
            },
            //阻止事件冒泡 捕获
            stopPropagation: function(event) {        
                if(event.stopPropagation) {  
                    event.stopPropagation();   
                } else {  
                    event.cancelBubble = true;        
                }    
            },
            //获取滚动条滚动的值
            getWheelDelta: function(event){
                if (event.wheelDelta){
                     return (client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta);
                } else {
                    return -event.detail * 40;
                }
            },
            //获取键盘码
            getCharCode: function(event){
                if (typeof event.charCode == "number"){
                    return event.charCode;
                } else {
                    return event.keyCode;
                }
            },
        }

    示例:

    btn.onclick = function(event){
        event = EventUtil.getEvent(event);
    };

    10 事件类型

    (1)ui 事件: 

    • DOMActivate: 表示元素已经被用户操作激活

    • load:当页面完全加载后在 window 上面触
    • unload:当页面完全卸载后在 window 上面触发
    • abort:在用户停止下载过程时,如果嵌入的内容没有加载完,则在<object>元素上面触发
    • error:当发生 JavaScript 错误时在 window 上面触发
    • select:当用户选择文本框(<input>或<texterea>)中的一或多个字符时触发
    • resize:当窗口或框架的大小变化时在 window 或框架上面触发
    • scroll:当用户滚动带滚动条的元素中的内容时,在该元素上面触发。

     (2)焦点事件

    • blur: 在元素失去焦点时触发。这个事件不会冒泡;所有浏览器都支持
    • focus: 在元素获得焦点时触发。这个事件不会冒泡;所有浏览器都支持
    • focusin:在元素获得焦点时触发。会冒泡
    • focusout:在元素失去焦点时触发

         其中,blur、和focusout的事件目标是失去焦点的元素;而focus、 focusin 的事件目标是获得焦点的元素。

    (3)鼠标与滚轮事件

    • click:在用户单击主鼠标按钮(左边按钮)或者按下回车键时触发,这一点对确保 易访问性很重要,意味着 onclick 事件处理程序既可以通过键盘也可以通过鼠标执行。
    • dblclick:在用户双击主鼠标按钮(左边按钮)时触发
    • mousedown:在用户按下了任意鼠标按钮时触发。不能通过键盘触发这个事件。
    • mouseenter:在鼠标光标从元素外部首次移动到元素范围之内时触发。这个事件不冒泡,而且 在光标移动到后代元素上不会触发。
    • mouseleave:在位于元素上方的鼠标光标移动到元素范围之外时触发。这个事件不冒泡,而且在光标移动到后代元素上不会触发。
    • mousemove:当鼠标指针在元素内部移动时重复地触发。不能通过键盘触发这个事件。
    • mouseout:当鼠标移出目标元素上方触发,不能通过键盘触发这个事件。
    • mouseover: 鼠标移入目标元素上方,鼠标移到其后代元素上时会触发,不能通过键盘触发这个事件。
    • mouseup: 在用户释放鼠标按钮时触发,不能通过键盘触发这个事件。

      双击事件触发顺序:   

        (1) mousedown (2) mouseup (3) click (4) mousedown (5) mouseup (6) click (7) dblclick

      ie下:

        IE8 及之前版本中的实现有一个小 bug,因此在双击事件中,会跳过第二个 mousedown 和 click事件,其顺序如下:

        (1) mousedown(2) mouseup(3) click 9 (4) mouseup(5) dblclick

        IE9 修复了这个 bug,之后顺序就正确了。

    (4)鼠标滚轮事件

      IE 6.0 首先实现了 mousewheel 事件。此后,Opera、Chrome 和 Safari 也都实现了这个事件。当用 户通过鼠标滚轮与页面交互、在垂直方向上滚动页面时(无论向上还是向下),就会触发 mousewheel 事件。这个事件可以在任何元素上面触发,最终会冒泡到 document(IE8)或 window(IE9、Opera、 Chrome 及 Safari)对象。与 mousewheel 事件对应的 event 对象除包含鼠标事件的所有标准信息外, 还包含一个特殊的 wheelDelta 属性。当用户向前滚动鼠标滚轮时,wheelDelta 是 120 的倍数;当用 户向后滚动鼠标滚轮时,wheelDelta 是120 的倍数

    EventUtil.addHandler(document, "mousewheel", function(event){ 
      event = EventUtil.getEvent(event);
      alert(event.wheelDelta); });

    Firefox 支持一个名为 DOMMouseScroll 的类似事件,也是在鼠标滚轮滚动时触发。与 mousewheel 事件一样,DOMMouseScroll 也被视为鼠标事件,因而包含与鼠标事件有关的所有属性。而有关鼠标滚 轮的信息则保存在 detail 属性中,当向前滚动鼠标滚轮时,这个属性的值是-3 的倍数,当向后滚动 鼠标滚轮时,这个属性的值是 3 的倍数。

    EventUtil.addHandler(window, "DOMMouseScroll", function(event){ 
      event = EventUtil.getEvent(event);   alert(event.detail); });

    (5)触摸设备

      iOS 和 Android 设备的实现非常特别,因为这些设备没有鼠标。在面向 iPhone 和 iPod 中的 Safari 开发时,要记住以下几点。

    • 不支持 dblclick 事件。双击浏览器窗口会放大画面,而且没有办法改变该行为。
    • 轻击可单击元素会触发 mousemove 事件。如果此操作会导致内容变化,将不再有其他事件发生;如果屏幕没有因此变化,那么会依次发生 mousedown、mouseup 和 click 事件。轻击不可单 击的元素不会触发任何事件。可单击的元素是指那些单击可产生默认操作的元素(如链接),或 者那些已经被指定了 onclick 事件处理程序的元素。
    • mousemove 事件也会触发 mouseover 和 mouseout 事件。
    • 两个手指放在屏幕上且页面随手指移动而滚动时会触发 mousewheel 和 scroll 事件。

    (6)键盘与文本事件

    • keydown:当用户按下键盘上的任意键时触发,而且如果按住不放的话,会重复触发此事件。
    • keypress: 当用户按下键盘上的字符键时触发,而且如果按住不放的话,会重复触发此事件。按下 Esc 键也会触发这个事件
    • keyup:当用户释放键盘上的键时触发。
    • textInput:这个事件是对 keypress 的补充,用意是在将文本显示给用户之 前更容易拦截文本。在文本插入文本框之前会触发 textInput 事件。

      在发生 keydown 和 keyup 事件时,event 对象的 keyCode 属性中会包含一个代码,与键盘上一 个特定的键对应。

      

    var textbox = document.getElementById("myText");
    EventUtil.addHandler(textbox, "keyup", function(event){
        event = EventUtil.getEvent(event);
        alert(event.keyCode);
    });

    (7)HTML5 事件

    • contextmenu:右击菜单事件,可使用该事件自定义菜单
    • beforeunload:这个事件会在浏览器卸载页面之前触发,可以通过它来取消卸载并继续使用原有页面
    EventUtil.addHandler(window, "beforeunload", function(event){ 
      event = EventUtil.getEvent(event);   var message = "I'm really going to miss you if you go.";
      event.returnValue = message; return message;
    });

      为了显示弹出对话框,必须将 event.returnValue 的值设置为要显示给用户的字符串,同时作为函数的值返回

    • DOMContentLoaded:window 的 load 事件会在页面中的一切都加载完毕时触发,但这个过程可能会因为要 加载的外部资源过多而颇费周折。而 DOMContentLoaded 事件则在形成完整的 DOM 树之后就会触发, 不理会图像、JavaScript 文件、CSS 文件或其他资源是否已经下载完毕。与 load 事件不同, DOMContentLoaded 支持在页面下载的早期添加事件处理程序,这也就意味着用户能够尽早地与页面 进行交互。
    • hashchange :HTML5 新增了 hashchange 事件,以便在 URL 的参数列表(及 URL 中“#”号后面的所有字符串) 发生变化时通知开发人员。

     (9)触摸事件

    • touchstart:当手指触摸屏幕时触发;即使已经有一个手指放在了屏幕上也会触发。

    • touchmove:当手指在屏幕上滑动时连续地触发。在这个事件发生期间,调用 preventDefault() 可以阻止滚动。
    • touchend:当手指从屏幕上移开时触发。
    • touchcancel:当系统停止跟踪触摸时触发。

      除了常见的 DOM 属性外,触摸事件还包含下列三个用于跟踪触摸的属性。

        touches:表示当前跟踪的触摸操作的 Touch 对象的数组。

        targetTouchs:特定于事件目标的 Touch 对象的数组。

        changeTouches:表示自上次触摸以来发生了什么改变的 Touch 对象的数组。

      

    (10)手势事件

    • gesturestart:当一个手指已经按在屏幕上而另一个手指又触摸屏幕时触发。
    • gesturechange:当触摸屏幕的任何一个手指的位置发生变化时触发。
    • gestureend:当任何一个手指从屏幕上面移开时触发。

    只有两个手指都触摸到事件的接收容器时才会触发这些事件。在一个元素上设置事件处理程序,意 味着两个手指必须同时位于该元素的范围之内,才能触发手势事件(这个元素就是目标)。由于这些事 件冒泡,所以将事件处理程序放在文档上也可以处理所有手势事件。此时,事件的目标就是两个手指都 位于其范围内的那个元素。

     11. 事件委托

      对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡,只指定一个事 件处理程序,就可以管理某一类型的所有事件。例如,click 事件会一直冒泡到 document 层次。也就 是说,我们可以为整个页面指定一个 onclick 事件处理程序,而不必给每个可单击的元素分别添加事 件处理程序。

      

  • 相关阅读:
    我受不了了,可能拿不到毕业证了
    [My B.S paper draft]我的本科答辩论文草稿
    Memory Dog for Autodesk Maya
    Silent Hill 5 Bug
    AMPAS/ASC Common File Format LUT
    CUDAAccelerated LUT Converter for DI Workflow
    Forking AfterBurn into Maya
    nicEdit上传图片无法显示的问题
    用插值的方法进行直方图平滑
    一个新的做presentation的利器
  • 原文地址:https://www.cnblogs.com/bruce-gou/p/9682390.html
Copyright © 2011-2022 走看看