JavaScript事件详解

先是,小编是一头菜鸡,所写的内容都是构建在温馨的精通基础之上,若有何样窘迫的地点,接待指正。

   事件是javascript跳动的中枢,是DOM全体元素结合的万金油。当大家在WEB
上开始展览一些交互时,事件也就生出了。点击某个内容,鼠标经过一定成分,按下一些开关,改动窗口。当然还或者是浏览器上有个别页面加载完毕。通过
javascript你能够监听特定事件的发生,为事件绑定管理函数。

JavaScript与HTML之间的并行是通过事件来落到实处的。事件,就是文书档案或浏览器窗口中产生的有些一定的互相弹指间。能够用侦听器来预约事件,以便事件发生的时候实践相应的代码。

 

 

 

壹.事件管理函数

DOM事件流

事件流

  事件是指自动触发的或用户手动触发的靶子景况的更换。

   
在DOM中,当某一个特定的HTNL成分产滋事件时,该事件会在该因秋天点与根节点之间按一定的依次传播,所经过的节点都会监听到该事件(但不确定试行该
事件对应的动作,因为未绑定事件管理函数),那么些流传进程便是DOM事件流。事件流有三种事件顺序:事件捕获和事件冒泡。

事件流描述了从页面中收取事件的次第,包含事件冒泡和事件捕获。

  事件管理函数:当事件触发时,电动施行的函数

 

事件冒泡

  事件管理函数的本质上是目标的一个异样性质,而该属性指向了一个函数。

冒泡型事件(event
bubble):冒泡型事件最早由IE落成,事件就如水中的血泡,有对象成分逐级向上冒,直到顶端的根节点

事件最开始时由最实际的成分(文书档案中嵌套等级次序最深的拾叁分节点)接收,然后逐级向上传播到比较不具体的节点(文书档案)。

  各样元素对象都能接触各类风云,而各样事件都对应多个事件管理函数。

 

举例有如下嵌套的HTML页面:

  当未有绑定事件管理函数时,还是能够触发事件,可是由于此时的风浪绑定函数为空,所以不会执行其余操作。

捕获型事件(event
capture):捕获型事件有netscape落成,它与冒泡刚好反而,事件从根节点逐级派送到目的成分。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Event</title>
</head>
<body>
    <div>
        <p>点击</p>
    </div>
</body>
</html>

  在程序实行时,将相应的函数或讲话绑定给目标的某部事件管理函数,那么1旦该对象的钦命事件触发,浏览器变回自动实行该目的的事件管理函数中的操作。

 

假若点击p成分,那么click事件首先在p成分上爆发,这些成分是大家单击的要素。然后,click事件沿着DOM树向上传播,在每一级节点上都会发出,直到传播到document对象。传播顺序如下:

  绑定事件管理函数 = 为on事件名(此函数)赋值**

DOM规范事件模型:W3C这些红娘将二者融入在同步就变成了DOM规范事件模型。先进行捕获,然后再冒泡(所以,若果七个管理函数既被绑定了捕获型事件,又被绑定了冒泡型事件,那么这么些事件处理函数会实行三遍,而且先进行捕获型事件)。

p -> div -> body -> html -> document

  

 

事件捕获

二.大旨事件分类

event-buddledomevent 

事件捕获的沉思是不太现实的节点应该更早接收事件,最切实的节点应该最后收到到事件。事件捕获的意向在于在事变达到预约目的此前捕获它。

  一.鼠标事件

 

由于老版本浏览器不帮忙,因而很少有人利用事件捕获。

    onclick  onbdclick   onmousedown  onmouseup  onmouseover(进入边界时触发三回)  onmouseout  onmusemove

事件监听器和事件管理函数

DOM事件流

  二.键盘事件

   
 事件管理函数(有的地点叫作事件句柄,此称呼轻便和事件监听器混淆,个人不推荐),用于响应有些事件而调用的函数。每2个轩然大波都应该相应二个事件管理函数
(理论上),不然就是做无用功,浪费能源。事件时有产生时,浏览器施行相应的事件管理函数,从而完结页面内容和用户操作的互动。大家认为响应点击事件的管理函
数为onclick。事件管理函数的三种分配办公室法:javascript和html(内联的事件管理函数格局早已经过去,不再切磋)中。假诺在
javascript中分红事件管理函数,首先需求得随地理目的的引用,然后将函数绑定到目的的事件管理函数属性上:

“DOM2级事件”规定的轩然大波流包罗八个品级:事件捕获阶段、处于目的阶段和事件冒泡阶段
document -> html -> body -> div -> p-> div -> body
-> html -> document

    onkeydown  onkeyup  onkeypress

 

IE八及更早版本不帮助DOM事件流

  三.动静事件

1  var link=document.getElementById(“mylink”);

 

    onload  onunload  onchange(select)  onfocus(表单)  onblur(表单)  onresize  onsubmit  onreset  onerror

2  link.onclick=function(){

事件处理程序

  

3   alert(“I was clicked !”);

响应事件的函数叫做事件管理程序或事件侦听器,大家得以经过如下格局为事件内定事件处理程序。

三.关于事件定义

4 }; 

HTML事件管理程序

  为特定的岁月概念监听函数有两种办法:

   
那种分配事件管理函数的一定是轻便,但不能够为一样事件绑定八个事件管理函数。鉴于此缺点,现在超越八分之四浏览器内置了轩然大波监听器来更周到的绑定事件管理函数。
在IE下的事件监听器是attach伊夫nt(),W3C标准型的风云监听器是addeventListener()。

有些成分援救的每个事件都能够采用多个与相应事件管理程序同名的HTML本性来钦命。那几个特点的值应该是力所能致施行的JavaScript代码。

  一.从来在HTML中定义成分的轩然大波的连带属性

 

<input type="button" value="click me" onclick="alert('clicked')">
<标签 on事件名="fun()/js语句">按钮</标签

<标签 class="d1" onclick="fun()">
相当于
d1.onclick=function(){
    console.log(this.className);    //d1
    eval("fun()");//[window.]fun
}
结论:fun()中this指向window

//若要获得当前目标元素对象
html:
    onxxx="fun(this)"
js中定义函数时:
    fun(elem);

A:attachEvent()

那般钦定事件管理程序有所部分优点。首先,那样会创设三个包装着元素属性值的函数。这一个函数中有八个有个别变量event,也正是事件目的。

  

 

<!-- 输出 'click' -->
<input type="button" value="click me" onclick="alert(event.type)">

那种情势违背了“内容和行为互动分开”的口径,应该尽量少用。

 
 在IE下,种种成分和window对象都有七个方法attach伊芙nt和detach伊芙nt方法。

由此event变量,能够一直访问事件目的,不须要团结定义或然从函数的参数列表中读取。

 

 

在那个函数内部,this指向事件的靶子成分,比方:

  2.在JavaScript中为成分的轩然大波相关属性赋值:

element.attach伊夫nt(“onevent”,eventListener);第三个参数是事件类型名,第3个参数是事件管理函
数。在IE下管理函数调用时this指向的不再是先前注册事件的元素,而是window(window.event的使用)。还有少数正是事件前面要
加”on”。
element.attach伊夫nt(“onevent”,eventListener)删除事件监听器,参数一致。

<!-- 输出 click me-->
<input type="button" value="click me" onclick="alert(this.value)">
elem.on事件名=函数对象;

 

关于这一个动态创制的函数,另贰个风趣的地点是它扩张作用域的艺术。在那么些函数内部,能够像访问片段变量同样访问document以及该因素本人的分子。这么些函数使用with想上边那样扩展功效域:

  那种情势贯彻了“内容与行为相分离”,但是元素只好绑定八个监听函数。

B:addEventListener()

function() {
    with(document) {
        with(this) {
            //元素属性
        }
    }
}

 

 

那样1来,我们就可以更简明的走访自身的品质,如下和眼下的例证效果等同。

  3.高级事件管理情势,3个事件可以绑定七个监听函数:

   
在支撑W3C规范事件监听器的浏览器,每一个对象都得以使用add伊芙ntListener方法。该办法及匡助冒泡型事件管理,也支撑捕获型事件管理。
elem.add伊芙ntListener(type,eventListener,capture),暗许情状下capture取false,即为冒
泡型事件管理。add伊芙ntListener方法接受四个参数。第三个是事件类型,没有须要加”on”,第壹个是事件管理函数,第伍个是调整事件管理函
数在冒泡照旧捕获阶段调用。移除事件已经登记的监听器用remove伊芙ntListener。
和挂号的时候参数1致element.remove伊夫ntListener(‘event’, eventListener,
useCapture);

<!-- 输出 click me-->
<input type="button" value="click me" onclick="alert(value)">

    DOM标准:elem.add伊芙ntListener(“事件名”,事件目的,是或不是在捕获阶段触发)

 

万1当前因素是个表单输入成分,则表用域中还会蕴藏访问表单成分(父成分)的入口,那些函数就成为了如下所示:

    IE八标准:elem.attach伊夫nt(“on事件名”,事件指标)

JavaScript事件详解。跨浏览器的事件监听器

function() {
    with(document) {
        with(this.form) {
            with(this) {
                //元素属性
            }
        }
    }
}

<!-- username中的值 -->
<form action="bg.php">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="button" value="Click Me" onclick="alert(username.value)">
</form>
btnObj.attachEvent('onclick',function(){});        //IE
btnObj.addEventListener('click',function(){});    //DOM
...
doucument.body.attachEvent('onload',initData);    //IE
document.body.addEventListener('load',initData);    //DOM
function(){
    ...
}

   
 既然IE和W3C注册时间监听器的方案是例外的,对于支持add伊芙ntListener方法的浏览器,只要供给事件监听器脚本就都亟需调用add伊夫ntListener方法;而对此不支持该措施的IE浏览器,使用事件监听器时则须求调用attach伊芙nt方法。那么大家要协作浏览器也不是哪些困难的事,上面是有血有肉的万分浏览器的挂号事件监听器方案:

使用HTML事件管理程序的瑕疵

  那种情势可认为3个因素绑定多个监听函数,可是要求注意浏览器包容性难题。

 

时差难点:用户恐怕会在HTML成分一出今后页面上就接触相应的轩然大波,不过及时事件管理程序或然不享有施行标准。譬如:

 小例子:逆向实践事件管理函数

复制代码

<input type="button" value="click me" onclick="clickFun();">

html:

 1 var eventUtil={

即便clickFun函数是在页面最尾部定义的,那么在页面解析该函数从前点击都会吸引错误。因而,许多HTML事件处理程序都会被打包到try-catch之中:

澳门葡京 1

 2     //注册

<input type="button" value="click me" onclick="try{clickFun();}catch(ex){}">

css:

 3     addHandler:function(elem,type,handler){

浏览器包容难点:那样扩充事件管理程序的效果域链在差异浏览器中会导致差别的结果。差异JavaScript引擎服从的标记符解析规则略有差别,很只怕会在做客非限定对象成员时出错。

澳门葡京 2

 4         if(elem.addEventListener){

代码耦合:HTML事件管理程序会导致HTML代码和JavaScript代码紧凑耦合。假若要改成事件管理成程序供给同时修改HTML代码和JavaScript代码。

js:

 5             elem.addEventListener(type,handler,false);

 

 澳门葡京 3

 6         }else if(elem.attachEvent){

DOM0级事件管理程序

 结果:

 7             elem.attachEvent(“on”+type,handler);

因此JavaScript内定事件管理程序的理念方法,正是将1个函数赋值给2个事件管理程序属性。那样的优势一是简约,二是浏览器兼容性好。

  原始

 8         }else{

var btn = document.getElementById('btn');
btn.onclick = function() {
    alert('clicked');
}

澳门葡京 4

 9             elem[“on”+type]=handler;

透过DOM0级格局钦点的事件管理程序被认为是因素的艺术。因而,这时候的事件管理程序是在要素的作用域中运转;换句话说,程序中的this引用当前成分:

  点击最内层方块结果:

10         }

var btn = document.getElementById('btn');
btn.onclick = function() {
    alert(this.id); //输出 'btn'
}

 澳门葡京 5澳门葡京 6

11     }

笔者们能够在事件处理程序中经过this访问成分的别样性质和艺术。以那种措施充足的事件管理程序会在事变流的冒泡阶段被管理。

三.轩然大波周期

12     //移除

也能够去除通过DOM0级方法内定的事件管理程序:

DOM

13     removehandler:function(elem,type,handler){

btn.onclick = null;

  解释器成立了3个event对象之后,会依据如下进程将其在HTML成分间张开传播:

14         if(elem.removeListener){

假使大家使用HTML钦点事件管理程序,那么onclick属性的值就是1个带有着在同名HTML个性中内定的代码的函数。

    第三阶段:事件捕获,事件目标沿着DOM树向下传播(IE中的事件模型中从不此阶段)

15             elem.removeListener(type,handler,false)

<input id="btn" type="button" value="click me" onclick="alert(123);">
<script>
    var btn = document.getElementById('btn');
    //输出function onclick(event) {  alert(123);} 
    alert(btn.onclick); 
    //单击按钮没反应
    btn.onclick = null;
</script>

    第一等第:目标触发,运维事件监听函数

16         }else if(elem.detachEvent){

 

    第二品级:事件冒泡,事件沿着DOM树向上传播

17             elem.detachEvent(“on”+type,handler)

DOM二级事件管理程序

澳门葡京 7

18         }else{

澳门葡京 ,“DOM二级事件”定义了多个点子,用于拍卖内定和删除事件管理程序的操作:add伊芙ntListener和remove伊芙ntListener。全数DOM节点中都包罗那多少个章程,并且都接到三个参数:要管理的事件名、作为事件管理程序的函数和三个布尔值。假设那个布尔值参数为true,表示在抓获阶段调用事件管理函数;假使是false,表示在冒泡阶段调用事件管理函数。

  1.事件的冒泡管理机制:

19             elem[“on”+type]=null;

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

    当远在DHTML对象模型尾巴部分对象事件发生时会依次激活上边对象定义的同类事件的处理

20         }

与DOM0级方法一致,加多的事件管理程序也是在其直属的要素的成效域中运转,此外,通过那种措施得以增加多个事件管理程序,增多的事件管理程序会根据加多它们的依次出发。

澳门葡京 8

21     }

var btn = document.getElementById('btn');
btn.addEventListener('click',function() {
    alert(this.id);
},false);
btn.addEventListener('click',function() {
    alert(this.type);
},false);

  结果:

22 }

问题

  澳门葡京 9

复制代码

咱们给1个dom同时绑定多少个点击事件,一个用捕获,贰个用冒泡,那么事件的试行各样是何许的?

 IE

   
当事件发生的时候接触事件处理函数,W3C情形下,event对象将电动在事件处理函数内可用,那几个目的涵盖了该事件的1切音信。但在IE下是因此全局对象window下的event属性来含有这一个音讯的。跨浏览器在获取事件目的和事件目的:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Event</title>
    <style>
        div {
            padding: 30px;
            border: 1px solid #000;
        }
    </style>
</head>
<body>
    <div id="one">
        <div id="two">
            <div id="three">
                <div id="four">Click Me</div>
            </div>
        </div>
    </div>
    <script>
        window.onload = function() {
            one.addEventListener('click',function(){
                alert('one');
            },true);
            two.addEventListener('click',function(){
                alert('two,bubble');
            },false);
            two.addEventListener('click',function(){
                alert('two,capture');
            },true);
            three.addEventListener('click',function(){
                alert('three,capture');
            },true);
            four.addEventListener('click',function(){
                alert('four');
            },true);
        }
    </script>
</body>
</html>

  唯有多个阶段,未有捕获

 

点击two,实施结果:one   two,bubble   two,capture

 4.event对象

复制代码

点击three,推行结果:one   two,capture   three,capture   two,bubble

  任何事件触发之后都会生出2个event对象

 1 var eventUtil={

分析:

  当事件发生时,自动创立,封装了风波消息(keyCode/screenX/screenY…)

 2     handler:function(event){

绑定在被点击元素的事件是依据代码顺序产生,其余因素通过冒泡或许捕获“感知”的风云,依据W3C的规范,头阵生捕获事件,后发生冒泡事件。全数事件的顺序是:其余因素捕获阶段事件
-> 本成分代码顺序事件 -> 别的因素冒泡阶段事件 。

  event对象记录事件发生时的鼠标地点,键盘开关状态和接触对象等新闻,事件目的的常用属性:

 3         event=event||window.event

经过add伊夫ntListener增加的事件管理程序只可以用remove伊夫ntListener来移除;移除时传出的参数与丰裕管理程序时行使的参数一样,这也就表示通过add伊芙ntListener添加的无名函数不可能移除。

  

 4         do somesthing

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

btn.addEventListener('click',function() {
    alert(this.id);
},false);
btn.addEventListener('click',function() {
    alert(this.type);
},false);
//不能移除
btn.removeEventListener('click',function() {
    alert(this.type);
},false)
- secElement(IE) / target(DOM)  :    事件源对象
- eventPhase   :    事件传播的阶段
- clientX/offsetX/pageX/screenX/x    :    事件发生时的X坐标
- clientY/offsetY/pageY/screenY/y    :    事件发生时的Y坐标
- which/keyCode/charCode              :    键盘事件中按下的按键
- button    :    鼠标哪个按键被按下
- cancelBubble    :    是否取消事件冒泡
- returnValue     :    是否阻止事件的默认行为

 5     }

 大大多情景下,都是将事件管理程序增添到事件流的冒泡阶段,那样可以最大限度地包容各类浏览器。最佳只在急需在事变达到目标在此之前截获它的时候将事件处理程序加多到捕获阶段。

  1.目的成分对象(一女不事二夫)

 6     getTarget;function(event){

 IE玖+、Firefox、Safari、Chrome、Opera辅助DOM贰级事件管理程序。

    一.HTML绑定事件措施

 7         return event,target||event.srcElement

 

    

 8 

IE事件管理程序

html:
onclick="fun(event)"  //event必须这样写,不能变

    //实际调用时,event会自动获得当前事件的对象
js:
fun(e){
    //e中获取到的就是当前的事件对象
    }

 9     }

IE完成了近似的三个主意:attach伊夫nt和detach伊芙nt。那三个主意接收多少个参数:事件管理程序名称和事件管理程序函数。由于IE8及更早版本只帮助事件冒泡,所以经过attach伊芙nt增添的事件管理程序都会被增添到冒泡阶段。

    二.js绑定格局

10 }

var btn = document.getElementById('btn');
btn.attachEvent('onclick',function() {
    alert('clicked');
})
//DOM标准:自动创建event对象,默认以第一个参数传入自定义的事件处理函数对象
//IE标准:window全局的event属性,当事件发生时,自动创建event对象,保存在window.event中

var e=window.event||arguments[0];
var src=e.srcElement||e.target;

复制代码

注意第二个参数是onclick而不是click。

 

阻拦事件暗中认可行为和阻挠事件冒泡

动用attach伊芙nt与利用DOM0级方法的显要差距在于事件管理程序的作用域,使用attach伊夫nt时,事件管理程序会在全局效用域中运维,因而this等于window。

5.撤回冒泡和接纳冒泡

   
 阻止事件冒泡,甘休冒泡型事件的更是传递(撤销事件传递不只是甘休IE和DOM规范共有的冒泡型事件,大家还足以告一段落援助DOM规范浏览器的捕捉型事件,用stopPropagation()方法。

var btn = document.getElementById('btn');
btn.attachEvent('onclick',function() {
    alert(this === window);  //true
})

  一.撤消冒泡

 

使用attach伊芙nt也得认为3个要素加多两个事件管理程序,但是这么些事件管理程序并不是以丰裕它们的顺序试行,而是以相反的顺序被执行。

DOM标准:e.stopPropagation()

   
阻止事件的默许行为,经常浏览器在事件管理完后会奉行与该事件波及的暗许操作。比如,假若表单中input
type 属性是
“submit”,点击后在事变传播完浏览器就自行提交表单。又举例,input 成分的
keydown 事件产生并拍卖后,浏览器默许会将用户键入的字符自动追加到 input
成分的值中。

应用attach伊芙nt增多的事件能够透过detach伊夫nt来移除,条件是必须提供平等的参数,所以佚名函数将不能被移除。

IE标准:e.cancelBubble=true;

 

协理IE事件管理程序的浏览器有IE和Opera,IE1一始发将不再帮助attach伊芙nt和detach伊芙nt。

用在当前的事件管理函数的结尾

A:截至事件冒泡的管理办法(把此函数放在目的成分管理函数的终极壹行):

跨浏览器的事件管理程序

if(e.stopPropagation)
{
    e.stopPropagation();
}else{
    e.cancelBubble=true;
}

 

function addEvent(element, type, handler) {
    if (element.addEventListener) {
        //事件类型、需要执行的函数、是否捕捉(false表示冒泡)
        //IE9+支持addEventListener,IE8及以下不支持addEventListener
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
        //IE11之后不再支持attachEvent
        //attachEvent添加的时间函数中this指向window
        //IE6-8只支持事件冒泡不支持事件捕获
        element.attachEvent('on' + type, handler);
    } else {
        element['on' + type] = handler;
    }
}

// 移除事件
function removeEvent(element, type, handler) {
    if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);
    } else if (element.datachEvent) {
        element.detachEvent('on' + type, handler);
    } else {
        element['on' + type] = null;
    }
}

  二.用到冒泡

复制代码

 

  优化:若多少个子成分中定义了扳平的事件管理函数,只须要在联合具名的父成分上定义1次就可以

1 function stopHandle(event){

事件目的

  原理:事件的破获和冒泡不会受到程序的干扰,当触发子成分时,会捕获到该因素,然后在父成分触发事件。

2     event=event||window.event

在触发DOM上的有些事件时,会发生2个轩然大波目的event,那几个目的中蕴涵着具有与事件有关的新闻。

陆.打消事件

3     if(event.stopPropagation){

DOM中的事件目的

if(e.preventDefault){
    e.preventDefault();    //DOM
}else{
    e.returnValue=false;    //IE
}

4         event.stopPropagation();

卓殊DOM的浏览器会将多少个event对象传入到事件管理程序中

  什么时候撤消:eg:表单提交以前,若验证未经过,就收回之后的自发性提交。

5     }else{

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

<input id="btn" type="button" value="click me" onclick="alert(event.type)">

 

6         event.cancelBubble=true;

常用属性和艺术

7     }    

品质方法      类型  读/写  表明

9 }

cancelable     Boolean 只读  注脚是还是不是足以裁撤事件的私下认可行为

复制代码

currentTarget  Element 只读  其事件管理程序当前正值处总管件的不得了成分、

B:阻止事件的默许行为

eventPhase    Integer 
只读  调用事件处理程序的级差:一-捕获阶段,二-处在目的,3-冒泡阶段

 

preventDefault   Function
 只读  撤消事件默许行为,假若cancelable是true则能够行使这几个艺术

复制代码

stopPropagation  
Function 只读  撤除事件的愈发捕获或许冒泡,同时阻止任何事件管理程序被调用(DOM三级事件中新添)

1 function defaultHandle(event){

target      Element 只读  事件的对象

2     event=event||window.event

type       String  只读  被触发的轩然大波的档案的次序

3     if(event.preventDefault){

在事件管理程序内部,this始终等于currentTarget的值,而target则只含有事件的实际上目的

4         event.preventDefault();

要是直接将事件管理程序钦定给了目的成分,则this、currentTarget和target包蕴同样的值。

5     }else{

如若须求通过三个函数管理多少个事件时,能够行使type属性:

6         event.returnValue=false;

var btn = document.getElementById('btn');
var handler = function(event) {
    switch(event.type) {
        case 'click':
            alert('click');
            break;
        case 'mouseover':
            alert('mouseover');
            break;
        case 'mouseout':
            alert('mouseout');
            break;
    }
}
btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;

7     }    

事件目标的eventPhase属性表示事件当前正投身事件流的哪位阶段,须要专注的是就算“处于目的”发生在冒泡阶段,可是eventPhase照旧1支等于二,当eventPhase等于二时,this、target、currentTarget始终是万分的。

9 }

留意:只有在事件管理程序推行时期,event对象才会存在,一旦事件处理程序实践完结,event对象就能够被销毁。

复制代码

 

 事件委托

IE中的事件目的

   
事件委托是身无寸铁在事变冒泡的根基上的,有那般一个事例,假设你有三个多行的报表,在每一种<tr>上绑定点击事件是个特别影响属性的大难题。大
繁多库或许框架的做法是行使事件委托。事件委托将事件绑定在蕴藏目标成分的容器成分上,然后经过决断点击的靶子子成分来触发相应的事件。

与走访DOM中的event对象差别,要访问IE中的event对象有三种分化的办法,取决于钦命事件管理程序的办法。在运用DOM0级方法增加事件管理程序时,event对象作为window对象的多少个天性存在。

 

var btn = document.getElementById('btn');
btn.onclick = function() {
    var event = window.event;
    alert(event.type);
}

复制代码

IE玖+中event对象也会作为参数被传播到事件管理程序中,可是IE玖和IE10中参数event和window.event并不是同一个目标,而IE1第11中学参数event和window.event为同一个对象。

1 var myTable=dcument.getElementById(“tab”);

var btn = document.getElementById('btn');
btn.onclick = function(event) {
    var event1 = window.event;
    alert(event === event1);  //IE11中为true
}

2 myTable.addEventListener(click,function(event){

万一事件管理程序是利用attach伊芙nt增多的,那么就能够有二个event对象传入事件管理函数中,同时大家也能够通过window对象来做客event对象,然则它们是不等于的。

3     event=event||window.event;

常用属性和措施

4     var targetNode=event.target||event.srcElement

品质方法      类型  读/写  表明

5     if(targetNode.nodeName.toLowerCase()==”tr”){

cancelBubble  
Boolean 读/写  暗中同意值为false,将其设置为true能够解除事件冒泡

6         alert(“you have clicked”);

returnValue     Element 读/写 
 默许值为true,将其设置为false能够收回事件的默许行为

7     }

srcElement    Element 只读  事件的靶子(也就是DOM中target属性)

8 })

type        String  只读  被触发的轩然大波的项目

上进行一些交互时,事件也就发出了。点击有个别内容,鼠标经过特定…

因为使用attach伊夫nt增添的事件管理程序中this指向window,所以大家常常选取srcElement来代替this。

跨浏览器的事件目的

var EventUtil = {
    // 阻止事件 (主要是事件冒泡,因为IE不支持事件捕获)
    stopPropagation : function(ev) {
        if (ev.stopPropagation) {
            ev.stopPropagation();
        } else {
            ev.cancelBubble = true;
        }
    },
    // 取消事件的默认行为
    preventDefault : function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },
    // 获取事件目标
    getTarget : function(event) {
        return event.target || event.srcElement;
    },
    // 获取event对象的引用
    getEvent : function(event) {
        return event ? event : window.event;
    }
}

 

事件代理

因为事件有冒泡机制,全部子节点的轩然大波都会顺着父级节点跑回来,所以大家得以经过监听父级节点来兑现监听子节点的功效,那正是事件代理。

运用事件代理第三有多少个优势:

  • 调整和减弱事件绑定,提高品质。以前您须求绑定一群子节点,而现行反革命你只须求绑定多个父节点就可以。减弱了绑定事件监听函数的数码。
  • 动态变化的 DOM 结构,还是可以监听。当贰个 DOM
    动态创立之后,不会含有此外交事务件监听,除非您重新实践事件监听函数,而利用事件监听无须担心那个主题素材。

    addEvent(ul2, ‘click’, handler)
    function addEvent(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;
    }
    

    }
    function handler(ev) {

    var ev = ev || event;
    var target = ev.target || ev.srcElement;
    

      //找到a元素

    if (target.nodeName.toLowerCase() == 'a') {
          //a添加的事件
     }
    

    }

jQuery的写法:

$('#ul1 a').on('click', function(){
    alert('正在监听');
});
//改为
$('#ul2').on('click', 'a', function(){
    alert('正在监听');
});

 

总结:

1. addEventListener()和attachEvent()的区别

  • add伊夫ntListener(type,handler,capture)有七个参数,在那之中type是事件名称,如click,handler是事件管理函数,capture是或不是采纳捕获,是二个布尔值,一般为false,那是暗中同意值,所以第七个参数能够不写。attach伊夫nt(‘on’+type,handler)有七个参数,个中type是事件名称,如click,第1个参数必须是onxxxx,handler是事件管理函数,IE6IE柒 IE八不匡助事件捕获,只支持事件冒泡。
  • add伊芙ntListener绑定的事件是先绑定先实行,attach伊芙nt绑定的事件是先绑定后试行
  • 使用了attach伊芙nt或detach伊夫nt后事件管理函数里面包车型地铁this指向window对象,而不是事件目标成分

2. 缓慢解决attch伊芙nt事件管理函数中 this指向window的法子

壹) 使用事件管理函数.apply(事件目标,arguments)
那种方法的后天不足是绑定的事件不或者收回绑定,原因上边已经说了,佚名函数和无名氏函数之间是互不相等的。

var object=document.getElementById('xc');
function handler(){
    alert(this.innerHTML);
}
object.attachEvent('onclick',function(){
    handler.call(object,arguments);
});

2) 使用事件源替代this关键字
以下代码仅适用于IE6 IE7IE八,那种情势完全忽略this关键字,但写起来稍显麻烦。

function handler(e){
    e = e||window.event;
    var _this = e.srcElement||e.target;
    alert(_this.innerHTML);
}
var object = document.getElementById('xc');
object.attachEvent('onclick',handler);

三)
写1个函数完全代表attach伊芙nt/detach伊芙nt,并且协助具有主流浏览器、消除IE6IE七 IE八事件绑定导致的先绑定后实践难题。
留神,本函数是全局函数,而不是DOM对象的成员方法。 

/*
 * 添加事件处理程序
 * @param object object 要添加事件处理程序的元素
 * @param string type 事件名称,如click
 * @param function handler 事件处理程序,可以直接以匿名函数的形式给定,或者给一个已经定义的函数名。
 * @param boolean remove 是否是移除的事件,本参数是为简化下面的removeEvent函数而写的,对添加事件处理程序不起任何作用
*/
function addEvent(object,type,handler,remove){
    if(typeof object != 'object' || typeof handler != 'function') return;
    try{
        object[remove ? 'removeEventListener' : 'addEventListener'](type,handler,false);
    } catch( e ){
        var i, l, xc = '_' + type;
        object[xc] = object[xc] || [];
        if(remove){
            l = object[xc].length;
            for(i = 0;i < l;i++){
                if(object[xc][i].toString() === handler.toString()){
                    object[xc].splice(i,1);
                }
            }
        } else{
            l = object[xc].length;
            var exists = false;
            for(i = 0;i < l;i++){                                                
                if(object[xc][i].toString() === handler.toString()) {
                    exists = true;
                }
            }
            if(!exists) object[xc].push(handler);
        }
        object['on' + type] = function(){
            l = object[xc].length;
            for(i = 0;i < l;i++){
                object[xc][i].apply(object,arguments);
            }
        }
    }
}
/*
* 移除事件处理程序
*/
function removeEvent(object,type,handler){
    addEvent(object,type,handler,true);
}

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website