事件

1.何谓事件

用户和网页交互时的行为,动作,称之为事件;

2.监视事件

现实生活中,为了监视车辆是否违章,通过在红绿灯安装摄像头监视车辆,我们在网页中要想知道用户是否某个行为是否发生了,也需要安装监听器进行监视,这样当用户的行为发生时,我们要做相应的处理,从而提升用户体验.

我们监视用户的行为(事件)是否发生了,有3种方式:
(1)将事件监听器绑定在html标签上,作为标签属性存在
例如我们监听用户点击的行为,可采取这种写法<a href="onclick">,通过on关键字加监视的行为(事件),这种方式由于html标签和javascript代码紧密耦合在一块,这样不是非常的灵活;

将事件监听器绑定在html标签上,作为标签属性存在

(2)DOM0级事件监听
将事件监听器绑定在DOM节点对象上

DOM0级事件监听

(3)DOM2级事件监听
DOM2级事件定义了两个方法用于处理指定和删除事件处理程序的操作:

  • addEventListener
  • removeEventListener
    所有的DOM节点都包含这两个方法,并且它们都接受三个参数:
  • 事件类型
  • 事件处理方法
  • 布尔参数,如果是true表示在捕获阶段调用事件处理程序,如果是false,则是在事件冒泡阶段处理

//参数1:事件类型 click,没有on
//参数2:事件发生时执行的函数
//参数3:是否捕获,true捕获、false非捕获-事件冒泡(100%----false)

  • IE(6-7-8)等浏览器通过attachEvent方法进行监听,通过detachEvent来移除监听程序
    在这里需要特别注意的是IE浏览器只支持事件冒泡的事件流,添加的事件处理程序发生在事件冒泡阶段;
    参数1:事件类型:加上on关键字
    参数2:事件发生时执行的函数
DOM2级监听的简单实例
采用DOM2级实现的监听效果

将上述代码进行简单的封装,保存到common.js文件中,之后导入主文件中进行调用
封装如下:


对DOM2级事件监听的兼容写法

3.事件流

事件流描述的是从页面中接收事件的顺序,比如有两个嵌套的div,点击了内层的div,这时候是内层的div先触发click事件还是外层先触发?目前主要有三种模型:

  • (1) IE的事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的元素

  • (2) Netscape的事件捕获:不太具体的节点更早接收事件,而最具体的元素最后接收事件,和事件冒泡相反

  • (3) DOM事件流:DOM2级事件规定事件流包括三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,首先发生的是事件捕获,为截取事件提供机会,然后是实际目标接收事件,最后是冒泡阶段
    采用以下实例来说明这种事件关系:

事件冒泡模型,事件捕获模型,DOM事件流

4.事件捕获和事件冒泡

  • 事件捕获:先执行父元素身上的事件,再执行自身.设置为true;

  • 事件冒泡:先执行自己身上的事件,再执行父元素身上的.设置false;
    阻止事件冒泡:

通过事件对象阻止,事件对象是当事件(用户行为)发生的时候,会自动产生的一个对象,而且这个对象会自动传递到函数里面,通常我们会通过事件对象来获得当行为发生时,事件主题的信息(坐标、左击、右击等)

分别将执行事件的stopPropogation方法和将cancleBubble属性设置为true,可以阻止主流浏览器和IE浏览器的事件冒泡现象;

  • event.stopPropogation()
  • event.cancleBubble = true

5.事件对象

DOM中的事件对象

在触发DOM上的某个事件的时候会产生一个事件对象event,这个对象包含着所有与事件有关的信息,包括产生事件的元素、事件类型等相关信息。所有浏览器都支持event对象,但支持方式不同。

event对象包含与创建它的特定事件有关的属性和方法,触发事件的类型不同,可用的属性和方法也不同,但是所有事件都会包含

事件对象的属性及方法

6.事件分类

(1)鼠标事件:用户鼠标的行为

  • click :鼠标单击事件
  • dbclick:鼠标双击行为(连续点击)
鼠标连续点击
  • mousedown:鼠标按下行为
  • mouseup:鼠标抬起行为
    通常应用场景:鼠标按下的时候,获得是左击还是右击?通过事件对象的button属性来获得:
    • button属性为:0表示鼠标左击
    • button属性为:1表示滑轮按下
    • button属性为:2表示鼠标右击
鼠标按下,抬起的行为
  • mouseover:鼠标移入(会出现事件冒泡,不仅执行子元素上的事件,而且还会执行父元素上的事件)
  • mouseout:鼠标移除(会出现事件冒泡,不仅执行子元素上的事件,而且还会执行父元素上的事件)
鼠标移入进来,鼠标移出去
  • mouseenter,mouseleave:鼠标移入,移出的行为(阻止事件冒泡)
    要注意这两个鼠标移入移出事件与mouseover以及mouseout事件的区别在于是否阻止了事件冒泡机制;

如上图,可见当鼠标移入子元素的时候,发生了事件冒泡现象,父元素的事件监听也执行了;


如上图,可见当鼠标移入子元素的时候,只会执行子元素上的事件监听程序,而不会发生事件冒泡现象

  • mousemove:鼠标移动(放大镜)
    通常通过鼠标移动的时候,获得事件发生时鼠标所在的位置

通过事件对象的
clientX、clientY:获得距离客户端(浏览器)的距离(不包含滚动条卷去的高度)
pageX、pageY:获得距离页面的距离(包含滚动条卷去的高度)

clientX,clientY分别是事件对象的属性
pageX,pageY表示获得距离页面的距离,包含了滚动条卷去的高度
  • scroll:鼠标滑轮滚动行为
    说明:由于scroll监视的是body整体在滑动,所以事件应该监视在body身上去
    获得每次滑轮滚动时,滚动的距离,通过scrollTop获得滚动距离,而scrollHeight获得滚动条总的高度;
    • scrollTop:获得滚动条每次滚动的距离(距离顶部的距离)
    • scrollLeft:获得滚动条每次滚动的距离(距离左边的距离)
    • scrollHeight:获得滚动条总的高度

(2)键盘事件:用户键盘行为

说明:监视用户的键盘的行为,用户可以通过键盘和网页进行交互

javascript设计者给每一个按键分配了一个ASCII码,通过事件对象的keyCode属性获得这个ASCII码:
比如当我们按下w键时,对应的ASCLL码值为87,同理s键对应的是83.a键对应的是65,d键对应的是68;

有3个按键是特殊:
ctrl键 ----------- event.ctrlKey属性
shift键---------- event.shiftKey属性
alt键----------- event.altKey属性
这三个按键只有当我们按下的时候,对应的这3个属性才为true

将来我们只需要判断只要ctrlKey属性为true,说明ctrl键被按下了,只要altKey属性为true,说明altKey属性被按下了

这三个键按下的时候打印true,抬起则为false
  • keydown:键盘按键按下
  • keyup:键盘按键抬起

(3)表单事件

  • submit:表单提交事件(表单提交行为)
    通常监视这个提交的行为,一旦提交行为发生了,我们要去验证输入框的内容是否合法,如果不符合规则,则阻止表单提交到服务器;

  • select:输入框内容被选中行为

  • focus:输入框获得光标,获得焦点行为

  • blur:输入框失去光标,失去焦点行为

  • change:监视下拉列表内容发生变化行为

  • reset:重置按钮被点击的行为

(4)页面加载完毕事件
load:某个网页以及图像被完整加载

复习部分

题目1: DOM0 事件和DOM2级在事件监听使用方式上有什么区别?

DOM0级事件和DOM2级在时间监听使用方式的区别在于:

  • DOM0级事件
    是将事件监听器绑定在DOM节点上,事件处理程序是被认为是当前绑定节点元素的事件处理属性的值,事件处理程序是在元素的作用域下运行,this指的是当前的元素;要注意的是一个事件只能绑定一次,如果绑定了新方法,则新方法会覆盖旧方法;

  • DOM2级事件 定义了addEventListener,removeEventLIstener两种方法用于处理指定和删除事件处理程序的操作;所有的DOM节点都包含这两个方法,并且它们都接受三个参数:事件类型、事件处理方法、布尔参数。本质是通过DOM节点特定的绑定事件监听程序来进行事件处理;

题目2: attachEvent与addEventListener的区别?

attachEvent与addEventListener的区别在于:

  • 兼容性上的区别,attachEvent是老版本IE上绑定事件处理程序的方法,而addEventListener是主流浏览器上的绑定事件处理程序的方法;

  • 参数个数不相同,addEventListener有三个参数,attachEvent只有两个,attachEvent添加的事件处理程序只能发生在冒泡阶段,addEventListener第三个参数可以决定添加的事件处理程序是在捕获阶段还是冒泡阶段处理(我们一般为了浏览器兼容性都设置为冒泡阶段)

  • 第一个参数意义不同,addEventListener第一个参数是事件类型(比如click,load),而attachEvent第一个参数指明的是事件处理函数名称(onclick,onload)

  • 事件处理程序的作用域不相同,addEventListener的作用域是元素本身,this是指的触发元素,而attachEvent事件处理程序会在全局变量内运行,this是window,所以会返回undefined,而不是元素id。

  • 为一个事件添加多个事件处理程序时,执行的顺序不同。 addEventListener 会按照添加的顺序执行。 attachEvent 添加多个事件处理程序时,顺序是无规律的。

题目3: 解释IE事件冒泡和DOM2事件传播机制?

  • 事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的元素;
    假如将DOM节点各级都绑定了事件监听器,那么当发生IE事件冒泡时,会从子类元素的事件处理程序开始执行,一级一级向上执行各级的事件冒泡程序;

  • DOM2级事件规定事件流包括三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,首先发生的是事件捕获,为截取事件提供机会,然后是实际目标接收事件,最后是冒泡阶段;

题目4:如何阻止事件冒泡? 如何阻止默认事件?

  • 要阻止事件的默认行为,可以使用preventDefault()方法,前提是cancelable值为true

  • stopPropagation()方法可以停止事件在DOM层次的传播,即取消进一步的事件捕获或冒泡

  • 而要阻止在IE上的事件冒泡发生,则可将事件对象的cancleBubble 属性设置为true;

题目5:有如下代码,要求当点击每一个元素li时控制台展示该元素的文本内容。不考虑兼容

<script>
    var liArr = document.getElementsByClassName('ct')[0].getElementsByTagName('li')
    for(var i=0;i<liArr.length;i++){
        liArr[i].addEventListener('click', function(){
            console.log(this.innerText);
        }, false)
        
    }
</script>

题目6: 补全代码,要求:

  • 当点击按钮开头添加时在<li>这里是</li>元素前添加一个新元素,内容为用户输入的非空字符串;当点击结尾添加时在最后一个 li 元素后添加用户输入的非空字符串.
  • 当点击每一个元素li时控制台展示该元素的文本内容。
 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
  <body>
    <ul class="ct">
    <li>测试数据1</li>
    <li>测试数据2</li>
    <li>测试数据3</li>
</ul>
<input type="text" class="ipt-add-content" placeholder="添加内容"/>
<button id="btn-add-start">开头添加</button>
<button id="btn-add-end">结尾添加</button>
<script>

    var ct=document.querySelector('.ct'),
        addStartBtn=document.querySelector('#btn-add-start'),
        addEndBtn=document.querySelector('#btn-add-end'),
        ipt=document.querySelector('.ipt-add-content');


    ct.addEventListener('click',function(e){
            if(e.target.tagName.toLowerCase()==='li'){
                console.log(e.target.innerText);
            }
  });

    addEndBtn.addEventListener('click', function(){
            if(!ipt.value){ 
                    alert('文本输入框必须输入内容'); 
                    return; 
            }else{
                let newLi=document.createElement('li');             
                newLi.innerText=ipt.value;
                ct.appendChild(newLi);
                ipt.value='';   
            }       
    });

    addStartBtn.addEventListener('click', function(){
            if(!ipt.value){ 
                alert('文本输入框必须输入内容'); 
                return; 
            }else{
              let newLi=document.createElement('li');
                newLi.innerText=ipt.value;      
                ct.insertBefore(newLi, ct.firstChild);
                ipt.value='';   
            }       
    });
</script>
</body>
</html>

题目7: 补全代码,要求:当鼠标放置在li元素上,会在img-preview里展示当前li元素的data-img对应的图片。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<ul class="ct">
    <li data-img="http://cdn.jirengu.com/book.jirengu.com/img/11.jpg">鼠标放置查看图片</li>
    <li data-img="http://cdn.jirengu.com/book.jirengu.com/img/13.jpg">鼠标放置查看图片</li>
    <li data-img="http://cdn.jirengu.com/book.jirengu.com/img/14.jpg">鼠标放置查看图片</li>
</ul>
<div class="img-preview"></div>

<script text="text/javascript">
    var ct = document.querySelector(".ct");
    var list = document.querySelectorAll("li");
    var preview = document.querySelector(".img-preview")

    //利用循环来绑定事件
    /*for(var i=0;i<list.length;i++){
        list[i].addEventListener('click', function(){
            //设置data-img变量来存储图片的网络地址
            var data_img = this.getAttribute("data-img");
            preview.innerHTML = "![]("+data_img+")";
        }, false)
    }
*/
    
    //利用事件代理来实现事件绑定
    ct.addEventListener('click', function(e){
        var data_img = e.target.getAttribute('data-img');
        preview.innerHTML = "![]("+data_img+")";
    }, false)
    
</script>
</body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 以下文章为转载,对理解JavaScript中的事件处理机制很有帮助,浅显易懂,特分享于此。 什么是事件? 事件(E...
    jxyjxy阅读 3,022评论 1 10
  • JavaScript 程序采用了异步事件驱动编程模型。在这种程序设计风格下,当文档、浏览器、元素或与之相关的对象发...
    劼哥stone阅读 1,250评论 3 11
  • 声明:本文来源于http://www.webzsky.com/?p=731我只是在这里作为自己的学习笔记整理一下(...
    angryyan阅读 6,940评论 1 6
  • DOM0级和DOM2级在事件监听使用方式上有什么区别? DOM0级事件监听:用JavaScript指定事件处理程序...
    LeeoZz阅读 367评论 0 1
  • 事件 JavaScript和HTML的交互是通过事件实现的。JavaScript采用异步事件驱动编程模型,当文档、...
    徐国军_plus阅读 568评论 0 2