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

     
     
    发展
    IE3和Netscape Navigator2    :       作为分担服务器负载的一种手段;
    IE4和Naviscape4    :    提供了相似却不相同的API;
    DOM2规范制定    :    开始尝试标准化DOM事件;
    DOM2实现    :    IE9、Firefox、Opera、Safari和Chrome全部实现‘DOM2级事件’核心部分;    
    DOM3级出现    :    API变得更加繁琐。
    13.1    事件流
        13.1.1    事件冒泡    :    最具体的元素->...->document
                
    • 支持情况    :    所有浏览器。

    • 差异       :    

    浏览器 表现
    IE5.5- 最具体的元素->...->body->document
    IE9、Firefox、Chrome、Safari 最具体的元素->...->body->html->document->window   

        13.1.2    事件捕获    :      document->html->body->...->最具体的元素

            [DOM2级规范]

            
    • 支持情况:    IE9、Safari、Chrome、Opera、Firefox

    • 不支持情况    :    所有老版本浏览器

        13.1.3    DOM事件流
      1. 事件捕获阶段    :    为截获事件提供机会

      2. 处于目标阶段    :    实际的目标接收到事件

      3. 事件冒泡阶段    :    冒泡阶段

    支持情况:    IE9、Safari、Chrome、Opera、Firefox
    13.2    事件处理程序
        13.2.1    HTML事件处理程序
            特点
    • 会创建一个封装着元素属性值的函数;

      • this    :    当前dom

      • event    :    事件对象

    • 扩展了作用域;

    //形象说明作用域的扩展情况function(){    with(document){        with(this){            //HTML标签中的代码相当于在这里执行        }    }}//表单的情况function(){    with(document){        with(this.form){            with(this){                //HTML标签中的代码相当于在这里执行            }        }    }}
            使用
     
    • 方式一    :    直接在标签中嵌入JS代码

    不能使用未经转义的HTML语法字符!
    <input type='button' value='Click Me' onclick="alert('Clicked')" />
    • 方式二    :    调用其他地方定义的脚本

    <script>    function showMessage(){        alert('Hello world!');    }</script><input type='button' value='Click Me' onclick="showMessage()" />
            缺点
    • 解析不及时引发错误    :    如果函数被定义在最底部,如果用户在页面解析注册的方法之前就被调用将发生错误;

    <!-- try-catch避免引发错误 --><input type='button' value='Click Me' onclick='try{showMessage();}catch(e){}' />
    • 扩展事件处理程序的作用域链在不同 浏览器中会导致不同结果;

    • HTML代码和JavaScript代码耦合。

        13.2.2    DOM0级事件处理程序    :    将函数赋值给一个事件处理程序属性
            特点
    • DOM0级方法指定的事件处理程序被认为是元素的方法,因此程序中的this引用当前元素;

    • 这种事件处理程序在事件流的冒泡阶段处理;

    • 每个元素(包括window和document)都有自己的的事件处理程序。

    var btn = document.getElementById('myBtn');btn.onclick = function(){    alert(this.id);    //'myBtn'};btn.onclick = null;    //删除通过DOM0级方法指定的事件处理程序 
        13.2.3    DOM2级事件处理程序
            两个方法
    • addEventListener()    :    添加事件,3个参数,要处理的事件名、作为事件处理处理程序的函数、布尔值(true表示捕获阶段;false表示冒泡阶段)

      • 依附元素的作用于;

      • 可以添加多个事件处理程序,事件触发后按添加的顺序执行;

      • addEventListener()添加的事件处理程序只能使用removeEventListener()来移除;

      • 移除时传入的参数与添加处理程序使用相同的参数;

      • 添加的匿名函数无法移除。

    • removeEventListener()    :    移出

      addEventListener()添加的事件处理程序,参数和

      addEventListener()

       保持一致     

    var btn = document.getElementById('myBtn');//添加多个事件处理程序btn.addEventListener('click', function(){    alert(this.id);},false);btn.addEventListener('click', function(){    alert('Hello World!');},false);//演示移除事件处理程序var handler = function(){    alert(this.id);};btn.addEventListener('click', handler, false);btn.removeEventListener('click', handler, false);   
            将事件添加到事件的冒泡阶段而不是捕获阶段可以最大程度兼容各种浏览器,除非需要在事件到达目标之前截获事件。
    IE9 Firefox Safari Chrome Opera
        13.2.4    IE事件处理程序
            两个方法
    • attachEvent()    :    添加事件,两个参数,事件处理程序名称、事件处理函数

      • IE8-只支持事件冒泡,因此会被添加到冒泡阶段;

      • 事件名带'on'前缀;

      • 事件处理程序在全局作用域中运行,this等于window;

      • 可以添加多个事件处理程序,事件触发后按与添加的相反的顺序执行;   

      • attachEvent() 添加的事件处理程序只能使用detachEvent()来移除;

      • 移除时传入的参数与添加处理程序使用相同的参数;

      • 添加的匿名函数无法移除。

    • detachEvent()    :    移除通过attachEvent()添加的事件处理函数

    var btn = document.getElementById('myBtn');var handler = function(){    alert(this == window);    //true};btn.attachEvent('onclick', handler);btn.detachEvent('onclick', handler);
    IE Opera
        13.2.5    跨浏览器的事件处理程序
    /*** DOM2>IE>DOM0* param{object} element - dom节点对象* param{string} type - 事件名称* param{boolean} handler - 函数的引用*/var EventUtil = {    //添加事件处理程序    addHandler:    function(element, type, handler){        if(element.addEventListener){    //DOM2            element.addEventListener(type, handler, false);        }else if(element.attachEvent){    //IE8-            element.attachEvent('on'+type, handler);        }else{    //DOM0            element['on'+type] = hanler;        }    },    //移除事件处理程序    addHandler:    function(element, type, handler){        if(element.removeEventListener){    //DOM2            element.addEventListener(type, handler, false);        }else if(element.detachEvent){    //IE8-            element.detachEvent('on'+type, handler);        }else{    //DOM0            element['on'+type] = null;        }    }};
    该方法没有考虑只支持DOM0级浏览器只支持一个事件处理程序的问题,如果多次绑定处理程序,只有最后一个有效。
    13.3    事件对象    :    触发DOM上的某个事件是会产生一个事件对象event(DOM0或DOM2),包含所有与时间有关的信息。
        特点
    • 所有浏览器都支持event对象,但支持方式不同;

    • 只在事件处理程序执行期间存在,执行完毕后被销毁;

    • 不同事件类型可用的属性和方法不同,都包括的成员如下:

            特别成员
    • event.type    :    事件类型

    var btn = document.getElementById('myBtn');var handler = function(event){    switch(event.type){        case "click":            alert('Clicked');            break;        case "mouseover":            event.target.style.backgroundColor = 'red';            break;        case "mouseout":            event.target.style.backgroundColor = '';            break;    }};btn.onclick = handler;btn.onmouseover = handler;btn.onmouseout  = handler;
     
    • event.target    :    事件的实际目标(最具体的那个元素)

    • event.currentTarget    :    和this相同,注册事件的那个元素

    • event.eventPhase     :    事件当前所在的事件流的阶段

      • 1:    捕获阶段调用事件处理程序

      • 2:    事件处理程序处在目标对象上

      • 3:    冒泡阶段调用事件处理程序

    var btn = document.getElementById('myBtn');//捕获阶段document.body.addEventListener('click', function(event){    alert(event.eventPhase);    //1},true);//处于目标阶段btn.onclick = function(event){    alert(event.eventPhase);    //2};//冒泡阶段document.body.addEventListener('click', function(event){    alert(event.eventPhase);    //3},false);
    • event.preventDefault()    :    取消默认行为

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

        13.3.2    IE中的事件对象
            特点
    • 访问IE中的event对象的方式取决于指定事件处理程序的方法

            访问方式
    • window.event(DOM0级方法)

    var btn = document.getElementById('myBtn');btn.onclick = function(){    var event = window.event;    alert(event.type);    //'click'};
    • 作为参数对象(attachEvent())

    var btn = document.getElementById('myBtn');btn.attachEvent('onclick', function(event){    alert(event.type);    //'click'});
    • 直接访问event(HTML中)

    <input tyep='button' value='Click Me' onclick='alert(event.type)' />
            属性/方法
        
        13.3.3    跨浏览器的事件对象
        创建一个兼容的操作事件对象的工具对象    :    因为兼容IE不支持阻止事件捕获
    var EventUtil = {    /**    * 用来添加事件处理程序的方法    * param{object} element - dom    * param{string} type - 事件名称    * param{function} handler - 函数引用    */    addHandler:    function(element, type, handler){        if(element.addEventListener){    //DOM2            element.addEventListener(type, handler, false);        }else if(element.attachEvent){    //IE8-            element.attachEvent('on'+type, handler);        }else{    //DOM0            element['on'+type] = hanler;        }    },     /**    * 用来移除事件处理程序的方法    * param{object} element - dom    * param{string} type - 事件名称    * param{function} handler - 函数引用    */    addHandler:    function(element, type, handler){        if(element.removeEventListener){    //DOM2            element.addEventListener(type, handler, false);        }else if(element.detachEvent){    //IE8-            element.detachEvent('on'+type, handler);        }else{    //DOM0            element['on'+type] = null;        }    },    /**    * 获得事件对象的方法    * param{object} event - 事件处理程序执行时产生的事件对象(如果有的话)    * return{object} 事件对象    */    getEvent:    function(event){        return event ? event : window.event;    },    /**    * 获得触发事件的目标的方法    * param{event} event    - 事件对象    * return{object} dom    - 触发事件的节点        */    getTarget:    function(event){        return event.target || event.srcElement;    },    /**    * 取消默认动作    * param{object} event    -事件对象    */    preventDefault:    function(event){        if(event.preventDefault){            event.preventDefault();        }else{            event.returnValue = false;        }    },    /**    * 阻止事件冒泡(或捕获)    * param{object} event    -事件对象    */    stopPropagation:    function(event){        if(event.stopPropagation){            event.stopPropagation();        }else{            event.cancelBubble =  true;        }    }};
        使用上述快跨览器的工具
    btn.onclick = function(event){    event = EventUtil.getEvent(event);    //    确保在不同浏览器都能获得event    var target = EventUtil.getTarget(event);    //确保获得target    EventUtil.preventDefault(event);    //确保清除默认动作    EventUtil.stopPropagatiom(event);    //阻止传播    };
    13.4    事件类型
    • DOM2级事件

    • DOM3级事件(以DOM2为基础)

    • UI事件

      • 焦点事件

      • 鼠标事件

      • 滚轮事件

      • 文本事件

      • 键盘事件

      • 合成事件

      • 变动事件

      • 变动名称事件

    • HTML5定义的一组事件

    • DOM和BOM中实现的其它专有事件(没有规范)

        13.4.1    UI事件
            历史:    出现在DOM规范之前,被规范保留。
            分类:    现有的UI事件
                      
    事件名称 DOM 触发时机 备注 
    DOMActive    任何元素 元素已经被用户操作激活 被DOM3废弃
    load



    window 页面加载完后 HTML事件


    框架集 所有框架都加载完毕
    <img> 图像加载完毕
    <object> 嵌入的内容加载完毕
    unload


    window 页面完全卸载 HTML事件   



    <img>    无法加载图片
    框架集    所有框架都卸载
    <object>    嵌入的内容卸载完毕
    abort <object>       用户停止下载,嵌入的内容没有加载完 HTML事件   
    error


    window JavaScript错误 HTML事件   



    <img> 无法加载图像
    <object> 无法加载嵌入内容
    框架集 有框架无法加载
    select <input> 用户选择文本框一个或多个字符 HTML事件   

    <textarea> 用户选择文本框一个或多个字符    
    resize window或框架 窗口或框架变化 HTML事件   
    scroll 带滚动条的元素 用户滚动带滚动条的元素中的内容 HTML事件 
     <body>元素中包含加载
    元素的滚动条
            为UI事件定义事件处理程序
    • load事件

            标准load事件实现
             案例一:以body为例
    方式一:    JS(推荐)
      • 使用了跨浏览器的脚本;

      • 传入的event不包含有关这个时间的任何附加信息;

      • 兼容DOM时,event.target会被设置为document;IE不会为其设置srcElement属性;

      • "DOM2级事件"规范应该在document上而不是window上触发load事件,但所有浏览器都在window上面实现了该事件(确保向后兼容)。

    EventUtil.addHandler(window, 'load', function(event){    alert('Loaded!');});
    方式二:    为元素添加onload属性
    <!DOCTYPE html><html><head>    <title>Load Event Example</title></head><body onload='alert('Loaded!')'></body></html>
            案例二:img
    方式一
    var image = document.getElementById('myImage');EventUtil.addHandler(image, 'load', function(event){    event = EventUtil.getEvent(event);    alert(EventUtil.getTarget(event).src);});
    方式二
    <img src='smile.gif' onload='alert('Image loaded.')'>
            案例三:创建新的<img>元素,同时指定一个事件处理程序
      • 要在window上的onload事件触发后才添加DOM中,否则document.body会报错;

      • 一旦设置了src属性,新创建的图像就开始加载图像,和是否添加到文档中无关;

    方式一:    DOM的方式
      • [IE8-]没有添加到DOM中的节点触发load事件时不会生成event对象。

    EventUtil.addHandler(window, 'load', function(event){    var image = document.createElement('img');    EventUtil.addHandler(image, 'load', function(event){        event = EventUtil.getEvent(event);        alert(EventUtil.getTarget(event).src);    });    document.body.appendChild(image);    image.src  = 'smile.gif';});
    方式二:    Image对象
      • 可以像使用<img>元素一样使用Image对象(并非所有浏览器都将Image对象实现为<img>);

      • 无法添加到DOM中;

      • 【IE8- 】Image对象触发load事件不会生成event对象。

    EventUtil.addHandler(window, 'load', function(){    var image = new Image();    EventUtil.addHandler(image, 'load', function(event){        alert('Imaeg loaded!');    });});
           案例四:    script元素
    • 指定src属性并将元素添加到文档后才开始下载。

    EventUtil.addHandler(window, 'load', function(){    var script = document.createElement('script');    EventUtil.addHandler(script, 'load', function(event){        alert('Loaded');    });    script.src = 'exaple.js';    document.body.appendChild(script);});
            兼容性问题
    浏览器版本 script元素onload事件 event.target
    大多数浏览器 支持 <script>节点
    Firefox3- 支持 document
    IE8- 不支持  
            案例五:    link属性
    • 和script类似

            兼容性问题
    IE Opera
     
        2.    unload事件
     
    • 发生时机举例:只要用户从一个页面切换到另外一个页面,就会发生unload事件;

    • 用途举例:清除引用避免内存泄漏;

    • DOM2级事件规定应该在<body>元素而不是window对象上触发unload事件。

    方式一:    JS
    EventUtil.addHandler(window, 'unload', function(event){    alert('Unloaded');});
    方式二:    HTML
    <!DOCTYPE html><html><head>    <title>Unloaded</title></head><body onunload="alert('unloaded!')"></body></html>
        3.    resize事件
    • 浏览器最大化最小化时也会触发resize事件。

    方式一:    JS
    EventUtil.addHandler(window, 'resize', function(event){    alert('Resized');});
    方式二:    HTML
    <!DOCTYPE html><html><head>    <title>Unloaded</title></head><body onresize="alert('resized!')"></body></html>
    event差异
    浏览器 event.target 备注
    兼容DOM的 document  
    IE8- event没有任何属性  
     
    行为差异
    浏览器 触发时间
    IE、Safari、Chrome、Opera 窗口变化1像素时
    Firefox 用户停止调整窗口大小时
        4.    scroll事件
    • 在window对象上触发,表现的是页面上元素的变化。

    模式 浏览器 元素 具体表现
    混杂模式 所有 body scrollLeft和scrollTop
    标准模式 Safari body 跟踪滚动位置
    其它 html 跟踪滚动位置
    //输出页面的垂直滚动位置,根据不同模式使用不同的元素EventUtil.addHandler(window, 'scroll', function(event){    if(document.compatMode == 'CSSCompat'){        alert(document.documentElement.scrollTop);    }else{        alert(document.body.scrollTop);    }});
        13.4.2    焦点事件
    • 触发:  页面获得或失去焦点;

    • 使用: 利用这些事件并与document.hasFocus()方法及document.activeElement属性配合来知晓用户在页面上的行踪;

    • 顺序:以焦点由A元素移动到B元素为例

      1. focusout(A)

      2. focusin(B)

      3. blur(A)

      4. DOMFocusOut(A)

      5. focus(B)

      6. DOMFocusIn(B)

    • 检测支持情况

    var isSupported = document.implementaation.hasFeature('FocusEvent','3.0');
     焦点事件名     冒泡 触发 兼容性 备注
    blur 失去焦点 所有 DOM3级事件(来自IE)
    focus 获得焦点 DOM3级事件(来自IE)     
    DOMFocusIn 是   获得焦点 Opera DOM3级事件中用focusin取代
    DOMFocusOut 失去焦点 DOM3级事件中用focusout取代
    focusin 获得焦点 IE5.5+、Safari5.1+、
    Opera11.5+、Chrome
     
    focusout 失去焦点  
     
        13.4.3    鼠标与滚轮事件
            DOM3级
    鼠标/滚轮事件名称 冒泡 触发 兼容性 备注
    click 单机主鼠标按钮(通常是左键)或键盘回车键    
    dbclick 双击主鼠标按钮 非DOM2  
    mousedown 用户按下任意鼠标按钮时    
    mouseenter 鼠标光标从元素外部首次移动到元素范围之内 IE、Firefox9+、Opera(非DOM2  )

    非子元素
    mouseleave 鼠标光标移动到元素之外  
    mousemove



    鼠标光标在元素内移动时重复触发   非键盘


    mouseout 从一个元素移动到里一个元素(父/子/兄弟)  
    mouseover 从目标元素外部移动到另一个元素边界内  
    mouseup 释放鼠标按钮  
    • 冒泡可以被取消,但会影响其他事件;

    • 事件执行顺序(以双击鼠标主键为例):

     
    标准 IE8(会跳过括号中的时间)
    1. mousedown

    2. mouseup

    3. click

    4. mousedown

    5. mouseup

    6. click

    7. dbclick

    1. mousedown

    2. mouseup

    3. click

    4. (mousedown)

    5. mouseup

    6. (click)

    7. dbclick

    • click和dbclick事件会依赖其它先行时间的触发;mousedown和mouseup不受其它事件影响;

    检测
    • DOM2

    var isSupported = document.implementation.hasFeature('MouseEvents', '2.0');
    • DOM3

    var isSupported = document.implementation.hasFeature('MouseEvent', '2.0'); 
               鼠标事件信息 
            1.    客户区(Client)坐标位置:浏览器视窗作为参照
     
    属性 作用 兼容性 特点
    event.clientX 事件发生时鼠标指针在视口中的水平坐标 所有 不包括滚动的距离
    event.clientY 事件发生时鼠标指针在视口中的垂直坐标
    var div = document.getElementByid('myDiv');EventUtil.addHandler(div, 'click', function(event){    event = EventUtil.getEvent(event);    alert('Client coordinates:' + event.clientX + ',' + event.clientY);});
            2.    页面(Page)坐标位置
     
    属性 作用 兼容性 特点
    event.pageX 事件发生时鼠标指针在页面中的水平坐标 IE8-之外 包括滚动的距离
    event.pageY 事件发生时鼠标指针在页面中的垂直坐标
                方式一:兼容IE8-,兼容混杂模式(document.body)和标准模式(document.documentElement)
    var div = document.getElementByid('myDiv');EventUtil.addHandler(div, 'click', function(event){    event = EventUtil.getEvent(event);    var pageX = event.pageX, pageY = event.pageY;    if(pageX === undefined){        pageX = event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);         pageY = event.clientY + (document.body.scrollTop || document.documentElement.scrollTop);    }    alert('Page coordinates:' + pageX + ',' + pageY);});
                方式二:其它浏览器
    var div = document.getElementByid('myDiv');EventUtil.addHandler(div, 'click', function(event){    event = EventUtil.getEvent(event);    alert('Page coordinates:' + event.pageX + ',' + event.pageY);});
            3.    屏幕(Screen)坐标位置
    属性 作用 兼容性 特点
    event.screenX 事件发生时鼠标指针在屏幕中的水平坐标 IE8-之外 包括滚动的距离
    event.screenY 事件发生时鼠标指针在屏幕中的垂直坐标
    var div = document.getElementByid('myDiv');EventUtil.addHandler(div, 'click', function(event){    event = EventUtil.getEvent(event);    alert('screen coordinates:' + event.screenX + ',' + event.screenY);});
            4.    修改键    :    按下鼠标时键盘上的某些键会影响所要采取的操作
    修改键 DOM规定的对应属性 兼容性
    Shift event.shiftKey 所有(IE8-除外)


    Ctrl event.ctrlKey
    Alt event.altKey
    meta(win或Cmd) event.metaKey
    //如果某个修改键被按下,event中对应的属性值为truevar div = document.getElementById('mDiv');EventUtil.addHandl(div, 'click', function(event){    event = EventUtil.getEvent(event);    var keys = new Array();    if(event.shiftKey){        keys.push('shift');    }    if(event.altKey){        keys.push('alt');    }    if(event.ctrlKey){        keys.push('ctrl');    }    if(event.metaKey){        keys.push('meta');    }    alert('Keys:' + keys.join(',’));} );
            5.    相关元素    :    mouseover和mouseout事件触发时,除住目标外还会涉及其它相关元素。
    • 获取相关元素:

    event的属性 事件 属性值 触发时机 兼容性
    relatedTarget mouseover A元素的dom 鼠标从A元素进入B(目标)元素 IE8-不支持
    mouseout B元素的dom 鼠标从A(目标)元素离开  
    fromElement mouseover A元素的dom 鼠标从A元素进入B(目标)元素 IE(包括IE8-)
    toElement mouseout B元素的dom 鼠标从A(目标)元素离开  
    var EventUtil = {    //省略其它代码        /**    * 跨浏览器获得相关元素的方法    */    getRelatedTarget: function(event){        if(event.relatedTarget){            return event.relatedTarget;        }else if(event.toElement){            return event.toElement;        }else if(event.fromElement){            return null;        }    },    //省略其它代码};
    var div = document.getElementById('myDiv');EventUtil.addHandler(div, 'mouseout', function(){    event = EventUtil.getEvent(event);    var target = EventUtil.getTarget(event);    var relatedTarget = EventUtil.getRelatedTarget(event);    alert('Mouse out of ' + target.tagName + ' to ' + relatedTarget.tagName);});
        6.    鼠标按钮(mousedown 和 mouseup发生时了解哪些鼠标按钮被ianxia)
    event.button DOM IE8-
    0 没有按下按钮
    1
    2
    3 主+次  
    4  
    5 主+中  
    6 次+中  
    7 主+中+次  
    var EventUtil = {    //省略其它代码    /**    * 检测是否兼容DOM并规范化对相应的值规范化    */    getButton: function(event){        if(document.implementation.hasFeature('MouseEvents', '2.0')){            return event.button;        }else{            switch(event.button){                case 0:                case 1:                 case 3:                case 5:                case 7:                    return 0;                case 6:                    return 2;                case 4:                    return 1;                               }        }    },    //省略其它代码};var div = document.getElementById('myDiv');EventUtil.addHandler(div, 'mousedown', function(event){    event = EventUtil.getElement(event);    alert(EventUtil.getButton(event));});
        7.    更多的事件信息
    DOM2级事件 IE
    event属性 类型 备注 event属性 类型 备注
    detail number 给定位置上发生点击的数量 altLeft boolean 是否按了Alt
          ctrlLeft boolean 是否按了Ctrl
          offSetX number 光标相对于目标元素边界的x坐标
          offSetY number 光标相对于目标元素边界的y坐标   
          shiftLeft boolean 是否按下shift键
        8.    鼠标滚轮事件(mousewheel)
    •  IE6首先实现

    event属性 浏览器 冒泡到 表现
    wheelDelta IE8 document 向前滚动120的倍数;向后滚动-120的倍数
    IE9、Opera、Chrome、Safari window
    //解决Opera 9.5之前的版本wheelDelta值正负点到的问题EventUtil.addHandler(document, 'mousewheel', function(event){    event = EventUtil.getEvent(event);    var delta = (client.engine.opera && client.opera < 9.5 ?-event.wheelDelta.opera:event.wheelDelta);    alert(delta);});
    /*** 兼容opera9.5-的获取wheelDelta值得方法*/var EventUtil = {    //省略了其它代码    getWheelDelta: function(event){        if(event.wheelDelta){            return (client.engin.opera && client.engin.opra < 9.5 ? -event.wheelDelta : event.wheelDelta);        }else{            return -event.detal * 40;        }    },};
        9.    触摸设备
    • 不支持dbclick事件。双击浏览器窗口会放大画面,而且没有办法改变;

    • 轻击可单击元素会触发mousemove;

    • mousemove事件也会触发mouseover和mouseout事件;

    • 两个手指放在屏幕上且页面随手指一动而滚动时会触发mousewheel和scroll事件。

        10.    无障碍性问题
    不建议使用click之外的其他鼠标事件展示功能或引发代码执行;
    不建议使用onmousedown,因为屏幕阅读器中无法触发mousedown事件;
    不推荐使用的事件:
    事件名 不推荐的原因
    click之外的鼠标事件 无法通过键盘触发
    onmousedown 屏幕阅读器无法触发该事件
    onmouseover
    dbclick 无法通过键盘触发
     
        13.4.4    键盘与文本事件
        支持修改键,IE不支持metaKey.
    •     键盘事件(3)

    1. 位数  77DOM0    :    对键盘事件的支持主要遵循DOM0级;

    2. DOM2    :    最终定稿时删除了相应的内容;

    3. DOM3    :    为键盘事件制定了规范,IE9率先实现。

    键盘事件 触发 表现 兼容性
    keydown 按下任意键 按住不放会重复触发  
    keypress 按下字符键(包括Esc) Safari3.1-(非字符键也会触发)
    keyup 释放键盘上的键    
    • 文本事件(1)

    文本事件 触发 表现 兼容性
    textInput 文本插入文本框之前 keydown->keypress->textInput->keyup  
        1.    键码
    event属性 对应事件 兼容性
    keyCode keydown 和 keyup ASCLL码中对应小写字母或数字的编码相同(分号按键存在兼容性问题) DOM和IE
    var textbox = document.getElementById('myText');EventUtil.addHandler(textbox, 'keyup', function(event){        event = EventUtil.getEvent(event);        alert(event.keyCode);});
        2.    字符编码
    event属性 对应事件 兼容性
    charCode keypress 按下的键对应的ASCLL IE9、Firefox、Chrome、Safari
    • 不考虑兼容

    var textbox = document.getElementById('myText');EventUtil.addHandler(textbox, 'keypress', function(event){        event = EventUtil.getEvent(event);        alert(event.charCode);});
    • 考虑兼容

    var EventUtil = {    //省略的代码        getCharCode: function(event){        if(typeof event.charCode == 'number'){            reutrn event.charCode;        }else{            reutrn event.keyCode;        }    },        //省略的代码};
        3.    DOM3级变化
     
    • event中删除的成员

    event属性 对应事件 兼容性
    charCode keypress 按下的键对应的ASCLL IE9、Firefox、Chrome、Safar
    • event中添加的成员

    event成员 对应事件 兼容性
    key
    keypress

    文本字符或键的名字(非字符) IE9支持
    char 文本字符或null(非字符) IE9不支持
    keyIdentifier(非DOM3) 'U+000'字符串或键的名字(非字符) Sfari 5 和 Chrome
    location number(代表键盘区域的位置) IE9
    keyLocation 有BUG Safari和Chrome
    getModifierState() boolean,检测某个修改键是否被按下 IE9唯一支持
    //跨浏览器获得键盘字符var textbox = document.getElementById('myText');EventUtil.addHandler(textbox, 'keypress', function(event){    event = EventUtil.getEvent(event);    var identifier = event.key || event.keyIdentifier;    if(identifier){        alert(identifier);    }});
    //检测某个修改键是否被按下var textbox = document.getElementById('myText');EventUtil.addHandler(textbox, 'keypress', function(event){    event = EventUtil.getEvent(event);    if(event.getModifiedState){        alert( event.getModifiedState('Shift'));    }});
     
        4.    textInput事件
    相关属性 有效元素 事件 来源 兼容性
    event.data 可编辑区域 textInput(在可编辑区域输入字符时) 用户输入的字符(非字符编码) DOM3级事件 IE9+、Safari、Chrome
    event.textInput 0-9(表示输入到文本框中的方式) 仅IE
     
    //获得用户输入的字符var textbox = document.getElementById('myText');EventUtil.addHandler(textbox, 'textInput', function(event){    event = EventUtil.getEvent(event);    alert(event.data);});
        5.    设备中的键盘事件
        13.4.5    复合事件(缺少支持,用处不大)
    var isSupported = document.implementation.hasFeature('CompositionEvent');
        13.4.6    变动事件
            为XML或HTML DOM设计。
    • DOM2级变动事件

    变动事件 触发 补充
    DOMSubtreeModified 在DOM结构中发生任何变化时 也就是说其它任何变动事件发生时都会触发
    DOMNodeInstead 一个节点被作为子节点插入到另一个节点  
    DOMNodeRemoved 将节点从父节点移除时  
    DOMNodeInsertedIntoDocument 节点被插入文档或通过子树间接插入文档 在DOMNodeInstead 之后触发  
    DOMNodeRemovedFromDocument 节点从文档移除或通过子树间接移除之前 在DOMNodeRemoved之后触发
    DOMAttrModified 特性被修改之后  
    DOMCharacterDataModified 文本节点的值发生变化  
    • 监测浏览器对变动事件的支持

    var isSupported = document.implementation.hasFeature('MutationEvents', '2.0');
        1.    删除节点
    事件(按触发先后顺序) 相关属性 属性值 dom位置 触发时机 冒泡 备注
    DOMNodeRemoved event.realtedNode 父节点 可以在DOM的任何层次处理   

    使用removeChild()或replaceChild()删除节点

    event.target 被删除的节点  
    DOMNodeRemovedFromDocument     被删除的子节点本身 被移除的所有子节点会相继触发 因为不会冒泡,所有必需给子节点指定事件处理程序才会触发
     
        2.    插入节点
    事件(按触发先后顺序) 相关属性 属性值 dom位置 冒泡 触发时机 备注
    DOMNodeInserted event.relatedNode 对父节点的引用 各个层次 appendChild()、replaceChild()、insertBefore()  
    DOMNodeInsertedIntoDocument event.target 被插入的节点  被插入的节点   必须在插入节点前为其添加事件处理程序
    DOMSubtreeModified     新插入节点的父节点      
        13.4.7    HTML5事件
        1.    contextmenu事件
    触发 用途 冒泡 屏蔽方式 备注
    右键单击(win);ctrl+单击(mac) 如何确定显示上下文菜单或如何自定义上下文菜单 DOM:event.preventDefault(); IE:event.returnValue = false;  
     
    EventUtil.addHandler(window, 'load', function(event){    var div = document.getElementById('myDiv');    EventUtil.addHandler(div, 'contextmenu', function(event){        event = EventUtil.getEvent(event);        EventUtil.preventDefault(event);        var menu = document.getElementById('myMenu');        menu.style.left = event.clientX + 'px';        menu.style.top = event.clientY + 'px';        menu.style.visibility = ''visable;    });    EventUtil.addHandler(document, 'click', function(event){        document.getElementById('myMenu').style.visibility = 'hidden';    });});
        2.    beforeunload事件    :    这个事件会在浏览器卸载页面之前触发    ,可以通过它来取消卸载并继续使用原有页面。
    //为了显示这个弹出的对话框,必需将event.returnValue的值设置为要显示给用户的字符串。EventUtil.addHandler(window, 'beforeunload', function(event){    event = EventUtil.getEvent(event);    var message = '确定卸载页面吗?';    event.returnValue = message;    return message;});
        3.    DOMContentLoaded事件    :    在形成完整的DOM树之后就会触发,不理会图像、JS文件、CSS文件或其它资源是否已经下载完毕。
    • 支持在页面下载的早期添加事件处理程序;

    • 事件会冒泡到window,但目标实际上是document;

    • event.target值为document,此外event没有额外的信息。

    IE9+ Firefox Chrome Safari3.1+ Opera9+
    //会在load事件之前触发EventUtil.addHandler(document, 'DOMContentLoaded', function(event){    alert('Content loaded');});
    • 不支持DOMContentLoaded的浏览器:

    //在当前JS处理完后立即运行,无法保证在所有环境下都早于load事件被触发。setTime(function(){    //在此添加事件处理程序},0);
        4.    readystatechange事件    :    提供与文档加载或元素加载状态有关的信息。
        可以很接近地模拟DOMContentLoaded事件,不能保证和load十一以相同的方式触发。
     
    readyState属性值 含义
    uninitialized 对象存在但未初始化
    loading 对象正在加载数据
    loaded 对象加载数据完毕
    interactive 可以操作对象了,但还没有完全加载
    complete 对象已经加载完毕
     
            特点:
    • 对象不一定经历所有阶段,属性变化也不总是连续的;

    • 因此readystatechange 事件经常会少于4次;

    • 与load事件一起使用时,无法预测两个事件触发的先后顺序。

    EventUtil.addHandler(document, 'readystateChange', function(event){    if(document.readyState == 'interactive'){         alert('Content loaded');    }});  
     
    EventUtil.addHandler(document, 'readystatechange', function(event){    if(document.readyState == 'interactive' || document.readyState == 'complete'){        EventUtil.removeHandler(document, 'readystatechange', arguments.callee);        alert('Content loaded');    }});
    IE Firefox4+ Opera
     
            link和script
            script
    EventUtil.addHandler(window, 'load', function(){    var script = document.createElement('script');    EventUtil.addHandler(script, 'readystatecange', function(event){        event = EventUtil.getEvent(event);        var target = EventUtil.getTarget(event);            if(target.readyState == 'loaded'){            EventUtil.removeHandler(target, 'readystatechange', argument.callee);        }     });    script.src = 'example.js';    docuemnt.body.appendChild(script);});
            link
    EventUtil.addHandler(window, 'load', function(){    var link = document.createElement('link');    link.type = 'text/css';    link.rel = 'stylesheet';    EventUtil.addHandler(script, 'readystatecange', function(event){        event = EventUtil.getEvent(event);        var target = EventUtil.getTarget(event);         if(target.readyState == 'loaded'){            EventUtil.removeHandler(target, 'readystatechange', argument.callee);        }    });    link.href = 'example.css';    docuemnt.getElementsByTagName('head')[0].appendChild(link);});
        5.    pageshow 和 pagehide事件
              往返缓存:Firefox和Opera的一个特性,这个缓存中保存着页面数据、DOM和JS状态,实际上将整个页面保存在内存里了。
              指定了onunload事件处理程序的页面会被自动排除在bfcache之外。
    事件名 触发 目标 绑定事件处理 event.persisted 兼容性
    pageshow 重新加载:load事件触发后 document window false Firefox
    Safari5+
    Chrome
    Opera
      bfcache中的页面:页面状态完全恢复时 true
    pagehide 浏览器卸载页面时 会将该属性设为true
    • 观察pageshow事件

    (function(){    var showCount = 0;    EventUtil.addHandler(window, 'load', function(){        alert('Load fired');    });    EventUtil.addHandler(window, 'pageshow', function(){        showCount++;        alert('Show has been fired ' + showCount + ' times.');    });})();
    • 观察pagehide事件

    EventUtil.addHandler(window, 'pagehide', function(event){    alert('Hiding.Persisted?' + event.persisted);});
        6.    haschange事件
    触发 对象 属性 属性值 来源 兼容性(属性) 兼容性(事件)
    URL参数列表(包括后面的所有字符串)发生变化时 window oldURL 变化前的URL HTML5 Firefox6+、Chrome、Opera IE8+、Firefox3.6+、Safari5+、Chrome、Opera10.6+
    newURL 变化后的URL
    • 捕获事件

    //Firefox6+、Chrome、OperaEventUtil.addHandler(window, 'hashchange', function(event){    alert('Old URL:' + event.oldURL + '
    New URL:' + event.newURL);});//使用location对象确定当前的参数列表(考虑兼容不支持oldURL和newURL的浏览器)EventUtil.addHandler(window, 'hashChange', function(event){    alert('Current hash:' + location.hash);});
    • 检测支持情况(考虑了IE8和IE7在文档模式下运行会发生BUG的问题)

    var isSupported = ('onhashchange' in window) &&(document.documentMode === undefined || document.documentMode > 7);
        13.4.8 设备事件
    W3C从2011年开始着手指定一份关于设备事件的新草案,以涵盖不断增长的设备类型并为它们定义相关的事件。
    1.    orientationchange事件    
    触发 相关属性 支持 来源  
    手机屏幕横纵切换方式变化 window.oritentation Safari 苹果公司  
     
    • window.oritentation 

    window.oritentation 含义 备注
    0 肖像模式  
    90 向左旋转为横向  
    -90 向右旋转为横向  
    180 头向下 无设备支持

        方式一:

    EventUtil.addHandler(window, 'load', function(event){    var div = document.getElementById('myDiv');    div.innerHTML = 'Current orentation is ' + window.orientation;    EventUtil.addHandler(window, 'orientationchange', function(event){        div.innerHTML = 'current orientation is ' + window.orientation;    });});
        方式二:指定<body>元素的onorientationchange特性来指定事件处理程序
        2.    MozOrientation事件
        3.    deviceorientation事件
        
        13.4.9    触摸与手势事件
     
    触摸事件 触发 备注    
    touchstart 手指触摸屏幕时触发      
    touchmove 手指在屏幕上连续地触发      
    touchend 手指从屏幕上移开时      
             
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    如何学习编程语言?
    spring AOP(1)
    一个老工程师给年轻工程师的十大忠告!!!
    跳楼时看到的[转]
    Python distribution打包&安装流程
    php rsa类的一个写法
    yii数据表关联操作
    JIRA是个好工具
    Yii CModel.rules() 方法 validate预定义完整列表
    Python Challenge挑战一下
  • 原文地址:https://www.cnblogs.com/eli01/p/3993396.html
Copyright © 2011-2022 走看看