JS 事件基础

事件基础

1.什么是事件

事件分为两部分:

  • 行为本身: 浏览器天生就赋予其的行为, onclick、onmouseover(onmouseenter)、onmouseout(onmouseleave)、onmousemove、onmousedown、onmouseup、onmousewheel(鼠标滚轮滚动行为)、onscroll(滚动条滚动行为)、onresize(window.onresize浏览器窗口大小改变事件)、onload、onunload(浏览器关闭)、onfocus(文本框获取焦点行为)、onblur(文本框失去焦点)、onkeydown、onkeyup, 哪怕没有给上述的行为绑定方法, 事件也是存在的,当点击盒子的时候,同样会触发它的onclick行为,只是什么事情都没做而已。
  • 事件绑定:给元素的某一个行为绑定方法, 当我们触发事件行为时,会把绑定的函数执行。
element.event = ()=>{}

DOM0级事件绑定

addEventListener

DOM2级事件绑定

element.addEventListener这个属性是定义在当前元素所属EventTarget这个类的原型上的

事件对象及兼容处理

onclick的e

e: MouseEvent,鼠标事件对象:
它是一个对象数据类型值,里面包含了很多的属性名和属性值,这些都是用来记录当前鼠标的相关信息的。

原型链:
MouseEvnet -> UIEvent -> Event -> Object

MouseEvent记录的是页面中唯一一个鼠标每一次触发时候的相关信息,和到底是在那个元素上触发的没有关系

属性值

e.type: 存储的是当前鼠标触发的行为类型“click”

e.clientX / e.clientY: 当前鼠标触发点距离当前屏幕左上角的距离

e.taget: 事件源,当前鼠标触发的是那个元素,那么它存储的就是那个元素,但是在IE6~8中不存在这个属性(e.tager的值是undefined),我们使用e.srcElement来获取事件源
e.clientX/clinetY:

e.pageX/pageY:当前鼠标触发点距离body左上角(页面第一屏幕最左上端)的x/y轴的坐标,但是在IE6~8中没有这个属性,我们通过使用clientY+滚动条卷去的高度来获取也可以

e.preventDefault: 组织浏览器的默认行为

e.currentTarget获取的是绑定事件的元素, 虽然点击的是ul的子元素li, 但是currentTarget获取的是ul

关于事件对象MouseEvent的兼容问题

事件对象本身的获取存在兼容问题:标准浏览器中是浏览器给方法传递的参数,我们只需要定义形参e就可以获取到;在IE6-8中浏览器不会给方法传递参数,我们如果需要的话,需要到window.evnet中查找

e = e || window.event;

e.target = e.target || e.srcElement;

e.pageX = e.pageX || (e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft))

e.pageY = e.pageY || (e.clientY + (document.documentElement.scrollTop || document.body.scrollTop))

onkeyup

keyboardEvent:

e.keyCode: 按下的键值,当前键盘上每一个键对应的值

事件的传播机制

事件的默认传播机制:

  • 捕获阶段:从外向内依次查找元素
  • 目标阶段:当前事件源本身的操作
  • 冒泡阶段:从内到外依次触发相关的行为

DOM0级事件绑定:
使用DOM0级事件绑定给元素的某一个行为绑定的方法, 都是在冒泡阶段执行的

addEventListener绑定:
第一个参数是行为类型,第二个参数是给当前的行为绑定方法,第三个参数是是否在捕获阶段发送,false在冒泡阶段发生

每个浏览器传播的最顶层是不一样的,谷歌中可以传播到document,但是在IE中只能传播到html

事件委托/事件代理

利用事件的冒泡传播机制,触发当前元素的某个行为,它父级所有元素的相关行为都会被触发,如果一个容器中有很多元素都要绑定点击事件,我们没有必要一个个的绑定,只需要给最外层容器绑定一个点击事件即可,在这个方法执行的时候,通过事件源的区分来进行不同的操作。

document.body.onclick?=?function?(e)?{
??????e?=?e?||?window.event;
??????var?target?=?e.target?||?e.srcElement;
??????console.log(target.id);
??????if?((target.id?=?"box"))?{
????????//?...
??????}?else?if?((target.id?=?"mark"))?{
????????//?...
??????}?else?{
????????//?...
??????}
????};
实现下拉输入框
<!--
?*?@Author:?lemon
?*?@Date:?2020-09-17?12:45:53
?*?@LastEditTime:?2020-09-17?13:27:23
?*?@LastEditors:?Please?set?LastEditors
?*?@Description:?In?User?Settings?Edit
?*?@FilePath:?\React前端准备\事件\百度搜索框.html
-->
<!DOCTYPE?html>
<html?lang="en">
??<head>
????<meta?charset="UTF-8"?/>
????<meta?name="viewport"?content="width=device-width,?initial-scale=1.0"?/>
????<title>Document</title>
????<style?type="text/css">
??????*?{
????????margin:?0;
????????padding:?0;
????????font-family:?"微软雅黑";
??????}
??????input?{
????????display:?block;
????????outline:?none;
??????}
??????a?{
????????display:?block;
????????text-decoration:?none;
????????color:?#000;
??????}
??????a:hover,
??????a:active,
??????a:target?{
????????text-decoration:?none;
????????color:?#000;
??????}
??????ul,
??????li?{
????????list-style:?none;
??????}
??????#box?{
????????position:?absolute;
????????top:?20px;
????????left:?50%;
????????margin-left:?-250px;
????????width:?500px;
??????}
??????#box?input?{
????????padding:?0?10px;
????????height:?35px;
????????border:?1px?solid?#008000;
??????}
??????#box?ul?{
????????display:?none;
????????position:?relative;
????????top:?-1px;
????????border:?1px?solid?#008000;
??????}
??????#box?ul?li,
??????#box?ul?li?a?{
????????height:?30px;
????????line-height:?30px;
??????}
??????#box?ul?li?a?{
????????padding:?0?10px;
??????}
??????#box?ul?li?a:hover?{
????????background:?#ccc;
??????}
????</style>
??</head>
??<body>
????<div?id="box">
??????<input?id="searchInput"?type="text"?/>
??????<ul?id="searchList">
????????<li><a?href="javascript:;">lemon</a></li>
????????<li><a?href="javascript:;">Lemon</a></li>
????????<li><a?href="javascript:;">柠檬</a></li>
????????<li><a?href="javascript:;">lemon-Xu</a></li>
????????<li><a?href="javascript:;">Lemon-Xu</a></li>
??????</ul>
????</div>
????<script?type="text/javascript">
??????var?searchInput?=?document.getElementById("searchInput");
??????var?searchList?=?document.getElementById("searchList");
??????searchInput.onfocus?=?searchInput.onkeyup?=?function?(e)?{
????????var?val?=?this.value.replace(/(^?+?|?+$)/g,?"");?//?获取文本框的内容并且去除他的首位空格
????????searchList.style.display?=?val.length?>?0???"block"?:?"none";
??????};
??????var?box?=?document.getElementById("box");
??????document.onclick?=?function?(e)?{
????????e?=?e?||?window.event;
????????e.target?=?e.target?||?e.srcElement;
????????console.log(searchList.style.display);
????????//?如果事件源是#searchList下的a标签,?我们让searchList隐藏,?并且把当前点击这个a中的内容放到文本框中
????????if?(
??????????e.target.tagName.toLowerCase()?===?"a"?&&
??????????e.target.parentNode.parentNode.id?===?"searchList"
????????)?{
??????????searchList.style.display?=?"none";
??????????searchInput.value?=?e.target.innerHTML;
??????????console.log(searchList.style.display);
??????????return;
????????}
????????searchList.style.display?=?"none";
????????console.log(searchList.style.display);
??????};
??????//???我们可以阻止一个容器中某些特殊性元素,?让其不在委托的范围内,?只需要把这些不需要委托的阻止冒泡传播即可
??????searchInput.onclick?=?function?(e)?{
????????e?==?e?||?window.event;
????????e.stopPropagation???e.stopPropagation()?:?(e.cancelBubble?=?true);
??????};
????</script>
??</body>
</html>

JS 事件基础

上一篇:CSS基础4--冲突和继承


下一篇:记录项目中针对单个模块(div)爆光统计--js封装