js事件浅析

js中关于DOM的操作很多,因此js事件机制也就尤为重要。

事件绑定形式:

一. 内联形式

耦合度高,不利于维护

<button onclick="alert(‘你点击了这个按钮‘);">点击这个按钮</button>

二. 属性绑定(DOM0级事件)

只能绑定一个函数

button.onclick = function() {};

三. 事件监听函数(DOM2级事件)

element.addEventListener(<event-name>, <callback>, <use-capture>);

element.removeEventListener(<event-name>, <callback>, <use-capture>);

element.attachEvent(event, callback)(IE11以后用addEventLisener);

element.detachEvent(event, callback)(IE11以后用addEventLisener);

事件代理

在父元素上绑定事件,监听子元素的事件。主要用于子元素是新建元素或者子元素个数很多的情况下。这种方法可以提高性能,同时避免提前绑定元素事件而导致新建元素的事件没有生效的结果。

<ul> <li>11111111111111111111</li> </ul>

document.addEventListener(‘click‘, function (e) {
            console.log(‘document currentTarget: ‘ + e.currentTarget.nodeName);
            console.log(‘document target: ‘ + e.target.nodeName);
            if (e.target.nodeName === ‘LI‘) {
                console.log(‘dom delegate: ‘ + e.eventPhase);
            }

            console.log(this);
        }, true);

 

事件触发顺序

  • Event Capturing(事件捕获): Netscape
  • Event Bubbling(事件冒泡): IE

这两种方式确定了事件执行的前后顺序,只不过后来W3C对DOM2的事件模型给出了一个规范:首先进入事件捕获阶段->达到元素后->进入事件冒泡阶段。

可以通过event.eventPhase查看事件触发阶段:

eventPhase (number): 这个属性的数字表示当前事件触发在什么阶段。

  • 0: none
  • 1: 捕获
  • 2: 目标
  • 3: 冒泡

1. DOM0

在元素处于目标时触发该事件。

2. DOM2

当addEventListener的最后参数为false时,是在冒泡阶段触发。如果是true的话是在捕获阶段出发。attachEvent始终是冒泡阶段触发。

允许捕获机制的事件流触发顺序:

事件流的触发顺序是首先从document元素开始,触发绑定在document上的捕获事件,依次向下,直到目标元素上。然后触发绑定在目标元素上的事件。最后依次向上,直到触发document元素上绑定的捕获事件。分别可以对于捕获阶段,处于目标阶段,冒泡阶段,捕获过程和冒泡过程并不包含目标元素阶段。

尝试下面的函数:

<ul>
        <li>11111111111111111111</li>
</ul>
<script>
    document.querySelector(‘li‘).addEventListener(‘click‘, function (e) {
            console.log(‘False currentTarget: ‘ + e.currentTarget.nodeName);
            console.log(‘False target: ‘ + e.target.nodeName);
            console.log(e.eventPhase);
            console.log(this);
        }, false);
    document.querySelector(‘li‘).addEventListener(‘click‘, function (e) {
            console.log(‘True currentTarget: ‘ + e.currentTarget.nodeName);
            console.log(‘True target: ‘ + e.target.nodeName);
            console.log(e.eventPhase);
            console.log(this);
        }, true);

    document.querySelector(‘ul‘).addEventListener(‘click‘, function (e) {
            console.log(‘ul false currentTarget: ‘ + e.currentTarget.nodeName);
            console.log(‘ul false target: ‘ + e.target.nodeName);
            console.log(e.eventPhase);
            console.log(this);
        }, false);
    document.querySelector(‘ul‘).addEventListener(‘click‘, function (e) {
            console.log(‘ul true currentTarget: ‘ + e.currentTarget.nodeName);
            console.log(‘ul true target: ‘ + e.target.nodeName);
            console.log(e.eventPhase);
            console.log(this);
        }, true);
    document.querySelector(‘li‘).onclick = function (e) {
            console.log(‘Onclick currentTarget: ‘ + e.currentTarget.nodeName);
            console.log(‘Onclick target: ‘ + e.target.nodeName);
            console.log(e.eventPhase);
            console.log(this);
        };

</script>

BeCareful: 可以看到,当点击li的时候,前两个绑定的事件是按照顺序来执行的,并没有先执行捕获事件然后执行冒泡事件,而是按照绑定顺序执行的。且event.eventPhase的值为2。

原因是:浏览器针对于事件的触发机制是,执行每个阶段会先设置在哪个阶段,然后在node的事件数组里执行相应阶段的事件。如果处于目标阶段是不区分捕获或者冒泡阶段的,直接按照注册顺序执行当前事件数组里的函数。event.eventPhase是在调用这些方法的时候设置的。而true和false是在注册的时候开发者传入的。

注释里面的那段话的意思就是,在目标阶段会触发捕获和冒泡事件的监听函数,因此,它会按照注册顺序执行,跟我们平时理解的顺序并不一样。

自定义事件

DOM3级还定义了自定义事件,自定义事件不是由DOM原生触发的,它的目的是让开发人员创建自己的事件。要创建的自定义事件可以由createEvent("CustomEvent");

返回的对象有一个initCustomEvent()方法接收如下四个参数。

1)type:字符串,触发的事件类型,自定义。例如 “keyDown”,“selectedChange”;

2)bubble(布尔值):标示事件是否应该冒泡;

3)cancelable(布尔值):标示事件是否可以取消;

4)detail(对象):任意值,保存在event对象的detail属性中;

可以像分配其他事件一样在DOM中分派创建的自定义事件对象。如:

var  div = document.getElementById("myDiv");
EventUtil.addEventHandler(div,"myEvent", function () {
alert("div myEvent!");
});
EventUtil.addEventHandler(document,"myEvent",function(){
alert("document myEvent!");
});
if(document.implementation.hasFeature("CustomEvents","3.0")){
var e = document.createEvent("CustomEvent");
e.initCustomEvent("myEvent",true,false,"hello world!");
div.dispatchEvent(e);
}

事件对象及行为

1. 事件目标

event = event || window.event;
target = event.target || event.srcElement;

event.target 和event.currentTarget的区别:前者是触发事件的最终目标,后者是绑定事件时的目标。

借用事件代理的例子:

<div class="btn" onclick="console.log(‘onclick‘)">

        <span>sss</span>

</div>

document.querySelector(‘.btn‘).addEventListener(‘click‘, function (e) {
            console.log(‘False currentTarget: ‘ + e.currentTarget.nodeName);
            console.log(‘False target: ‘ + e.target.nodeName);
            console.log(e.eventPhase);
            console.log(this);
        }, false);

2. 取消默认行为 & 阻止事件冒泡

DOM:
event.preventDefault();
event.stopPropagation();
IE8以下:
event.returnValue = false;
event.cancelBubble = true;

return false方式:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="http://cdn.bootcss.com/jquery/1.11.0/jquery.js"></script>
</head>
<body>

    <div onclick="alert(‘Outer clicked‘)">
        Outer Div<br><br>
        <a id="inner" href="http://www.google.com" onclick="return false;">Google</a>
    <script>
        document.getElementById(‘inner‘).addEventListener(‘click‘, function(e){
            alert(e.type);
            e.stopPropagation();
            return false;
        }, false);
        document.getElementById(‘inner‘).onclick = function(e){
            alert(e.type);
            e.stopPropagation();
            return false;
        };

        $(‘#inner‘).click(function (e) {
            return false;
        });
    </script>
</div>
</body>
</html>

在没有使用jquery的情况下,return false这种方式只有在DOM0的方式时可以相当于阻止默认行为的方法,DOM2级事件是不起任何效果的。

如果在jquery环境,return false相当于阻止默认行为和冒泡行为的方法,因为jquery本身的定义。

 

参考资料:

1. 前端工程师手册

时间: 2024-12-25 23:26:41

js事件浅析的相关文章

js事件冒泡和事件委托

js所谓的事件冒泡就是子级元素的某个事件被触发,它的上级元素的该事件也被递归执行 html: 1 <ul class="clearfix" data-type="cityPick"> 2 <li class="active_sort_opts" data-id="0">全部</li> 3 <li data-id="88">纽约</li> 4 <

特殊js事件

1:点击enter事件 $(document).keypress(function(e) { // 回车键事件 if(e.which == 13) { submitForm(); } }); 2:JQUERY表单ajax提交事件 1):添加js插件 2):添加js事件 function submitForm(){ $.ajax({ url:'${root}/doLogin', data:$('form').serialize(), dataType:'json', cache:false, ty

JS事件(事件冒泡和事件捕获)

事件流:描述的是在页面中接收事件的顺序 事件冒泡:由最具体的元素接收,然后逐级向上传播至最不具体的元素的节点(文档) 事件捕获:最不具体的节点先接收事件,而最具体的节点应该是最后接收事件 DOM中:用于处理指定和删除事件处理程序的操作addEventListener()和removeEventListener().他们都接收三个参数:要处理的事件名.作为事件处理程序的函数和布尔值(事件处理的时候)[true:事件捕获时;false:事件冒泡时] DOM中的事件对象: type属性 用于获取事件类

略谈js事件

 本人是这样从做学的js事件分成以下三个方面: 第一部分:浏览器的按键事件 用js实现键盘记录,要关注浏览器的三种按键事件类型,即keydown,keypress和keyup,它们分别对应onkeydown. onkeypress和onkeyup这三个事件句柄.一个典型的按键会产生所有这三种事件,依次是keydown,keypress,然后是按键释放时候的keyup. 在这3种事件类型中,keydown和keyup比较底层,而keypress比较高级.这里所谓的高级是指,当用户按下shift +

js事件的三个阶段

js事件的三个阶段分别为:捕获.目标.冒泡 1.捕获:事件由页面元素接收,逐级向下,到具体的元素 2.目标:具体的元素本身 3.冒泡:跟捕获相反,具体元素本身,逐级向上,到页面元素 IE5.5:div---body---document IE6.0:   div---body---html---document Mozilla:div---body---html---document---window 事件捕获:当使用事件捕获时,父级元素先触发,子元素后触发 事件冒泡:当使用事件冒泡时,子级元素

JS中的函数、Bom、DOM及JS事件

本期博主给大家带来JS的函数.Bom.DOM操作,以及JS各种常用的数据类型的相关知识,同时,这也是JavaScript极其重要的部分,博主将详细介绍各种属性的用法和方法. 一.JS中的函数 [函数的声明及调用] 1.函数声明的格式: function 函数名(参数1,参数2,参数3,--){//函数体 return 结果; } >>>函数的调用格式: 直接调用:函数调用的格式:函数名(参数一的值,参数二的值,--): 事件调用:事件名=函数名( ); 2.函数声明的几点强调: ①函数名

js事件对象坐标

js事件对象坐标---贴上代码 <body style="position:relative;width:100%;height:100%;padding:15px;margin:20px;"> <div style="position:absolute;top:100px;left:100px;width:500px;height:500px;padding:5px;margin:9px;background:#ddd;" onclick=&qu

JS的Touch事件们,触屏时的js事件

丫的,终于找到了JS在平板电脑上的事件!!! iphone.ipod Touch.ipad触屏时的js事件 1.Touch事件简介 pc上的web页面鼠标会产生onmousedown.onmouseup.onmouseout.onmouseover.onmousemove的事件,但是在移动终端如iphone.ipod Touch.ipad上的web页面触屏时会产生ontouchstart.ontouchmove.ontouchend.ontouchcancel事件,分别对应了触屏开始.拖拽及完成

Js事件大全

一般事件 事件 浏览器支持 描述  onClick IE3|N2|O3 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击  onDblClick IE4|N4|O 鼠标双击事件  onMouseDown IE4|N4|O 鼠标上的按钮被按下了  onMouseUp IE4|N4|O 鼠标按下后,松开时激发的事件  onMouseOver IE3|N2|O3 当鼠标移动到某对象范围的上方时触发的事件  onMouseMove IE4|N4|O 鼠标移动时触发的事件  onMouseOut IE4