javascript事件流是啥?都有哪些事件流?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript事件流是啥?都有哪些事件流?相关的知识,希望对你有一定的参考价值。

事件流描述的是从页面中接收事件的顺序,IE采用事件冒泡流,标准采用事件捕获流,最后addEventLister给出了第三个参数同时支持冒泡与捕获。

常用的事件主要有:
(1)单击事件:onclick。用户单击鼠标按键时产生的事件,同时。nclick指定的事件处理程序或代码将被调用执行.
(2)改变事件:onchange。当text或textarea元素内的字符值改变或select表格选项状态改变时发生该事件。
(3)选中事件:onselect。当text或textarea对象中的文字被选中时会引发该事件。如:
<ipnut type="text" value="默认信息”onselect=alert(”您选中T文本框中的文字”)>
(4)获得焦点事件:onfocus。用户单击text或textarea以及select对象,即光标落在文本框或选择框时会产生该事件。如:
<select name= "zhengjian" onfocus=alert(”我成为焦点”)>
(5)失去焦点事件:onblur.失去焦点事件正好与获得焦点事件相对,当text或textarea以及select对象不再拥有焦点而退出后台时,引发该事件。
(6)载人文件事件:onload,’当页面文件载人时产生该事件。onload的一个作用就是在首次载人一个页面文件时检测cookie的值,并用一个变量为其赋值,使它可以被源代码使用,本事件是window的事件,但是在html中指定事件处理程序时,一般把它写在<body>标记中。如:
<body onload=alert(”正在加载页面,请等待一”)>
(7)卸载文件事件:onunload。与载人文件事件。nload正好相反,当Web页面退出时引发的事件,并可更新。ookie的状态。如:
<body onunload=confirm(”你确定要离开本页?”)>
(8)鼠标镇盖事件:onmouseover, onmouseover是当鼠标位于元素上方时所引发的事件。如:
<input type= "boutton" value=”按钮”onmouseover= "window. status=‘请您注意下面的状态栏·;return true">
(9)鼠标离开事件:onmouseout, onmouseout是当鼠标离开元素时引发的事件。如果和鼠标覆盖事件同时使用,可以创建动态按钮的效果。
(10)一般事件。
ondbclick:鼠标双击事件。
onkeypress:当键盘上的某个键被按下并且释放时触发的事件,要求页面内必须有激活的对象。
onkeydown:当键盘上某个键被按下时触发的事件,要求页面内必须有激活的对象。
onkeyup:当键盘上某个键被放开时触发的事件,要求页面内必须有激活的对象。
(11)页面相关事件。
onabort:图片在下载时被用户中断时触发的事件。
onbeforeunload:当前页面的内容将要被改变时触发的事件。
参考技术A

javascript对这种问题的处理方式可以称之为事件流即事件的传播机制。对于事件流IE跟FF有不同的解释。IE下的解决方案称之为:

冒泡型事件,而FF下称之为:捕获型事件。顾名思义冒泡型事件是从低而上的触发机制,而捕获型事件则是从上到下的触发机制。《JavaScript高级程序设计》一书提到:

DOM事件流同时支持两种事件触发机制,但是捕获型事件先发生。注意因为事件的目标(也就是DOM树最深的节点)是最精确的元素,实际上它会连续接收两次事件,一次是在捕获过程中,一次是在冒泡过程中。事情到底是不是这样呢?观察下面的程序:

<html onclick=" clickHandle('html'); ">
<head>
<title>JAVASCRIPT事件流</title>
<meta http-equiv="content-type" content="text/html; charset=GBK">
<script type="text/javascript">
function clickHandle(ele)
alert(ele); 

</script>
</head>
<body onclick=" clickHandle('body'); ">
<div style="bgcolor:red" onclick=" clickHandle('div'); ">click me!</div>
</body>
</html>

IE:点击 click me 运行顺序为:DIV-->BODY-->HTML 点击页面其他部分:BODY-->HTML

FF: 点击 click me 运行顺序为:DIV-->HTML-->BODY 点击页面其他部分:HTML-->BODY 

JavaScript为我们提供了三种事件处理函数的分配方式,第一种就像上面的程序一样,是在HTML代码中分配事件处理函数。

第二种方法是在JavaScript中分配事件处理函数,这种方法首先必须得获得要分配事件处理函数的元素的引用,参考以下程序:

1 window.onload = function()


2 var oDiv = document.getElementById("contentDiv"); 


3 oDiv.onclick = function()


4 alert(oDiv.innerHTML); 


5


6

就像上面提到的,该方法在分配事件处理函数时必须保证已经获得对该元素的引用,所以这个程序才把oDiv的onclick事件放在了onload事件的内部,否则会报oDiv未被定义。

还有一个需要注意的地方是使用这种事件处理函数的分配方式时只能为某个特定的事件分配一个函数且事件函数的签名必须小写,否则前面分配的函数会被后面的函数所覆盖。

如果想为同一个事件分配两个以上的处理函数,需要采用第三种事件处理函数分配方式。

在IE中我们使用obj.attachEvent()方法为某个元素分配函数,使用obj.detachEvent()方法为某个元素分离事件处理函数,而在DOM(以FireFox为例)中我们使用addEventListener()方法分配函数,使用removeEventListener()方法分离函数。

参考一下代码:

1 window.onload = function()
2 var oDiv = document.getElementById("contentDiv"); 
3 var func1 = function()
4 alert(oDiv.innerHTML); 
5
6 var func2 = function()
7 alert("also " + oDiv.innerHTML); 
8
9 //IE
10 if(oDiv.attachEvent)
11 oDiv.attachEvent("onclick",func1); 
12 oDiv.attachEvent("onclick",func2); 
13 //oDiv.detachEvent("onclick",func1); 
14 else if(oDiv.addEventListener)
15 //FireFox
16 oDiv.addEventListener("click",func1,true); 
17 oDiv.addEventListener("click",func2,true); 
18 //oDiv.removeEventListener("click",func1,true); 
19
20 
21

我们来说明一下IE下与FireFox下这种事件处理函数的不同点:

1、在函数的第一个参数中,IE下必须有"on"做为前缀,而FF下不用,两种情况下处理函数签名必须小写。

2、FireFox下的addEventListener()函数的第三个参数表示的是:true表示在捕获阶段增加事件处理函数,false表示在冒泡阶段增加事件处理函数,但是由于FireFox不支持冒泡事件流,所以这里我们设成True或者Flase好像没什么区别。

但是要注意的一点就是,如果在 addEventListener()中第三个参数设为true,那么在removeEventListener()方法中的第三个参数一定也要设为相同的值,否则方法失效。

3、在运行时阶段,IE首先执行的是最后边一个被增加的事件处理函数然后才是倒数第二个以此类推,但是在FireFox下与IE相反,他会按照事件处理函数的添加顺序执行。

参考技术B 事件流是描述页面接收事件的顺序。
具体的有事件冒泡事件捕获DOM事件流。
1、事件冒泡又叫IE的事件流,即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。
2、事件捕获的思想是不太具体的节点应该更早的接收到事件,而最具体的节点应该在最后接收到节点。事件捕获的用意在于事件到达预定目标之前捕获它。
3、DOM2级事件流规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件作出响应。

JavaScript事件冒泡和事件捕获

事件流

事件流是指当事件发生时,会在发生事件的元素节点与DOM树根节点之间按特定的顺序进行传播的过程。IE的事件流是事件冒泡流(event bubbling),而Netscape的事件流是事件捕获流(event capturing)

事件冒泡

在这里插入图片描述

事件的冒泡(Bubble) 所谓的事件冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发。事件冒泡会从当前触发的事件目标一级一级往上传递,依次触发,直到document为止。
在这里插入图片描述

    <style>
        #box1{
            width: 200px;
            height: 200px;
            background-color: yellowgreen;
        }
        #s1{
            background-color: yellow;
        }
    </style>
    <div id="box1">
        我是box1
        <span id="s1">我是span</span>
    </div>
    <script>
        window.onload = function(){
            // 为s1绑定一个单击响应函数
            var s1 = document.getElementById('s1')
            s1.onclick = function(event){
                event == event || window.event
                alert('我是span的单击响应函数');
            }
            // 为box1绑定一个单击响应函数
            var box1 = document.getElementById('box1')
            box1.onclick = function(){
                alert('我是div的单击响应函数');
            }
            // 为body绑定一个单击响应函数
            document.body.onclick = function(){
                alert('我是body的单击响应函数');
            }
        }

可以发现当我们点击了span后,在触发span本身的事件后还会继续触发span父元素div的绑定相同的事件,并且一直延续到body绑定的相同事件, 这就是事件冒泡的体现。

在大部分情况下事件冒泡是对开发有利的,如事件委托机制就是利用事件冒泡这一特点,但如何取消事件冒泡呢?

可以通过事件对象取消事件冒泡,通过设置cancelBubble为true即可取消冒泡,或者也可以通过stopPropagation()方法取消事件冒泡。

        window.onload = function(){
            // 为s1绑定一个单击响应函数
            var s1 = document.getElementById('s1')
            s1.onclick = function(event){
                event == event || window.event
                alert('我是span的单击响应函数')
                // 取消冒泡
                // 可以将时间的cancelBubble设置为true 即可取消冒泡
                event.cancelBubble = true
                // event.stopPropagation()
            }

由此可以发现,当设置了 cancelBubble = true 或者调用stopPropagation( ) 方法后,当点击span后,自身事件触发后其父元素div和祖先元素body中的alert事件没有触发,取消了span的事件冒泡。

事件捕获

**事件捕获(event capturing)**相比于事件冒泡,事件会从最外层开始发生,直到最具体的元素。

    <!-- 事件捕获 -->
    <div>
        <button>
            <p>点击捕获</p>
        </button>
    </div>
    <script>
        var p = document.querySelector('p');
        var btn = document.querySelector('button');
        var div = document.querySelector('div');    
        p.addEventListener('click',function(){
            console.log('p标签被点击')
        },true);    
        btn.addEventListener('click',function(){
            console.log("button被点击")
        },true);    
        div.addEventListener('click',function(){
            console.log('div被点击')
        },true);
        document.body.addEventListener('click',function(){
            console.log('body被点击')
        },true);
    </script>

在这里插入图片描述
由控制台可以发现当我们点击p标签后,body绑定的事件是最先被触发的,依次向下传递直到最具体的目标标签p,同理想要取消事件捕获仍然可以调用事件对象的stopPropagation( ) 方法。

以上是关于javascript事件流是啥?都有哪些事件流?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript事件冒泡和事件捕获

javascript中的事件Event

DOM事件

事件流,冒泡,捕获,事件委托

JavaScript事件

JavaScript 事件机制