JavaScript之事件

事件

js是由事件驱动的

浏览器会侦听页面,当我们出发了对应的行为(事件发生)执行对应的函数(事件的响应)

注册事件(绑定事件)

  • 给元素添加事件,称为注册事件或者绑定事件
  • 注册事件有两种方式:传统方式方法监听注册方式

传统的注册方式

利用on 开头的事件onclick

内联JS
执行js代码

<button onclick="alert(hi~)"></button> 内联JS

执行函数(全局函数)

函数需要加括号

<div onclick ="fn()"></div>

function fn(){
    alert("ok");
}

有参数的情况

<div onclick ="fn(1,2,event)"></div>

function fn(a, b ,e){
    alert("ok");
}
DOM一级事件
var wrapBox = document.querySelector(".wrapBox");
wrapBox.onclick = function() {
    alert('ok');
}
  • btn.onclick=function(){}
  • 特点:注册事件的唯一性
  • 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数

方法监听注册方式 (DOM二级事件 )

w3c标准推荐方式

addEventListener() 它是一个方法

IE9之前的IE不支持此方法,可使用attachEvent()代替

特点:

  • 同一个元素同一个事件可以注册多个监听器,绑定多个事件
  • 可以自定义事件

事件监听可以有多个

按注册顺序依次执行

addEventListener 事件监听方式

https://www.runoob.com/jsref/met-element-addeventlistener.html

eventTarget.addEventListener(eventType,callback,useCapture)

eventTarget.addEventListener()方法将指定的监听器注册到eventtarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

该方法接收三个参数:

  • eventType( 必须参数) 事件类型字符串,必定带引号,比如click、mouseover,不要使用 “on” 前缀。 例如,使用 “click” ,而不是使用 “onclick”

    • 事件类型(click,dbclick,mousedown,keyup)

    https://www.runoob.com/jsref/dom-obj-event.html

  • callback( 必须参数) 事件处理函数,事件发生时,会调用该监听函数。当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, “click” 事件属于 MouseEvent(鼠标事件) 对象

  • useCapture (可选参数)是一个布尔值,指定事件是否在捕获或冒泡阶段执行

    • true - 事件句柄在捕获阶段执行
    • false- 默认 事件句柄在冒泡阶段执行

this指向绑定事件的元素

attachEvent 事件监听方式(IE9及其以下浏览器写法)

IE9之前版本支持

eventTarget.attachEvent()方法将指定的监听器注册到evenTarget(目标对象)上,当该对象触发指定的事件时,指定的回调函数就会被执行。

该方法接收两个参数:

  • eventNameWithOn:事件类型字符串,比如onclick、onmouseover,这里要带on
  • callback:事件处理函数,当目标触发事件时回调函数被调用

注册事件 兼容处理

低版本IE存在兼容问题

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image-20200813230024071

自定义事件的触发(抛发)

抛发

image-20200818120608656

// 先自定义事件

// 创建一个事件对象,honor为自定义的事件名
var e = new Event('honor');
console.log(e);

// 抛发
//由绑定事件的元素来抛发
// 传统的注册方式,也可以抛发
wrapBox.dispatchEvent(e)

创建鼠标。键盘的自定义事件对象

image-20200819091107193

删除事件(解绑事件)

传统方式的解绑

内联JS 清除事件

删除对应事件的属性

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一级事件 清除事件,设置为null
eventTarget.onclick=nul1;

image-20200813230701146

方法监听方式的解绑

清除的时候的,对应函数名清除

函数触发谁,就指向谁,事件监听中的函数,绑定给谁,就指向谁

eventTarget.removeEventListener(eventType,function,useCapture);

// eventType 事件类型(click,dblclick ,mousedown,keyup) 
// function 清除的函数
// bool是否在捕获阶段触发事件

//此时的function不能是匿名函数,必须在下面封装,在此处调用的的时候,不需要加括号

attachEvent事件的移除

eventTarget.detachEvent(eventNameWithon,callback);

image-20200813230833040

删除事件兼容处理

image-20200818144414169

image-20200813230931847

事件传播的两种方式

历史渊源

网景浏览器 事件捕获 从最特定的元素到最特定的元素(由外而内)

IE浏览器 事件冒泡 从最特定的元素到最不特定的元素 (由内到外)

  • 主流 事件冒泡

  • DOM 一级绑定 只能进行事件冒泡

  • 低版本IE 只能冒泡

DOM事件流(父子元素都绑定同类型的事件)

  • 事件流描述的是从页面中接收事件的顺序
  • 事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
  • 比如我们给一个div注册了点击事件:

DOM事件流分为3个阶段:

  • 捕获阶段
    • 事件由外而内触发一直找到事件源
  • 当前目标阶段
    • 如果目标元素(事件源)有事件,则先触发目标元素的事件
    • 如果目标元素(事件源)没有事件,则进入冒泡阶段
  • 冒泡阶段
    • 自目标元素的父元素开始冒泡,如果有事件则会触发

image-20200813231345383

  • 事件冒泡:IE最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到DOM最顶层节点的过程
  • 事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程

形象理解

image-20200813231501252

注意:

  • js 代码中只能执行捕获或者冒泡其中的一个阶段
  • onclick和attachEvent只能得到冒泡阶段
  • addEventListener(type,listener,usecapture)
    • 第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;
    • 如果是false(不写默认就是false),表示在事件冒泡阶段调用事件处理程序。
  • 实际开发中我们很少使用事件捕获,我们更关注事件冒泡
  • 有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave
  • 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件

事件对象

image-20200813233342915

  • 事件对象事件发生时的所有相关信息(事件源(在谁身上触发的),事件类型(发生了什么事件)鼠标的位置及状态、按下的键,事件发生的时间)
  • event 就是一个事件对象,写到我们侦听的函数的小括号里面,当形参来看
  • 事件对象只有 有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
  • 事件对象 是 我们事件的一系列相关数据的集合,跟事件相关的,
    • 比如鼠标点击,里面就包含了鼠标的相关信息,如鼠标坐标等。
    • 如果是键盘事件,里面就包含的键盘事件的信息,比如判断用尸按下哪个键
  • 这个事件对象我们可以自己命名,比如 event、evt、e
  • 事件对象也有兼容性问题ie678,通过window.event获取

事件对象的使用语法

传统方式

image-20200813232802986

addEventListener 方式

image-20200813232849578

  • 这个event 是个形参,系统帮我们设定为事件对象,不需要传递实参过去

  • 当我们注册事件时,event对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)

事件对象兼容性处理

事件对象本身的获取存在兼容问题:

  • 标准浏览器中是浏览器给方法传递的参数,只需要定义形参e就可以获取到。

  • 在IE6~8中,浏览器不会给方法传递参数,如果需要的话,需要到window.event中获取查找

  • 解决:

    e=e || window.event;
    

image-20200813233233088

事件对象的通用属性

ctrlKey 事件触发时,ctrl键是否被按下

image-20200817180551430

altkey 事件触发时,alt键是否被按下

shiftkey 事件触发时,shift键是否被按下

metakey 事件触发时,win键是否被按下

事件对象的属性

onmouseover/onmouseout 两个事件才有的属性

fromElement 事件触发时,从哪个元素来

toElement 事件触发时,到哪个元素去

事件对象的常见属性和方法

image-20200813233755730

e.target属性 返回触发的事件对象

target 事件源 (触发事件的源头,由哪个元素触发的事件,绑定事件的元素本身,也有可能是它的子代元素)

image-20200813234058526

srcElement 事件源(IE)
e.target 兼容性处理

image-20200813234441046

e.currentTarget属性

跟this非常相似,但是IE 6 7 8不认识

e.target和this的区别
  • e.target 返回的是触发事件的对象(元素),点击了那个元素,就返回哪个元素
  • this 返回是是绑定事件的对象 (元素),哪个元素绑定了这个点击事件,那么就返回谁
e.type属性 返回事件的类型

事件类型是不带on的

image-20200813234936898

浏览器默认行为

阻止 a标签的默认跳转

image-20200819111656048

form的默认提交

image-20200819112059193

阻止 按f5浏览器刷新

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

阻止 鼠标右键菜单

image-20200819112332879

常规浏览器 e.preventDefault() 阻止默认行为(事件)

让链接不跳转或者让提交按钮不提交(DOM标准写法)

注意:

  • 这是一个方法
  • 别忘记加小括号

image-20200813235205239

IE浏览器中 e.returnValue() 低版本浏览器,阻止默认行为

注意:

这是一个属性

兼容写法

image-20200818180513556

addEventListener阻止默认行为

只有e.preventDefault一种方法

传统的注册方式,阻止默认行为
  • 使用e.preventDefault()
  • e.returnValue()
  • 使用return false
    • 也能阻止默认行为没有兼容性问题特点:return后面的代码不执行了,而且只限于传统的注册方式

image-20200813235752008

阻止事件冒泡

事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到到DOM最顶层节点

事件冒泡本身的特性,会带来的坏处,也会带来的好处,需要我们灵活掌握

  • 由于事件传播的机制(事件冒泡),当父子元素绑定相同类型的事件,点击子元素会冒泡到父元素
  • 当父子元素绑定不是相同类型的事件,则此处无法阻止事件冒泡
  • 当父子元素绑定不是相同类型的事件,则各自走各自的完整的一套事件流

阻止事件冒泡的两种方式

  • 标准写法:利用事件对象里面的stopPropagation()方法
  • 阻止当前元素向父级冒泡
e.stopPropagation()
  • 非标准写法:IE6-8利用事件对象cancelBubble属性
// e.cancelBubble默认为false
e.cancelBubble = true;

阻止事件冒泡兼容性解决

// 阻止冒泡的兼容写法
    if(e.stopPropagation){
        e.stopPropagation();
    }
    else{
        e.cancelBubble = true;
    }

image-20200818162934149

image-20200814000624046

事件委托

image-20200814000806191

image-20200814000833605

事件委托也称为事件代理,在jQuery里面称为事件委派

image-20200814001215499

事件委托的原理

不要给每个子节点单独设置事件监听器,而是将事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。

  • 利用事件冒泡的原理,把子元素的事件委托给父代元素(页面中已经存在),由父代元素代为执行

优点:

  • 节省内存

  • 代码结构清晰

  • 给未来生成的元素 绑定事件(页面加载的时候,没有生成,等待一定时间ajax,或则手动触发事件后新增)

  • 可以用e.target 查看返回的是触发事件的对象(元素),点击了那个元素,就返回哪个元素

事件委托的作用

我们只操作了一次DOM,提高了程序的性能

利用冒泡特性,把子元素的事件,委托给父元素,查找元素

判断点击的元素,是什么类型的标签(按标签区分)

image-20200818165339606

按类名区分

  • 单类名

image-20200818165618442

  • 多类名

image-20200818165725662

  • 找下标

image-20200818170030052

真数组才可以调用indexOf()方法

页面相关的事件

  • window
  • onload
  • onresize
  • onscroll

常用的鼠标事件

  • onclick 点击事件(鼠标左键)

  • ondbclick 双击事件

  • onmousedown 鼠标按下(左键 中键 右键均可触发)

    • button值为0,则表示点击了左键
    • button值为1,则表示点击了中键
    • button值为2,则表示点击了右键
  • onmousemove 鼠标移动(每次都触发)

  • onmouseup 鼠标抬起

  • 按下 移动 抬起 配合拖拽使用

  • onmouseover 滑入(只触发一次)

    鼠标经过自身盒子会触发,经过子盒子还会触发。

    • mouseenter 只会经过自身盒子触发,不会冒泡
  • onmouseout 滑出 (只触发一次)

    问题

    当鼠标滑到子元素上会先触发一次mouseout,再触发onmouseover

    解决方法

    用onmouseenter替换onmouseover

    用onmouseleave替换onmouseout

image-20200814001340849

contextmenu 禁止鼠标右键菜单

image-20200814001510282

image-20200814001555259

自定义右键菜单

image-20200819114009584

selectstart禁止鼠标选中

image-20200814001627933

image-20200814001714022

鼠标事件对象

event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象MouseEvent 和键盘事件对象 KeyboardEvent

image-20200814001926047

image-20200814002343153

client 返回鼠标在可视区的x和y坐标(可视位置)

不管有没有滚动条,只返回当前可视区的坐标

page 返回鼠标在文档页面的x和y坐标(实际位置)

拖动滚动条的时候,返回滚动后的坐标

// 变相用于
pagex=clientx+document.documentElement.scrollLeft pageY=clientY+document.documentElement.scrollTop
screen 返回鼠标在电脑屏幕的x和y坐标
offset 事件触发时,鼠标相对于事件源的偏移
  • 一旦出现元素嵌套,不能用此方法
图片跟随鼠标动

image-20200814003025245

image-20200814002907157

image-20200814003001031

键盘事件

  • onkeydown 按键按下时触发事件(所有按键均可触发,虚拟键盘码(大小写 特殊字符和数字))

  • onkeyup 按键抬起/松开时触发事件

  • onkeypress 按键按下时触发(功能键不触发,文本输入的相关按键可以触发 数字 字母 标点符号 运算符)keycode按ASCII码来

image-20200814003106796

注意

  • 如果使用addEventListener****不需要加on
  • onkeypress和前面2个的区别是,它不识别功能键,比如左右箭头,shift等。
    三个事件的执行顺序是:keydown keypress keyup

image-20200814003341746

两种绑定方式

  • 绑定给document 文档的任何位置均可出发|
  • 绑定给单行文本框或者多行文本域(input textarea 设置conteneditable了非表单元素)

键盘事件对象

keyup 和keydown

image-20200814145408933

keyup 和keydown事件,不区分字母大小写,返回对应的keycode,a和A得到的都是65

keypress

区分字母大小写,返回对应的keycode

在onkeypress中,ctrl+enter组合键的 keycode 为10

keycode

IE键盘码的兼容

image-20200817175422410

var keycode=e.keycode || e.which;

通过ASCII码值,判断用户按下了哪个键

o_ASCII表

表单事件

onfocus 表单聚焦时触发

onblur 表单失焦时触发

onchange 表单内容改变时触发

  • 有两个前提
    • 内容改变
    • 失去焦点(enter键也可以触发)
  • 可在下拉框中使用,下拉框改变时触发(省市联动)

oninput 表单内容输入(即时输入)触发

image-20200814152855559

onsubmit 表单提交

onsubmit 绑定给form 表单由提交(input,submit,button)按钮触发

阻止表单默认提交

image-20200814153557102

image-20200814153748147

表单重置

onreset 绑定给form表单,由重置(input:reset)触发

image-20200814153833479

元素拖拽

  • 拖拽的过程 按下 移动 抬起
  • 鼠标按下onmousedown 记录鼠标按下的位置

image-20200817151206080

image-20200817151533517

  • 鼠标移动onmousemove 相对于按下的位置移动

    因为先按下才能移动所以两者是嵌套关系

    image-20200817152316809

image-20200817152339246

  • 最标抬起onmouseup 松开元素 不再移动

image-20200817152517844

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值