事件

作者: 没了提心吊胆的稗子 | 来源:发表于2019-08-07 18:57 被阅读0次

    什么是事件

    事件分为两部分:
    1)行为本身:浏览器赋予的行为(本来就存在的):onclick、onmouseover(onmouseenter)、onmouseout(onmouseleave)、onmousemove、onmousedown、onmouseup、onmousewheel(鼠标滚轮滚动)、onscroll、onresize(window.onresize浏览器窗口大小改变事件)、onload、onunload(浏览器关闭的时候)、onfocus(文本框获取焦点)、onblur(文本框失去焦点)、onkeydown、onkeyup(键盘的按下和抬起)
    2)事件绑定:给元素的某一个行为绑定方法,两种方式:DOM0级事件绑定(例如element.onclick = function(){})DOM2级事件绑定(例如element.addEventListener("click", function(){}, false))

    // 当点击元素的时候这个方法执行
    // 这种方式是定义在当前元素的私有属性上的
    // DOM0级事件绑定
    element.onclick = function(){}
    // same as
    // 这种方式是定义在当前元素的所属EventTarget类的原型上的
    // DOM2级事件绑定
    element.addEventListener("click", function(){}, false);
    

    绑定的时候是把匿名函数当做一个值赋值给元素的行为,当触发行为的时候,这个绑定的方法才会执行,此时浏览器默认地给这个方法传递了一个参数值,以点击行为为例,MouseEvent鼠标事件对象。
    1)它是一个对象数据类型值,里面包含很多方法和属性,都是用来记录当前鼠标相关信息的
    2)MouseEvent--UIEvent--Event--Object
    3)MouseEvent记录的是页面中唯一一个鼠标每次触发时候的相关信息,和到底是哪个元素上触发的没有关系

    事件对象MouseEvent的兼容问题

    1)事件对象本身的获取存在兼容问题,标准浏览器中是浏览器默认传递,只需我们定义形参e即可获取;IE6-8下浏览器不会给方法传递这个参数,若要使用,则需通过window.event获取查找。兼容写法:

    oDiv.onclick = function(e){
     e = e || window.event;
    }
    

    e.clientX/e.clientY:鼠标触发点距离当前屏幕左上角的x/y轴的坐标
    e.pageX/e.pageY:鼠标触发点距离body左上角的x/y轴的坐标,IE6-8没有这个属性,若要计算,则需要e.clientX加上滚动条卷去的宽度/e.clientY加上滚动条卷去的高度

    oDiv.onclick = function(e){
     e.pageX = e.pageX || (e.clientX + ( document.documentElement.scrollLeft || document.body.scrollLeft));
     e.pageY = e.pageY || (e.clientY + ( document.documentElement.scrollTop || document.body.scrollTop));
    }
    

    e.type:存储的是鼠标触发的行为类型
    e.target:事件源,当前鼠标触发的是哪个元素,那么它存储的就是哪个元素。IE6-8下值为undefined,使用e.srcElement获取

    oDiv.onclick = function(e){
     e.target = e.target || e.srcElement;
    }
    

    e.preventDefault:组织浏览器的默认行为,vue中直接在绑定事件时@event.prevent即可
    例如,其他元素的:hover在IE6下不兼容,需要在元素里面嵌套一个a标签来实现,这个时候点击当前元素不想让a标签跳转,就可以使用e.preventDefault来阻止默认的跳转行为。IE6-8没有这个属性,使用e.returnValue=false
    return false也可以;直接在a标签中href="javascript:; href="javascript:void 0;" href="javascript:void 1;"都可以

    oDiv.onclick = function(e){
     e.preventDefault ? e.preventDefault() : e.returnValue=false;
     // same as
     return false;
    }
    

    e.stopPropagation:阻止事件冒泡传播,IE6-8不兼容e.cancleBubble=true

    oDiv.onclick = function(e){
     e.stopPropagation? e.stopPropagation : e.cancleBubble=true;
    }
    

    e.keycode:当前键盘上每个键对应的值
    空格键(space):32
    删除键:8
    回车键(enter):13
    回退键(delete):46
    四个方向键:左37 上38 右39 下40

    事件的默认传播机制

    捕获阶段:从外向里依次查找元素
    目标阶段:当前事件源本身
    冒泡阶段:从内到外依次触发相关行为(最常用的就是冒泡阶段)
    1、使用DOM0级事件绑定给元素的某一个方法,都是在行为触发后的冒泡阶段执行方法的。
    在冒泡阶段,不仅当前元素的行为被触发,他的所有父级元素的行为也会被触发,若父级元素也有绑定方法,这个方法也会执行
    注意:每个浏览器中的最顶层是不一样的,谷歌浏览器中可以传播到document,但IE中只能传播到html。
    2、使用DOM2级事件绑定给元素的某一个方法
    addEventListener三个参数:1.当前行为的类型(如click),2.给当前行为绑定的方法,3.控制在哪个阶段发生true:在捕获阶段;false:在冒泡阶段
    onmouseover/onmouseoutonmouseenter/onmouseleave都是鼠标滑上滑下的效果,区别在于后两者默认阻止了事件冒泡。

    事件委托

    利用事件的冒泡传播机制(触发当前元素的某个行为,他父级所有元素的相关行为都会被触发),如果一个容器中有很多元素都要绑定点击事件,只需要给最外层容器绑定即可,通过事件源的区分来进行不同的操作

    DOM0级和DOM2级事件绑定

    DOM2级事件绑定是让元素通过原型链一直找到EventTarget这个内置类的原型上的addEventListener方法实现的
    1)DOM0级事件绑定:只能给一个元素的某一个行为绑定一此方法,第二次绑定会把第一次的绑定覆盖
    2)DOM0中的行为类型用DOM2一样可以绑定;而且DOM2中还提供了一些DOM0中没有的行为类型,如DOMContentLoaded:当页面中的DOM结构(HTML结构加载完成)出发的行为
    window.onload=function(){}:当页面中的所有资源都加载完成(图片、HTML结构、音视频...)才会执行后面的函数;并且在一个页面中只能用一次,后面再写会把前面的覆盖掉。因为是用DOM0级事件绑定的只能绑定一次
    jQuery:$(document).ready(function(){})当页面中的HTML结构加载完成就可以执行对应的函数;并且在一个页面中可以出现多次。用DOM2级事件绑定的,绑定的行为就是DOM2中新增加的DOMContentLoaded
    loadDOM2级事件绑定就可以执行多次

    window.addEventListener("load", function(){}, false);
    window.addEventListener("load", function(){}, false);
    // 两个不会冲突
    

    3)在解除事件绑定的时候,DOM0级可以直接赋值为null,而DOM2级需要在绑定的时候使用具名函数,removeEventListener来移除(行为本身,方法,哪个阶段发生三个参数必须都有),匿名函数不可以
    4)只能给某个元素的同一个行为绑定多个不同的方法,如果方法相同,只能留一个,当行为触发,会按照绑定的先后顺序依次把绑定好的方法执行,执行的时候方法中的this是当前被绑定事件的元素本身
    事件池:用来存储当前行为绑定的方法的(浏览器自带的机制)
    IE6-8浏览器中不支持addEventListener/removeEventListener,实现DOM2级事件绑定需要用attachEvent/detachEvent,只有两个参数,不能控制函数在哪个阶段执行,默认只在冒泡阶段发生,行为参数需要添加on,和DOM0级事件很类似

    box.attachEvent("onclick", function(){});
    

    和标准浏览器事件池对比:
    1)执行顺序是乱序,标准浏览器事件池中是按绑定顺序依次执行的
    2)不能区分同一个绑定的方法,会重复执行
    3)this不是当前绑定的元素,而是window

    相关文章

      网友评论

          本文标题:事件

          本文链接:https://www.haomeiwen.com/subject/urbwdctx.html