循序渐进学编程8.javascript DOM事件

dom事件

术语

  • 事件:发生一件事

  • 事件类型:发生什么事情;点击、鼠标按下、鼠标抬起、鼠标移入、鼠标移出、键盘按下、键盘抬起…

  • 事件处理程序:一个函数,当某件事情发生时运行。

  • 事件注册:将一个事件处理程序,挂载到某个事件上。

事件流

事件流:当某个事件发生的时候,哪些元素会监听到该事件发生,这些元素发生该事件的顺序.

当一个元素发生了某个事件时,那该元素的所有祖先元素(html结构上)都发生了该事件—这就是事件冒泡和事件捕获会发生的根本原因

事件冒泡:先触发最里层的元素,然后再依次触发外层元素

事件捕获:先触发外层的元素,然后再依次触发里面的元素

目前,标准规定,默认情况下,事件是冒泡的方式触发的;

事件源的祖先元素的事件默认发生在事件冒泡阶段;

事件源、事件目标:事件目标阶段的元素(事件触发的元素)

事件注册

事件绑定

dom0

将事件名称前面加上on,作为dom的属性名,给该属性添加一个函数,即为事件注册

移除:重新给事件属性赋值,通常为null、undefined

dom2

dom对象.addEventListner:注册事件

与dom0的区别

  1. dom2可以为某个元素的同一个事件,添加多个处理程序(按照事件注册顺序触发)
  2. dom2允许开发者控制事件处理的阶段,使用第三个参数,表示其是否在捕获阶段触发,默认为false,给事件目标写在捕获阶段触发无意义,只有给事件目标的父元素写才有意义
    1. 如果元素是目标元素(事件源),则第三个参数无效
      事件的移除:dom对象.removeEventListner(事件名,处理函数-有名函数);

dom2中如果要移除事件,不能使用匿名函数

细节

  1. dom2在IE8及以下不兼容,需要使用attachEvent, detachEvent添加和移除事件,ie支持冒泡,所以没有第三个参数;
  2. 添加和移除事件时(removeEventListner),可以将第三个参数写为一个对象,进行相关配置
    对象参数
    1. capture:是否在捕获阶段运行
    2. once:该事件是否只运行一次

事件对象

封装了事件的相关信息

获取事件对象

  • 通过事件处理函数的参数获取
    ie的以前版本是window.event

事件对象的通用成员

  • target属性 & srcElement属性

事件目标(事件源)

事件委托(给祖先元素注册事件,然后使用event.target判断事件源,进行不同的注册)

e.target.tagName 得到事件源的标签名
好处:使用事件委托注册的事件,动态添加子元素的时候事件也会被触发并且做出操作

通常,事件委托用于动态生成元素的区域

  • currentTarget属性

当前目标:获取绑定事件的元素,等效于this

  • type属性

字符串,得到事件的类型

  • preventDefault方法 & returnValue属性

阻止浏览器默认行为-比如a元素有默认的行为跳转页面,button元素

e.preventDefault()–该方法可阻止浏览器的默认行为

e.returnValue属性是ie8以下的方法,但是现在这个已经建议不被使用–e.returnValue = false可以在ie8以下阻止浏览器默认行为

dom0的方式,在事件处理程序中返回false

针对a元素,可以设置功能性链接,阻止默认行为,在href属性中可以写’javascript:[void 0];’

void xxx—就是先运行xxx在返回undefined

  • stopPropagation方法

阻止事件冒泡,在事件目标阶段阻止冒泡的话阻止后面的所有冒泡

写在冒泡阶段,该目标就是事件冒泡结束元素

  • bubbles属性
    布尔值,返回该元素的该事件是否冒泡
div.div1>p.div2>span.div3>button

div1.onclick = div3.onclick = button.onclick = function (e) {
    console.log(e.currentTarget.tagName);
}
div2.onclick = function (e) {
    e.stopPropagation();
}
// 只会打印span和button
  • eventPhase属性

得到事件所处的阶段

1:表示事件捕获
2:表示事件目标
3:表示事件冒泡

鼠标事件

事件类型

  • click:用户按下主按钮(可以配置,一般是左键)或者在鼠标聚焦时按下回车;

  • dblclcik:用户双击主鼠标按键触发(频率取决于系统配置)–双击还会触发两次click事件

  • mousedown:用户鼠标按下的时候被触发

  • mouseup:用户抬起鼠标任意按键时触发

  • mousemove:鼠标在元素上移动时触发

  • mouseover:鼠标进入元素时触发

  • mouseout:鼠标离开元素时触发

先触发的时over和out,后出发enter和leave

  • mouseenter:鼠标进入元素时触发,该事件不会冒泡-将子元素作为自己的一部分
  • mouseleave:鼠标离开元素时触发,该事件不会冒泡

区别:

  • over和out,不考虑子元素,从父元素移动到子元素,对于父元素而言,仍然算作离开
  • enter和leave,考虑子元素,子元素仍然时父元素的一部分
  • mouseenter和mouseleave

事件对象

所有的鼠标事件,事件处理程序中的事件对象,都为MouseEvent
下列为事件对象的属性

键盘判断

  • altKey:触发事件时,是否按下了键盘的alt键
  • ctrlKey:触发事件时,是否按下了键盘的ctrl键
  • shiftKey:触发事件时,是否按下了键盘的shift键
  • button:触发事件时,按下的鼠标类型(鼠标移入移出这样的事件不会触发)
    • 0:左键
    • 1:中键
    • 2:右键

位置:

  • page:pageX、pageY, 当前鼠标距离页面的横纵坐标
  • client:clientX、clientY,鼠标相对于视口的坐标
  • offset:offsetX、offsetY,鼠标相对于事件源的内边距的坐标
  • screen:screenX、screenY,鼠标相对于屏幕
  • x、y:等同于clientX、clientY
  • movement:movementX、movementY,只在鼠标移动事件(mousemove)中有效,相对于上一次鼠标位置(并不是移动一个像素就触发)

window对象中有一个属性top,只可读不可写

  1. 使用movement
  2. 按前和按后的page差
  3. client
  1. 拖拽效果
  2. 仿照京东商城做放大镜
  3. 星星评分

键盘事件

注册事件尽量给大的元素注册事件,防止小元素无法聚焦导致无法触发键盘事件

事件类型

  • keydown:按下键盘上任意键时触发,如果按住不放,会一直触发
  • keypress:按下键盘上一个字符键时触发
  • keyup:抬起键盘上任意键触发

keydown和keypress如果阻止了默认行为,文本不会显示

press:往往有点反馈
input框能够将输入的字符显示是因为keydown、keypress的默认行为,只需要阻止其中一个事件中的默认行为就无法输入字符;

事件对象

KeyboardEvent

大部分已经过期

  • keycode、which:得到键盘编码

  • code属性:得到按键字符串,适配键盘布局(可以识别左右)。

  • key属性:得到按键字符串,不适配键盘布局;能得到打印字符

其他事件

聚焦事件(表单事件,a元素)

  • focus:元素聚焦的时候触发(能与用户发生交互的元素,都可以聚焦),该事件不会冒泡
  • blur:元素失去焦点时触发,该事件不会冒泡
  • submit:提交表单事件,仅在form元素有效,提交的是整个表单,该事件可以冒泡
  • change:文本改变事件, 离开文本框的时候触发
  • input:文本改变事件,即时触发–可以用来做即使验证,该事件无法阻止默认行为

输入框有一个defaultValue的属性—值是一开始在html元素行间写的value的值

其他事件

window全局对象

  • load、DOMContentLoaded、readystatechange

window的load:页面中所有资源加载完毕的事件
图片dom的load:图片异步加载完成之后触发的事件–这种场景应用较多

浏览器渲染页面的过程

  1. 得到页面源代码
  2. 创建document节点
  3. 从上到下依次执行代码
  4. 将元素依次添加到dom树中,每添加一个元素,进行预渲染
    有外部资源的时候进行同步加载外部资源
    asynchronous
    async–布尔属性,写在行间表示该资源异步加载
    sync–同步的
    js代码应该尽量写到页面底部,先看到页面,在看到功能,而且js同步加载很浪费时间

document的DOMContentLoaded:dom元素构建完成之后发生-该事件必须使用dom2的注册方法

readystate:loading、interactive(dom已经建立好了)、complete

interactive:触发DOMContentloaded事件
complete:触发window的load事件

document.readystate;
window.addEventListner('DOMContentloaded', function () {
    console.log(document.reaystate);
});
window.addEventListner('load', function (){
    console.log(document.readystate);
})
// 输出顺序是loading、interactive、complete

document.readystatechange事件:当页面状态发生改变后触发该事件

  • css代码应该写到页面底部:避免出现闪烁(如果放到页面底部,会导致元素先没有样式,会使用丑陋的默认样式,然后到读到css文件后,重新改变样式)

  • js应该写到页面底部:避免阻塞后续的渲染,也避免运行js时,得不到页面中的元素。

  • unload、beforeunload

beforeunload:window的事件,关闭窗口时运行,可以阻止关闭窗口(在事件处理函数中返回一个字符串即可)
unload:window的事件,关闭窗口时运行

  • scroll

窗口发生滚动时运行的事件,触发频率无法自己决定,取决于配置和浏览器

通过scrollTop和scrollLeft,可以获取和设置滚动距离

细节:如何获取整个网页的滚动条top和left

  • document.documentElement.scrollTop + document.body.scrollTop,这两个值一个一定是0, 一个是有值的,所以相加可得最终值.

  • resize
    window的事件

窗口尺寸发生改变后运行的事件,监听的是可视区的尺寸

  • window的属性
  1. window.innerWidth、window.innerHeight
    窗口的内尺寸(包含滚动条)
  2. window.outerWidth、window.outerHeight
    窗口的外尺寸
  3. document.documentElement.clientWidth、document.documentElement.clientHeight
    得到视口尺寸(不包含滚动条)
  4. window.screen.width、window.screen.height—客户的屏幕尺寸
  • dom的属性
    dom.clientWidth、dom.clientHeight—不包含边框和滚动条
    dom.offsetWidth、dom.offsetHeight—包含边框和滚动条
    dom.scrollWidth、dom.scrollHeight—包含所有实际的内容(包括不可见的区域),不包含滚动条和边框

  • contextmenu
    右键菜单事件,阻止默认行为的话就不可以通过点击右键来使得无法出现菜单事件

  • paste
    粘贴后触发的事件,阻止默认行为的话无法粘贴
    window.clipboardData || e.clipboardData – 在paste事件中可得到一个对象obj, obj.getData(‘MIME’)可得到字符串,obj.setData(‘MIME’, data)—这个方法现在无法使用,obj.clearData(‘MIME’)—清空文本框;

MIME-互联网中字符串的标准格式

  1. text/plain—普通文本
  • copy
    复制元素内容后触发的事件,阻止默认行为的话无法复制

  • cut
    剪切后触发的事件,阻止默认行为后无法进行剪切

补充知识

元素位置

每个元素都有的属性

  • offsetParent

获取某个元素的第一个有定位的父元素,如果没有,则得到body

body的offsetParen是null

  • offsetLeft、offsetTop

相对于该元素的offsetParent的坐标
如果该元素的offsetParent是body,则将其当作是整个网页
注意这里的right值是指视口左部到元素右端的距离

  • getBoundingClientRect

该方法得到一个对象,该对象记录了该元素相对于视口的距离

事件模拟

  • click
    先绑定事件,然后直接调用就可以手触发
    dom.click();
  • submit

只有以上两个事件才可以这样直接调用
其他事件需要使用到dispatchEvent触发

  • dispatchEvent方法
    dom.dispatchEvent(event);—这个实参event可以是用MouseEvent构造函数new出来的对象
var event = new MouseEvent("mouseenter", {
    bubbles:false
    // 一些配置
})

其他补充

  • window.scrollX、window.pageXOffset、window.scrollY、window.pageYoffset

window.scrollX、window.pageXOffset:相当于根元素的scrollLeft

window.scrollY、window.pageYOffset:相当于根元素的scrollTop

  • scrollTo(x, y)、scrollBy(offsetX, offsetY)
    window的方法
    scrollTo设置滚动条的位置
    scrollBy是基于原来位置改变

  • resizeTo(width, height)、resizeBy(offsetWidth, offsetHeight)

window的属性,这个方法只能是用代码打开的窗口才可以设置,用户的浏览器窗口不允许设置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值