HTML 学习笔记 JavaScript(事件)

事件流:

事件流: 描述的是从页面中接收事件的顺序 也可以理解为事件在页面中传播的顺序;

事件: 就是用户或浏览器自身执行的某种动作 例如 click(点击) load(加载) mouseover(鼠标悬停)

事件处理程序: 响应某个事件的函数就叫事件处理程序(或事件侦听器)



下面所示例子注册事件的方式均使用DOM2级事件定义的事件处理程序进行注册。DOM2级事件定义可两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener(),所有的DOM节点都包含这两个方法,并且它们都接收三个参数:处理事件的方式 作为事件处理程序的函数 和一个bool值。当这个Bool值为true时,表示在捕获阶段调用事件处理程序,如果为false 表示在冒泡阶段调用事件处理程序。

事件的作用范围讨论

示例1

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            #wrap {
                width: 200px;
                height: 200px;
                background: orange;
            }
            #outer {
                position: relative;
                top: 50px;
                left: 50px;
                width: 100px;
                height: 100px;
                background: #eeddff;
            }
            #liner {
                position: relative;
                top: 25px;
                left: 25px;
                width: 50px;
                height: 50px;
                background: #44ddff;
            }
        </style>
    </head>
    <body>
        <div id="wrap">
            <div id="outer">
                <div id="liner">

                </div>
            </div>
        </div>

        <script>
            var wrap = document.getElementById("wrap");
            wrap.addEventListener("click",function(){
                alert("1314");
            },false);
        </script>

    </body>
</html>

output

问题1:容器元素wrap注册了事件,那么此事件的作用范围是什么?

思考1:根据上面的例子 当点击橘黄色块中(包括被子元素覆盖的部分)任何一部分时,都会弹出1314,点击橘黄色块外面的部分没有任何反应,那么,我们可以得到这样的结论,元素注册事件的作用范围为元素自身在页面中所占空间的大小,但是真的是这样吗?下面我们来做个实验:

我们可以更改上面代码中的CSS代码 改过后为这样:

<style type="text/css">
    #wrap {
        width: 200px;
        height: 200px;
        background: orange;
    }
    #outer {
        position: relative;
        top: 50px;
        left: 50px;
        width: 100px;
        height: 100px;
        background: #eeddff;
    }
    /*liner中的top被修改*/
    #liner {
        position: relative;
        top: 152px;
        left: 25px;
        width: 50px;
        height: 50px;
        background: #44ddff;
    }
</style>

此时HTML页面是这样的:

结论1:当橘黄色块外的浅蓝色部分被点击的时候,同样弹出了1314,而浅蓝色部分是嵌套在wrap元素之内的元素,故可以得出结论:当元素注册了事件,此事件的作用范围:1元素自己所占页面空间的加嵌套元素所占空间的范围(若嵌套元素覆盖在容器元素上,则此事件的作用范围为容器元素自身所占空间的大小)

事件的执行顺序的讨论

问题2 根据上面的示例 那么这里大家可以在思考一个问题,若容器元素wrap以及嵌套元素outer liner 都注册了click事件,根据1得出的结论 那么嵌套在最里层的元素liner所占页面的空间范围内 一共有三个click事件作用在其上,那么当在liner元素的作用范围内点击页面时,3个事件的执行顺序会是什么样的呢?

要解决上面我们提出的问题 这就涉及到了两种处理事件流的不同的机制,事件冒泡 和 事件捕获

事件冒泡

IE 的事件流叫做事件冒泡 即事件开始由最具体的元素(文档中嵌套层次最深的节点)接收,然后逐级向上传播到较为不具体的节点。

示例2:

将参数设置为false 让元素在冒泡阶段调用事件处理程序:

我们将CSS代码还改为最开始的时候 ,并修改js代码如下:

<script>
    var wrap = document.getElementById("wrap");
    var outer = document.getElementById("outer");
    var liner = document.getElementById("liner");
    wrap.addEventListener("click",function(){
        alert("1314");
    },false);
    outer.addEventListener("click",function() {
            alert("1000");
    },false);
    liner.addEventListener("click",function() {
        alert("888");
    },false);

</script    

当我们只点击橘黄色块的时候 只提示1314 点击淡紫色块的时候 会先弹出1000 在弹出1314 当点击淡蓝色的时候 会依次弹出888, 1000 ,1314 可见冒泡事件是由最具体的元素先接受然后一级一级向上传递(向上传播到不具体的元素)

结论2:

在冒泡阶段调用事件处理程序,上面问题的结果是这样的:当点击页面中心浅蓝色的部分时,依次弹出888,1000,1314,因此当容器元素以及嵌套元素都在冒泡阶段调用处理程序时,事件按照冒泡的顺序执行事件处理程序。

事件捕获

Netscape团队提出的另外一种事件流叫做事件捕获,事件捕获的思想是 不太具体的节点应该更早的接收到事件,而最具体的节点应该最后接收到事件。

我们将上面的js代码在做一下修改,代码如下,可以看到只是将addEventListener()的第三个参数改为了true

<script>
    var wrap = document.getElementById("wrap");
    var outer = document.getElementById("outer");
    var liner = document.getElementById("liner");
    wrap.addEventListener("click",function(){
        alert("1314");
    },true);
    outer.addEventListener("click",function() {
            alert("1000");
    },true);
    liner.addEventListener("click",function() {
        alert("888");
    },true);

</script  

这次 我们再点击浅蓝色的块的时候 会看到先弹出的是 1314 然后是 1000 最后才是自己的事件 弹出 888 是和事件冒泡相反的顺序。是事件捕获的思想

结论三:

在捕获阶段调用事件处理程序,上面问题的结果是这样的:当点击页面中心浅蓝色的部分时,先是弹出wrap,接着弹出outer,最后弹出liner。因此当容器元素及其嵌套元素都在捕获阶段调用事件处理程序时:事件按事件捕获的顺序执行事件处理程序。

问题3:根据思考1,思考2得出的结果,接着又有一个问题我认为需要思考,当同一个元素即在冒泡阶段注册了事件,又在捕获阶段注册了同一事件,那么当事件被触发时,事件的执行顺序又会是如何的?

要解决问题三 就涉及到了DOM的事件流

DOM 事件流

DOM2级事件规定的事件流包括三个阶段:事件捕获阶段-->处于目标阶段-->事件冒泡阶段。首先发生的是事件捕获阶段 为截获事件提供了机会,然后是实际目标接收事件,最后一个阶段是冒泡阶段,以下图片来自w3c

示例4:

var wrap = document.getElementById(‘wrap‘);
var outet = document.getElementById(‘outer‘);
var liner = document.getElementById(‘liner‘);

wrap.addEventListener(‘click‘,function(){
  alert(‘789‘);
},false);
outer.addEventListener(‘click‘,function(){
  alert(‘456‘);
},false);
inner.addEventListener(‘click‘,function(){
  alert(‘123‘);
},false);
wrap.addEventListener(‘click‘,function(){
  alert(‘wrap‘);
},true);
outer.addEventListener(‘click‘,function(){
  alert(‘outer‘);
},true);
liner.addEventListener(‘click‘,function(){
  alert(‘inner‘);
},true);

结论4:当点击页面中心浅蓝色部分的时候,先从最不具体的节点捕获事件,先弹出wrap,接着弹出outer。接着处于目标阶段,先弹出888,再弹出liner。紧接着,事件处于冒泡阶段,先弹出1000,再弹出1314。因此我们可以得出结论,当容器元素及嵌套元素,即在捕获阶段又在冒泡阶段调用事件处理程序时:事件按DOM事件流的顺序执行事件处理程序,且当事件处于目标阶段时,事件调用顺序决定于绑定事件的书写顺序,按上面的例子为,先调用冒泡阶段的事件处理程序,再调用捕获阶段的事件处理程序

时间: 2024-11-05 12:11:50

HTML 学习笔记 JavaScript(事件)的相关文章

学习笔记---Javascript事件Event、IE浏览器下的拖拽效果

学习笔记---Javascript事件Event.IE浏览器下的拖拽效果     1. 关于event常用属性有returnValue(是否允许事件处理继续进行, false为停止继续操作).srcElement(触发事件的事件源对象)和attachEvent("onclick",function(){...}); 2. a. 实现拖放(Drag and Drop): 目前支支持IE, 若定制某对象为可拖放对象, 则必须覆盖目标对象的dragenter和dragover事件, 可以用e

Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle&lt;T&gt;

Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle<T> 今天 说一下Caliburn.Micro的IEventAggregator和IHandle<T>分成两篇去讲这一篇写一个简单的例子 看一它的的实现和源码 下一篇用它们做一个多语言的demo 这两个是事件的订阅和广播,很强大,但用的时候要小心发生不必要的冲突. 先看一下它的实现思想 在Caliburn.Micro里EventAggregator要以单例的形式出现这样可以

IOS学习笔记-触摸事件

一.事件传递的过程1.用户手指触摸屏幕,产生一个事件对象 2.系统会将这个事件对象添加到事件队列(先进先出)中 3.由UIApplication取出事件队列中的事件对象进行处理 4.UIApplication会先将事件对象传递给主要的UIWindow(当然,要先检测UIWindow是否能够接收和传递事件) 5.UIWindow会遍历所有的子控件,看看触摸点有没有落在某个子控件上面: 1> 如果触摸点没有落在子控件上,那么就由UIWindow直接处理这个事件,事件传递完毕 2> 如果触摸点落在子

Symfony2学习笔记之事件分配器

----EventDispatcher组件使用 简介:       面向对象编程已经在确保代码的可扩展性方面走过了很长一段路.它是通过创建一些责任明确的类,让它们之间变得更加灵活,开发者可以通过继承这些类创建子类,来改变它们的行为.但是如果想将某个开发者的改变跟其它已经编写了自己子类的开发者共享,这种面向对象的继承就不再那么有用了. 举一个现实的实例,你想为你的项目提供一个插件系统.一个能够被添加到方法的插件,或者在方法执行的前后完成某些工作,而不会干扰到其它插件.这个通过单一的继承完成不是一个

HTML 学习笔记 JavaScript(面向对象)

现在让我们继续跟着大神的脚步前进 学习一下JavaScript中的面向对象的思想,其实作为一个iOS开发者,对面向对象还是比较熟悉的,但是昨晚看了一下Js中的面向对象,妈蛋 一脸萌比啊.还好有大神.让我们跟着大神的思路在捋一下.(在这里更欢迎大家阅读原博 )原博地址:http://www.cnblogs.com/dolphinX/p/4385862.html 理解对象 对象这个词如雷贯耳,同样出名的一句话:XXX语言中一切皆为对象! 对象是什么?什么觉面向对象的编程? 对象(object),台湾

JavaScript学习笔记之事件

首先,事件流描述的是从页面中接受事件的顺序. 事件捕获和事件冒泡: IE的事件流是事件冒泡,一直冒泡到window对象.(IE9之前会跳过HTML元素,从body直接跳到document) 事件捕获:与事件冒泡的思路相反,即不太具体的节点应该先接收到事件的信息,最具体的节点应该最后接受到事件信息.(IE9也支持) DOM事件流: 分为三个阶段:事件捕获,处于目标阶段,事件冒泡. IE9之前的浏览器不支持事件流. 事件处理程序就是响应某个事件的函数,也叫做事件侦听器. HTML事件处理程序:因为值

JAVAscript学习笔记 js事件 第一节 (原创) 参考js使用表

<!DOCTYPE html> <html lang="en" onUnload="ud()"> <head> <meta charset="UTF-8"> <title>Title</title> <script> function demo() { alert("hello"); } function onOver(ooj) { ooj.i

JQuery学习笔记- jQuery 事件与应用

1. 页面加载时触发ready()事件 ready()事件类似于onLoad()事件,但前者只要页面的DOM结构加载后便触发,而后者必须在页面全部元素加载成功才触发,ready()可以写多个,按顺序执行.此外,下列写法是相等的: $(document).ready(function(){})等价于$(function(){}); 2. 使用bind()方法绑定元素的事件 bind()方法绑定元素的事件非常方便,绑定前,需要知道被绑定的元素名.绑定的事件名称.事件中执行的函数内容就可以,它的绑定格

HTML 学习笔记 JavaScript (prototype)

原博地址:http://www.cnblogs.com/dolphinX/p/3286177.html 原博客的作者是一个非常牛逼的前端大神,我作为一个初学者,在此借助大神的博客进行自己的学习.在这里感谢原作者无私的分享.也强烈建议大家到原作者的博客下学习.好了,现在让我们跟着大神的脚步前进吧. 用过JavaScript的人肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都有一个prototype属性,可以为其添加函数供实例访问,其他的就不清楚了,下面我们