DOM事件

130 阅读8分钟

事件基础

概念

事件是指用户跟页面进行交互的各种动作的统称。比如点击、双击、按压键盘、滚轮等。
我们可以实现通过事件的处理能够当用户触发某个动作时能够去执行js代码。

事件分类

UI:跟用户间接相关的事件:
load:在资源加载完成之后触发
只针对window对象以及img标签有效
window对象即页面加载完成之后触发。如果是img标签,那么表示图片加载完成之后进行触发
resize:在页面的尺寸发生变化时进行触发
标签变量名.onload = function() {
     //资源加载完成之后
     }
标签变量名.onresize = function() {
    //标签尺寸变化时进行触发
    }
例子
window.onload = function(){
    //页面的dom结构加载完之后进行触发
    }
    var img = document.querySelector("img")
img标签变量名.onload = function(){
    图片加载完之后进行触发
    }
对于window.onload来说,可以保证里面的代码是在页面dom树加载完成之后执行,就避免了head标签里的dom代码会失效。
resize一般也是针对整个页面

鼠标
click:点击事件
dblclick:双击
mousemove:当鼠标在指定标签内部移动时会触发
mouseenter:当鼠标进入指定标签内部会触发一次
mouseleave:当鼠标离开指定标签内部会触发一次
标签变量名.ondblclick = function() {
    //要执行的代码
    }
标签变量名.onmouse move= function() {
    //该标签内部移动时会执行
    }
标签变量名.onmouseenter = function() {
    //进入该标签内部时会执行
    }
标签变量名.onmouseleave = function() {
    //离开该标签内部时会执行
    }
 <div ondblclick="" onmouseenter="" onmouseleave=""></div>
 
键盘
keydown:按下键盘任何一个键时会触发
keyup:按下键盘任何一个键完全释放时触发
keypress:按下键盘任何一个键到底部即将释放时触发
标签变量名.onkeydown = function() {
    
    }
标签变量名.onkeypress = function() {
    
    }
标签变量名.onkeyup = function() {
    
    }
<div onkeyup="" onkeydown="" onkeyup=""></div>
这三个事件只有keyup可以获取输入框最新的数据,所以一般keyup用的最多。
一般我们会用来实时检测用户的输入是否符号要求。

焦点
focus:一般是表单元素获取焦点时触发,比如鼠标点击输入框
blur:一般是表单元素失去焦点时触发,比如鼠标点击输入框
标签变量名.onfocus = function() {

}
标签变量名.onblur = function() {

}
<div onfocus="" onblur=""></div>
一般用于用户输入监测或改变样式

文本
change:一般针对下拉菜单的,用于当用户切换选项时触发
<select onchange=""></select>
标签变量名.onchange = function(){

}

滚轮
mousewheel:当鼠标滚轮在滚动时进行触发,火狐不兼容
DOMMouseScroll:当鼠标滚轮在滚动时进行触发,火狐不兼容
<div onmousewheel = ""></div>
标签变量名.onmousewheel = function() {

}
标签变量名.onDOMMouseScroll = function() {

}
标签变量名.addEventListener("DOMMouseScroll",function() {

})
一般用于实现长列表数据动态加载(参考京东首页数据滚动加载)

触摸屏
touchstart:当触摸屏单个手指点击时触发
touchend:当触摸屏单个手指离开屏幕时触发
touchmove:当触摸屏上的单个手指在屏幕上移动时触发
标签变量名.addEventListener('touchstart',function(){

})
标签变量名.addEventListener('touchend',function(){

})
标签变量名.addEventListener('touchmove',function(){

})

事件处理程序

事件流

背景:为了解决针对嵌套标签的事件触发位置问题。所以才有了事件流的概念。
概念
事件流是指事件触发的顺序流向,即谁先触发事件,谁后触发。针对嵌套标签。
根据事件触发的顺序不同事件流分为冒泡和捕获。
冒泡
从具体触发事件的子标签开始冒泡,会依次的去触发父标签及祖先标签的事件
html:
<div class="box1">div-1
    <div class="box2">div-2
        <div class="box3">div-3
            <div class="box4">div-4
                <div class="box5">div-5</div>
            </div>
        </div>
    </div>
</div>
js
给5个div设置事件。对于冒泡来说,触发的事件顺序是box5 ->box4 ->box3 ->box2 ->box1 ->body ->html ->document对象.由具体的子标签到父标签。

捕获
从document开始触发事件,一直触发到具体的子标签。

html:
<div class="box1">div-1
    <div class="box2">div-2
        <div class="box3">div-3
            <div class="box4">div-4
                <div class="box5">div-5</div>
            </div>
        </div>
    </div>
</div>
js
给5个div设置事件。对于冒泡来说,触发的事件顺序是box5<- box4<- box3<- box2<- box1<- body<- html<- document对象.由document到body,到具体的子标签。

事件执行阶段

概念

当用户触发某个事件时,该事件的完整的执行流程就是事件执行流程(阶段)

流程

第一阶段:先执行一次捕获,即父标签触发(最顶层能够到document),一直到具体的子标签触发。
第二阶段:事件目标阶段:真正用户要执行事件的子标签进行触发
第三阶段:执行一次冒泡。由具体的子标签到父标签依次触发。

注意点

第二阶段:事件目标实际上是将第一阶段的末尾以及第三阶段的开头划分为了第二阶段。只是为了说明目前是对用户真正要执行的标签进行处理。实际第二阶段不会再单独的触发一次。
实际的事件处理中,只会在捕获或冒泡中二选一,普遍用的最多的是冒泡。

事件处理程序

概念

当触发某个事件时要执行的程序(即代码),根据更新分为DOM0级和DOM2级。

DOM 0级

1.js
标签变量名.on事件名 = function(){

}
2.作为标签的属性
<div on事件名=“要执行的代码”></div>

DOM 0级只能是在事件执行阶段中的第三阶段处理。

DOM 2级

//添加事件处理程序
标签变量名.addEventListener('事件名',事件触发要执行的函数,是否是捕获阶段处理);
第三个参数是布尔型,true表示捕获阶段处理,false表示冒泡阶段处理,默认false//删除事件处理程序
标签变量名.removeEventListener'事件名',事件触发要执行的函数,是否是捕获阶段处理);

例子:body设置点击事件的处理程序为handler,捕获阶段处理
document.body.addEventListener('click',handler,true);
//删除
document.body.eamoveEventListener('click',handler,true);

function handler(){
    console.log("body被点击了")
    }

如果要删除的话,必须保证删除使用的3个参数和添加时写的3个参数完全一样。第二个参数必须是一个函数名,而不是一个具体的function。

DOM 2级和DOM 0级关于事件处理程序的区别

dom 2级可以选择在捕获阶段或冒泡阶段进行处理。而dom 0级只能在冒泡阶段处理。

兼容性

DOM 2级只能ie9+支持,DOM 0级全系支持。

event对象

概念

js为了能够在处理事件相关代码时,能够获取该事件的相关信息,js会在触发某事件时自动创建一个event对象并收集该事件的相关信息,该event对象会作为事件处理函数的实际参数。所以我们在写事件处理代码时需要定义形式参数来接收。
接收event对象后,可以使用event对象里所包含的相关内容。比如事件的触发标签,事件类型名,甚至可以控制冒泡行为,获取触发事件时鼠标的所在位置。

获取event对象

html:
<div></div>
js:
var div = document.querySelector('div');
div.addEventListener('click',function(event){
    //event参数就保存了该对象
    console.log(event);
    })

每次触发事件时会新建event对象

常用属性和api

target:真正触发事件的标签
currentTarget:当前正在处理的事件标签,因冒泡或捕获,所以实际的标签会不同,不常用。
stopPropagation():取消进一步的冒泡。
preventDefault():取消事件的默认行为。比如a标签的默认行为是条件,如果调用了该函数后,a标签就不再有跳转功能。表单里的按钮也是一样,调用了该函数后,按钮就不具有表单提交功能。
type:事件的类型名
clientX&clientY:指触发事件时,鼠标在当前窗口中的下标。以屏幕左上角为原点。
pageX&pageY:获取鼠标的坐标,以屏幕左上角为原点。跟clientX&clientY的区别是是以整个HTML文档作为参考。
event对象名.target
event对象名.clientX
event对象名.clientY
event对象名.preventDefault();
event对象名.stopPropagation();

事件委托

背景

我们在给多个标签设置事件处理程序时,那么相关代码会很多,特别是针对有规律的事件代码,会显得很繁琐。针对代码繁琐,我们可以用事件委托来解决。

概念

事件委托,又称事件代理。是指利用了事件执行阶段中的冒泡机制以及配合event对象来达到减少事件处理代码量的一种编程技巧。

作用

减少事件处理程序的代码量。
管理事件处理代码。

语法(流程)

给需要设置点击事件的标签的父标签或祖先标签设置事件处理程序。
利用event.target来判断真正触发事件的具体子标签。然后针对该子标签执行相应代码。
//事件委托
document.body.addEventListener('click',function(e){
    //区分:class id nodeName
    var classname = e.target.getAttribute('class');
    if(classname == 'box1')
      //点击了box1 div
      //执行box1 的点击事件代码)
      console.log('点击了box1')
      }else if(classname == 'box2') {
          console.log('点击了box2')
      }
  });

扩展

表单提交或重置

submit()
reset()
html
<form action="success.html" id="loginForm">
        用户名:<input type="text" id="user">
        密码:<input type="password" id="pass">
        <button id="login-btn">登录</button>
</form>

js
var form = document.querySelector("#loginForm");

提交:form.submit();
重置:form.reset();