javascript----事宜概述

事宜处置惩罚递次

DOM0级事宜处置惩罚递次

经由过程Javascript指定事宜处置惩罚递次的传统体式格局,就是将一个函数赋值给一个事宜处置惩罚递次属性。
每一个元素都有自身的事宜处置惩罚递次属性,这些属性一般悉数小写,比方onclick。将这类属性的值设置为一个函数,就可以指定事宜处置惩罚递次。

var btn = document.getElementById('myBtn');
// 增添事宜处置惩罚递次
btn.onclick = function () {
    alert( this );//为DOM元素btn
};
// 移除事宜处置惩罚递次
btn.onclick = null;

长处:1.简朴2.具有跨浏览器的上风
瑕玷:在代码运转之前不会指定事宜处置惩罚递次,因而这些代码在页面中位于按钮背面,就有能够在一段时刻怎样点击都没回响反映,用户体验变差。

DOM2级事宜处置惩罚递次

定义了两个要领,用于处置惩罚指定和删除事宜处置惩罚递次的操纵:addEventListener()和removeEventListener()。三个参数,1.要处置惩罚的事宜名。2.作为事宜处置惩罚递次的函数3.一个布尔值。末了这个布尔值为true,示意在捕捉阶段挪用事宜处置惩罚递次,false示意在冒泡阶段挪用事宜处置惩罚递次。

// 增添多个事宜处置惩罚递次
var btn = document.getElementById('myBtn');
btn.addEventListener('click',function (){
    alert( this );// 为DOM元素btn
},false );
btn.addEventListener('click',function () {
    alert('Hello World');
},false);

// 移除事宜处置惩罚递次
btn.removeEventListener('click',function () {
    // 匿名函数没法被移除,移除失利
},false);
   // 改写
   var handler = function () {
    alert(this.id);
   };
   btn.addEventListener('click',handler,false);
   // 再次移除事宜处置惩罚递次
   btn.removeEventListener('click',handler,false);// 移除胜利

这两个事宜处置惩罚递次会根据增添他们的递次触发。大多数状况,都是将事宜处置惩罚递次增添到事宜流的冒泡阶段,如许可以最大限制的兼容种种版本的浏览器。

长处: 一个元素可以增添多个事宜处置惩罚递次
瑕玷: IE8及以下浏览器不支撑DOM2级事宜处置惩罚递次。(包括IE8)

IE事宜处置惩罚递次

定义了两个要领,与上相似:attachEvent(),detachEvent()。这两个要领吸收雷同的两个参数:事宜处置惩罚递次称号和事宜处置惩罚递次函数。由于IE8以及更早版本的浏览器只支撑事宜冒泡,所以经由过程detachEvent()增添的事宜处置惩罚递次会被增添到冒泡阶段。

var btn = document.getElementById('myBtn');
btn.attachEvent('onclick', function(){
    alert( this );// window
});
btn.attachEvent('onclick', funciton(){
    alert("HELLO, WORLD");
});

点击按钮,这两个事宜处置惩罚递次的触发递次与上述恰好相反。不是根据增添事宜处置惩罚递次的递次触发,恰好相反。

长处:一个元素可以增添多个事宜处置惩罚递次
瑕玷:只支撑IE。

跨浏览器的事宜处置惩罚递次

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

事宜对象

DOM中的事宜对象

兼容DOM的浏览器会将一个event对象传入到事宜处置惩罚递次中。不管指定事宜处置惩罚递次时运用什么要领(DOM0级或DOM2)级,都邑传入event对象。event对象包括与竖立它的特定事宜有关的属性和要领。触发的事宜范例不一样,可用的属性和要领也不一样。不过,一切事宜都有下表列出的成员

| 属性/要领 | 范例 | 申明
| ————— | ————- | ————
| bubbles
| cancebles
| currentTarget
| defaultPrevented
| detail
| evnetPhase
| preventDefault
| stopImmediatePropagation()
| stopPropagation()
| target
| trusted
| type
| view

1.currentTarget与target

target :事宜的目的对象
currenTarget : 其当前事宜处置惩罚递次正在处置惩罚事宜的谁人元素

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

btn.onclick = function ( e ) {
    console.log( this === e.currentTarget );// true
    console.log( this === e.target );// true
};

document.body.onclick = function ( e ) {
    console.log( this === e.currentTarget );// true
    console.log( this === e.target );// false
};

点击按钮,结果如上。

2.preventDefault()与cancelable

cancelable :只读属性,表明是不是可以作废事宜的默许行动,值为true便可以,反之不可。
preventDefault :阻挠特定事宜的默许行动。比方,链接的默许行动就是在被单击时会导航到其href特征指定的URL。

var link = document.getElementById( 'myLink' );
link.onclick = function ( e ) {
    // 阻挠默许行动
    e.preventDefault();// 只需cancelable设置为true的事宜,才可以运用
}

3.stopPropagation()与eventPhase

stopPropagation() : 作废事宜进一步捕捉或冒泡,假如bubbles为true,则可以运用这个要领
eventPhase : 挪用事宜处置惩罚递次的阶段:1.示意捕捉阶段2.示意’处于目的阶段’3.示意冒泡阶段。

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

document.body.addEventListener( 'click', function ( e ) {
    alert( e.eventPhase );
}, true );// 1

btn.addEventListener( 'click',function ( e ) {
    alert( e.eventPhase );
}, false );// 2

document.body.addEventListener( 'click', function ( e ) {
    alert( e.eventPhase );
}, false );// 3

点击btn按钮弹出1,2,3。

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

document.body.addEventListener( 'click', function ( e ) {
    alert( e.eventPhase );// 1
}, true );

btn.addEventListener( 'click',function ( e ) {
    // 阻挠进一步的事宜冒泡
    e.stopPropagation();
    alert( e.eventPhase );// 2
}, false );

document.body.addEventListener( 'click', function ( e ) {
    alert( e.eventPhase );// 点击按钮时,事宜处置惩罚递次被阻挠,无回响反映
}, false );

点击btn按钮弹出1,2。

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

document.body.addEventListener( 'click', function ( e ) {
    // 阻挠进一步的事宜冒泡
    e.stopPropagation();
    alert( e.eventPhase );// 1
}, true );

btn.addEventListener( 'click',function ( e ) {
    alert( e.eventPhase );// 点击按钮时,事宜处置惩罚递次被阻挠,无回响反映
}, false ); 

document.body.addEventListener( 'click', function ( e ) {
    alert( e.eventPhase );// 点击按钮时,事宜处置惩罚递次被阻挠,无回响反映
}, false );

点击btn按钮弹出1。

IE中的事宜对象

接见IE中的event对象有几种差别的体式格局,取决于指定事宜处置惩罚递次的要领。IE的event对象一样也包括与竖立它的事宜相干的属性和要领。与DOM中的event对象一样,这些属性和要领也会由于事宜范例的差别而差别,但一切事宜对象都邑包括下表所列的属性和要领。

| 属性/要领 | 范例 | 申明
| ————— | ————- | ————
| cancelBubble
| returnValue
| srcElement
| type

1.srcElement

事宜的目的(与DOM中的target属性雷同)

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

btn.onclick = function () {
    alert( window.event.srcElement === this )// true
};
btn.attachEvent('onclick', function (e) {
    alert( e.srcElement === this ) // false, IE事宜处置惩罚递次绑定this的值为window
});

2.returnValue

默许值为true,但将其设置为false就可以作废事宜的默许行动(与DOM中的preventDefault()作用雷同)

var link = document.getElementById( 'myLink' );
link.onclick = function () {
    // 阻挠默许行动
    window.event.returnValue = false;
}

与DOM差别的是,在此没有办法肯定事宜是不是能被作废。

3.cancelBubble

默许值为false,但将其设置为true就可以作废事宜冒泡(与DOM中的stopPropagation()作用雷同)

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

btn.onclick = function () {
    alert( 'Clicked' );
    window.event.cancelBubble = true;
};

document.body.onclick = function () {
    alert( 'Body Clicked' )
};

跨浏览器的事宜对象

要接见IE中event对象有几种差别的体式格局,取决于指定事宜处置惩罚递次的要领。在运用DOM0级要领增添事宜处置惩罚递次时,event对象作为window对象的一个属性存在。运用IE事宜处置惩罚递次,event对象可以经由过程window对象举行接见,同时也会被当作参数通报。

var EventUtil = {
    
    getEvent: function( event ){
        return event ? event : window.event
    }
}

事宜范例

DOM3级事宜模块在DOM2级事宜模块基础上从新定义了这些事宜,也增添了一些新事宜。包括IE9在内的一切主流浏览器都支撑DOM2级事宜。IE9也支撑DOM3级事宜。

HTML5事宜

  • DOMContentLoaded :

    1. 可以为document和window增添响应的事宜处置惩罚递次(只管这个事宜会冒泡到window,但它的目的实际上是document)。

    2. DOMContentLoaded中的event对象不会供应分外的信息(其target属性是document)
      兼容性:IE9+,Fifrefox,Chrome,Safari3.1+,Opera9+。

  • hashchange :

    1. 必需要把hashchange事宜处置惩罚程增添给window对象,然后URL参数列表只需变化就会挪用它。

    2. 此时的event对象应当分外包括两个属性:oldURL和newURL。这两个属性离别保存着参数列表变化前后的完全URL。
      兼容性:IE8+,firefox3.6+,Safari5+,Chrome,Opera10.6+。在这些浏览器中只需Firefox6+,chrome和Opera支撑oldURL和newURL属性。为此,最好是运用location对象来肯定当前的参数列表。

键盘事宜

  • keydown(任意键),keypress(字符键), keyup

发作keypress事宜意味着按下的键会影响到屏幕中文本的显现。在一切浏览器中,按下可以插进去或许删除字符的键都邑触发keypress事宜。

  1. 一切元素都支撑以上三个事宜,但只需在用户经由过程文本框输入文本时才最常用到

  2. 触发递次:在用户按下了一个字符键时,keydown–>keypress–>keyup。在用户按下的是一个非字符键,keydown–>keyup。

  3. event对象

    • shiftKey,ctrlKey,altKey和metaKey属性。

    • 在发作keydown和keyup事宜时,event对象的keyCode属性会包括一个键码。

兼容性:IE不支撑metaKey
Working With the Keyboard

鼠标事宜

  • mousedown,mouseup

  • click,dbclick

    1. 一切元素都支撑鼠标事宜。

    2. 触发递次:mousedown–>mouseup–>click–>mousedown–>mouseup–>click–dbclick。在IE8以及之前版本,有一个小bug,会跳过第二个mousedown和click

    3. event对象:

      • clientX和clientY:示意事宜发作时,鼠标指针在视口中的水温和垂直坐标

      • PageX和PageY:示意鼠标光标在页面中的位置,因而坐标是从页面自身,而非视口的左侧和顶边盘算的。

      • screenX和screenY:可以肯定鼠标事宜发作时,鼠标指针相对于全部屏幕的坐标信息。

      • shiftKey,ctrlKey,altKey和metaKey属性。

      • mousedown和mouseup事宜,还包括一个button属性:示意按下或开释的按钮DOM的button属性能够有以下3个值,0示意主鼠标按钮,1示意中心的鼠标按钮,2示意次鼠标按钮。

兼容性:

  • IE8以及更早版本不支撑事宜对象上的页面坐标,不过运用客户区坐标和转动信息可以盘算出来。

  • IE8以及更早版本不支撑metaKey属性。

  • touchstart

内存和机能

事宜处置惩罚递次对机能的影响

在javascript中,增添到页面上的事宜处置惩罚递次数目将直接关联到页面的团体运转机能。

1.每一个函数(事宜处置惩罚递次)都是对象,都邑占用内存。内存中的对象越多,机能就越差。
2.必需事前指定一切 事宜处置惩罚递次而致使的DOM接见次数,会耽误全部页面的交互停当时刻。
3.每当将 事宜处置惩罚递次指定给元素时,运转中的浏览器代码与支撑页面交互的Javascript代码之间就会竖立一个衔接。这类衔接越多,页面执行起来越慢。

<div id="love-wrapper">
    <div id="love-l">L</div>
    <div id="love-o">O</div>
    <div id="love-v">V</div>
    <div id="love-e">E</div>
</div>

var l = document.getElementById( 'love-l' );
var o = document.getElementById( 'love-o' );
var v = document.getElementById( 'love-v' );
var e = document.getElementById( 'love-e' );

l.addEventListener('click', function () {
    alert(' L ')
}, false);
o.addEventListener('click', function () {
    alert( 'O' )
}, false);
v.addEventListener('click', function () {
    alert( 'V' )
}, false);
e.addEventListener('click', function () {
    alert( 'E' )
}, false);

在上面的示例中,为每一个元素的点击事宜都绑定了差别事宜处置惩罚递次。

  • 取得了4个DOM元素。==>DOM接见次数为4次

  • 增添了4个事宜处里递次。==>内存中的对象多增添了4个

  • 响应的事宜处置惩罚递次与指定元素衔接了4次==》衔接数4

假如页面庞杂,那末就会有数不清的代码用于增添事宜处置惩罚递次。影响页面机能。

事宜托付

对事宜处置惩罚递次过量题目的处理计划就是事宜托付。

事宜托付应用了事宜冒泡,只指定一个事宜处置惩罚递次,就可以治理 某一范例(比方:点击事宜)的一切事宜。
假如可行的话,可以斟酌为document对象增添一个事宜处置惩罚递次,用以处置惩罚页面上特定范例的事宜。有点以下

  1. document对象很快就可以接见,而且可以在页面生命周期中的任何时点上为它增添事宜处置惩罚递次(无需守候load和DOMContentLoaded事宜)。换句话说,只需可点击的元素呈如今页面上,就可以马上具有恰当的功用

  2. 在页面中设置事宜处置惩罚递次所需的时刻更少。只增添一个事宜处置惩罚递次所需的DOM援用更少,所花的时刻更少。 全部页面所占得内存空间更少

var love = document.getElementById( 'love-wrapper' );
love.addEventListener('click', function ( e ) {
    switch ( e.target.id ) {
        case 'love-l' : 
            alert('L');
            break;
        case 'love-o' :
            alert('O');
            break;
        case 'love-v' :
            alert('V');
            break;
        case 'love-e' :
            alert('E');
            break;
    }
},false)

在上面的示例中

  • 取得了1个DOM元素。==>DOM接见次数削减到了1次

  • 增添了1个事宜处置惩罚递次。==>内存中的对象只增添了1个

  • 响应的事宜处置惩罚递次与指定元素衔接了4次==>衔接数1

完成了和上一个例子中一样的结果。然则却有用的掌握了DOM接见次数,事宜处置惩罚递次的增添个数,以及DOM元素与响应的事宜处置惩罚递次的衔接次数。

移除事宜处置惩罚递次

应用事宜托付我们可以有用的掌握响应的事宜处置惩罚递次与指定元素的衔接次数。别的,在不需要的时刻移除事宜处置惩罚递次,也是处理这个题目的一种计划。内存中留有那些过期不必的”空事宜处置惩罚递次,也是形成Web应用递次内存和机能题目的主要原因”。

有两种状况能够致使上述题目

  1. 带有事宜处置惩罚递次的 指定元素 经由过程DOM操纵被删除了,页面中的某一部分被替换了,致使带有事宜处置惩罚递次的 指定元素 被删除了。

  2. 卸载页面的时刻。

第一种状况:本质上来说都是一种状况,就是带有事宜处置惩罚递次的 指定元素被删除了,然则其事宜处置惩罚递次依然和 指定元素坚持着援用关联,致使其事宜处置惩罚递次没法被当作渣滓接纳。(尤其是IE)会做出这类处置惩罚

<div id="myDiv">
    <div id="myBtn"></div>
</div>
var handler = function () {
    // 删除指定元素
    document.getElementById( 'myDiv' ).removeChild();
}

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

btn.addEventListener('click', handler, false);

点击按钮时,按钮被删除,然则其事宜处置惩罚递次却还和其坚持了援用关联,致使内存增添。因而在晓得 指定元素能够被删除的状况下,先消除他们之间的援用关联。以下

<div id="myDiv">
    <div id="myBtn"></div>
</div>
var handler = function () {
    // 消除衔接援用关联
    btn.removeEventListener( 'click', handler, false );

    // 删除指定元素
    document.getElementById( 'myDiv' ).removeChild();
}

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

btn.addEventListener('click', handler, false);

如许经由过程消除援用衔接关联,也可以提拔页面机能。

第二种状况:IE8及更早浏览器在这类状况下依然是题目最多的浏览器。假如在页面卸载之前,没有清算清洁事宜处置惩罚递次,那它们就会滞留在事宜处置惩罚递次中。

一般来说,最好的做法是在页面卸载之前,先经由过程unload事宜处置惩罚递次移除一切事宜处置惩罚递次。

    原文作者:Murphywuwu
    原文地址: https://segmentfault.com/a/1190000004430888
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞