JS中的事件

事件 –DOM0 –DOM2–发布订阅–拖拽

什么是事件? 指的是是一件事或一个行为

事件

  • 鼠标事件
    • click 单击
    • dblclick双击 大约300ms内连续点击两次
    • mouseover 鼠标滑进 冒泡阶段 先自己触发 后父辈触发
    • mouseout 鼠标滑出
    • mouseenter 鼠标移入 捕获阶段 先父辈触发 后自己
    • mouseleave鼠标移出
    • mousemove 鼠标滑动(过程)
    • mousedown 鼠标按下(不动)
    • mouseup鼠标抬起
    • mousewheel鼠标滚轮移动
  • 键盘事件
    • 应用元素:textarea input window html body等都可绑定键盘事件
    • keydown (键盘按下时触发)
    • keyup(键盘抬起来时触发)
    • keypress(按下时并抬起来时触发,系统键是监听不到的)
  • 系统事件
    • onload 加载页面资源后
    • onresize(浏览器窗口发生改变时触发)
    • onscroll(滚动条发生改变时触发)
    • DOMContentLoaded (dom元素加载完了后再触发)
  • 表单元素
    • onfoucs 获取焦点(光标)时触发
    • onchange(表单元素发生改变,并且失去焦点后时,才能触发)
    • oninput(移动端,表单输入时触发,只要内容发生改变就会触发)
    • onblur(失去焦点,表示光标离开表单元素时触发)
    • onpropertychange 只要内容发生改变,就会触发
  • 移动端事件
    • ontouchstart触碰到元素触发
    • ontouchend离开元素触发
    • ontouchmove必须在点击的情况,来回移动,才能触发函数
    • onclick 有大约300ms的延迟
事件绑定:事件行为发生时去做的具体的事情 行为和具体事情要绑定起来这就是事件绑定呀

事件对象

1
2
3
4
5
6
7
8
box.onclick = function(e){
e:事件对象 当执行事件绑定的方法时,浏览器会将事件对象作为实参传递到方法中
e.target:事件源 元素对象
e.clientX:鼠标点击的位置距离 可视窗口的 左偏移
e.clientY:鼠标点击的位置距离 可视窗口的 上偏移
e.pageX:鼠标点击的位置距离 BODY的 左偏移
e.pageY:鼠标点击的位置距离 BODY的 上偏移
}

兼容IE低版本浏览器的写法

1
2
3
4
5
box.onclick = function (){
e = e || window.event
var tar = e.target || e.srcElement
e.preventDefault ? e.preventDefault():e.returnValue = false 阻止默认行为
}

操作这个box上下左右移动 键盘事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
enter回车键 : 13
window.onkeydown = function (e){
switch(e.keyCode){//键盘码
case 37 :
box.style.left = parseFloat(box.style.left) - 10 + 'px'
break
case 38 :
box.style.top = parseFloat(box.style.top) - 15 + 'px'
break
case 39 :
box.style.left = parseFloat(box.style.left) + 25 + 'px'
break
case 40 :
box.style.top = parseFloat(box.style.top) + 15 + 'px'
break
}
}

  • 给一个元素(如:div,ul,li)绑定一个行为(如:onclick、onmouseover)等于一个方法 方法里写要执行的东东

默认事件

  • 先执行绑定的事件,再执行默认事件
  • 注:天生自带默认事件的
    • keydown和input和keyupinput事件是在down之后,up之前触发,阻止默认后,不在触发input;
    • a标签默认进行跳转 锚点定位功能
    • img绑定鼠标事件后,会触发原生鼠标拖拽事件
    • 移动端默认事件:touchmove
      • 阻止默认事件:document.addEventListener(‘touchmove’,function(){},{passive:false}) (在PC端时需注意,用此方式让绑定的touchmove默认事件 - 即滚动事件 先执行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div>
<img id = 'img' src = 'www.baidu.com'/>
</div>
img.onmousemove = function(e){
e.preventDefault()
}
<a href="https://baidu.com" id="oa">百度一下</a>
<!-- 正常跳转 -->
<a href="javascript:;" id="">百度两下</a>
<!-- 禁止页面跳转 -->
<a href="" id="">百度三下</a>
<!-- 刷新页面 -->
<a href="Javascript :void(0);" id="">百度四下</a>
<!-- 禁止页面跳转 -->
oa.onclick = function (e){e.preventDefault();alert(111)}
阻止a标签这种默认行为

事件传播

  • 事件冒泡
    • 0级事件是在冒泡阶段触发的
  • 阻止冒泡:e.stopPropagation||e.cancelBubble = true
  • 事件绑定

  • 绑定分为DOM0级事件绑定 和 DOM2级事件绑定
    • 是按照绑定的顺序执行方法
    • 低版本IE浏览器会乱序
  • DOM0级事件绑定

    传统的事件绑定
    odiv.onclick=function
    问题 : DOM0级事件绑定 对同一元素,同一事件绑定多个行为时,后面的行为会覆盖前面的行为,最终只执行最后一次绑定的行为

  • DOM2级事件绑定

    较于0级事件绑定,优点是可以绑定多个方法
    第一个参数 事件类型
    第二个参数 事件绑定行为
    第三个参数 事件传播的方式
    oiv.addEventListener(“click”,function ( ) {alert(1)},false);
    true捕获阶段触发 false在冒泡阶段触发

  • DOM0 和 DOM2 在事件绑定上的区别
    • 1.机制不一样
      • dom0采用的是给私有属性赋值,所以只能绑定一个方法
      • dom2采用的是事件池机制,所以能绑定多个不同的方法
    • 2.移除的操作
      • box.onclick = null dom0移除
      • dom2 在移除的时候,必须清楚要移除哪一个方法,才能在事件池中移除,所以基于DOM2做事件绑定,我们呢要有“瞻前顾后”的思路,也就是绑定的时候考虑一下如何移除(技巧:不要绑定匿名函数,都绑定实名函数)
    • 3.DOM2事件绑定增加了一些DOM0无法操作的事件行为,例如:DOMContentLoaded事件,(当页面中的HTML结构加载完后才能就会触发执行)

IE低版本单独拿出来

IE低版本浏览器绑定方式 IE 6 ~ 8 DOM2级事件绑定
odiv.attachEvent(“onclick”,function () {alert(666)})
IE 低版本浏览器移除绑定
odiv.detachEvent(“onclick”,function () {alert(666)})

DOM事件绑定移除

  • DOM0级事件移除:odiv.onclick=null
  • DOM2级事件移除 odiv.removeEventListener(“click”,function () {alert(1)},false);移除
    1
    2
    3
    /*var odiv=document.getElementById('div1')
    odiv.onclick=function (e) {
    }*/

事件对象 (e)浏览器天生存在的

浏览器记录了事件相关的信息

  • clientX 到窗口左边的距离 clientY 到窗口上边的距离
  • pageX 到文档左边的距离 pageY 到文档上边的距离
  • pageY相当于clientY+(document.documentElement.scrollTop||document.body.scrollTop)
  • type 事件类型
  • target 事件源 也就是事件绑定的元素
  • preventDefault 阻止默认行为 IE低版本浏览器 retuenValue=true
  • stopPropagation 阻止冒泡 IE低版本浏览器 cancelBubble=true
  • IE6~8用Window.event 接收事件对象 e = e || Window.event

事件委托

一个容器中,有很多后代元素的点击行为都要处理一些事情,之前的思路是把需要操作的元素一一获取,然后再一一做事件绑定,在不同的方法中完成不同的需求,现在不用了,基于事件的冒泡传播机制,我们可以只给容器的Click绑定一个方法,这样不管以后点击的容器中的哪一个后代元素,都会通过事件的冒泡传播机制,把容器的Click行为触发,把绑定的方法执行,我们在方法执行的时候,根据事件对象中的事件源(e.target)来做不同的业务处理即可,这种机制既是事件委托机制
1)容器中很多后代元素的某个行为要进行操作,委托给容器处理是不错的选择
2)元素是动态绑定的
3)需求是除了xxx,剩下的操作都是干同样的事情业务(此时把点击行为的操作委托给BODY,事件源是xxx做什么,不是同一做什么)
………..


原生拖拽

拖放的流程:选中 == > 拖动 == > 释放

选中过程:

在HTML5标准中,为了使元素可拖动,把draggable属性设置为true。文本、图片和链接是默认可以拖放的,它们的draggable属性自动被设置成了true。
图片和链接按住鼠标左键选中,就可以拖放。
文本只有在被选中的情况下才能拖放。如果显示设置文本的draggable属性为true,按住鼠标左键也可以直接拖放。
draggable属性:设置元素是否可拖动。

  • 语法:
    1
    2
    3
    4
    <element draggable="true | false | auto" >
    true: 可以拖动
    false: 禁止拖动
    auto: 跟随浏览器定义是否可以拖动
拖动过程:
  • 每一个可拖动的元素,在拖动过程中,都会经历三个过程,拖动开始 ==>拖动过程中 ==> 拖动结束
  • dragenter和dragover事件的默认行为是拒绝接受任何被拖放的元素。因此,我们必须阻止浏览器这种默认行为。e.preventDefault()
针对对象 事件名称 说明
被拖动的元素 dragstart 在元素开始被拖动时候触发
drag 在元素被拖动时反复触发
dragend 在拖动操作完成是触发
目的地对象 dragenter 当被拖动元素进入目的地元素所占据的屏幕空间时触发
dragover 当被拖动元素在目的地元素内时触发
dragleave 当被拖动元素没有放下就离开目的地元素时触发
释放过程:
  • 到达目的地之后,释放元素事件
针对对象 事件名称 说明
目的地对象 drop 当被拖动元素在目的地元素里放下是触发,一般需要取消浏览器的默认行为

发布订阅模式(观察者模式)

  • 思想:准备一个容器,把达到指定时间点要处理的事情,事先一一的增加到容器中(发布计划,并且向计划表中订阅方法),当到达指定时间点,通知容器中的方法依次执行即可
    1
    2
    3
    4
    5
    6
    7
    8
    let $plan = $.Callbacks()// 创建一个空的计划表 空容器 => $plan
    setTimeout(function (){
    $plan.fire(10,20)//=>fire 就是通知容器中的方法按照顺序依次执行的:
    1020是执行容器中每一个方法的时候,都会给他们出阿迪两个参数值
    },1000)
    $plan.add((x,y)=>{...})//=>add是向容器中增加方法,remove是从容器中移除方法
    $plan.add((x,y)=>{...})
    $plan.add((x,y)=>{...})

bind源码

  • 利用形成的不销毁的栈内存,用来存值及保护变量不受全局的污染
  • 外层套个函数用来存储我们以后需要的值,return一个匿名函数,编程思想这种编程思想我们称作柯理化函数bianc
    `
    Function.prototype.mybind = function mybind (context,…arg){
    let _this = this
    return function anonymous(…innerArg){
          _this.apply(obj,arg.concat(innerArg))
    }
    
    }
    document.body.onclick = fn.mybind(obj,10,20)
-------------本文结束感谢您的阅读-------------