事件高级
1.注册事件
给元素添加事件,称为注册事件或者绑定事件。
注册事件有两种方式:传统方式和方法监听注册方式
1.1 传统注册方式
- 利用 on开头的事件onclick
- <button οnclick= “alert(hi~)”
- btn.onclick = function() {};
- 特点: 注册事件的唯一性
- 同一个元素同一个事件只能设置一个处理函数。最后注册的处理函数将会覆盖前面注册的处理函数
1.2 方法监听注册方式
- w3c 标准推荐方式
- addEventListener() 它是一个方法
- IE9 之前的IE不支持此方法,可使用attachEvent()代替
- 特点: 同一个元素同一个事件可以注册多个监听器
- 按注册顺序依次执行
addEventListener事件监听方式
eventTarget . addEventListener (type, listener[,useCapture] )
eventTarget . addEventListener ()方法将指定的监听器注册到eventTarget (目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。
该访法接收三个参数:
- type :事件类型字符串,比如click、mouseover ,注意这里不要带on
- listener :事件处理函数,事件发生时,会调用该监听函数
- useCapture :可选参数,是一个布尔值,默认是false。学完DOM事件流后,我们再进一步学习
attachEvent事件监听方式(了解)
eventTa rget . attachEvent (eventNameWi thon, callback)
2.删除事件(解绑事件)
2.1 传统注册方式
eventTarget. onclick = null ;
2.2 方法监听注册方式
eventTarget. removeEventListener (type, listener [,useCapture]) ;
3.DOM事件流
事件流描述的是从页面中接收事件的顺序。
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
都会得到点击,但不一定有监听事件
注意
- JS代码中只能执行捕获或者冒泡其中的一个阶段。
- onclick 和attachEvent 只能得到冒泡阶段。
- addEventListener (type, listener [, useCapture] )
第三个参数如果是true ,表示在事件捕获阶段
调用事件处理程序;如果是false (不写默认就是false) , 表示在事件冒泡阶段
调用事件处理
程序。 实际开发中我们很少使用事件捕获,我们更关注事件冒泡
。有些事件是没有冒泡的,比如onblur、 onfocus、onmouseenter、onmouseleave
事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件,我们后面讲解。
捕获阶段:
冒泡阶段:
4.事件对象
1.event就是一个事件对象写到我们侦听函数的小括号里面当形参来看
2.事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
3.事件对象是我们事件的一系列相关数据的集合,跟事件相关的,比如:鼠标点击
里面就包含了鼠标的相关信息,鼠标坐标啊,如果是键盘事件
,里面就包含的键盘事件的信息比如判断用户按下了那个键
4.这个事件对象我们可以自己命名比如event、evt、e
5.事件对象也有兼容性问题ie678通过window. event 兼容性的写法 e = e||window.event;
4.1 常见事件对象属性和方法
事件对象属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象 标准 |
e.srcElement | 返回触发事件的对象 非标准 ie6-8使用 |
e.type | 返回事件的类型比如click mouseover 不带on |
e.cancelBubble | 该属性阻止冒泡 非标准 ie6-8使用 |
e.returnValue | 该属性阻止默认事件(默认行为) 非标准 ie6-8使用比如不让链接跳转 |
e.preventDefault() | 该方法阻止默认事件(默认行为) 标准 比如不让链接跳转 |
e.stopPropagation() | 阻止冒泡 标准 |
e.target
e.type
e.preventDefault()
5.阻止事件冒泡
- 标准写法:利用事件对象里面的stoppropagation()方法
6.事件委托(代理、委派)
事件冒泡本身的特性,会带来的坏处,也会带来的好处,需要我们灵活掌握。
点击每个li都会弹出对话框,以前需要给每个i注册事件,是非常辛苦的,而且访问DOM的次数越多,这就
会延长整个页面的交互就绪时间。
事件委托的原理
不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
以上案例:给ul注册点击事件,然后利用事件对象的target来找到当前点击的Ii ,因为点击Ili,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器。
事件委托的作用
我们只操作了一次DOM ,提高了程序的性能。
7.常用鼠标事件
event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象
MouseEvent和键盘事件对象Keyboa rdEvent。
7.1 鼠标事件对象
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 |
e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 |
e.pageX | 返回鼠标相对于文档页面的X坐标 IE9+支持 |
e.pageY | 返回鼠标相对于文档页面的Y坐标 IE9+支持 |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
e.clientX和e.clientY
7.2 禁止鼠标右键
contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
document . addEventListener ( ‘contextmenu’, function(e) {
e. preventDefault () ;
})
7.3 禁止鼠标选中( selectstart开始选中)
document. addEventListener (’ selectstart’,function(e) {
e. preventDefault () ;
})
案例:跟随鼠标小天使
①鼠标不断的移动,使用鼠标移动事件: mousemove
②在页面中移动,给document注册事件
③图片要移动距离,而且不占位置,我们使用绝对定位即可
④核心原理:每次鼠标移动,我们都会获得最新的鼠标坐标,把这个x和y坐标做为图片的
top和left值就可以移动图片
效果:
代码:
<!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>
img {
position: absolute;
}
</style>
</head>
<body>
<img src="imag/angel.gif" alt="" />
</body>
<script type="text/javascript">
var pic = document.querySelector('img');
document.addEventListener('mousemove', function (e) {
var x = e.pageX;
var y = e.pageY;
console.log('x坐标是' + x + 'y坐标是' + y);
pic.style.left = x - 40 + 'px';
pic.style.top = y - 40 + 'px';
});
</script>
</html>
8.常用键盘事件
事件除了使用鼠标触发,还可以使用键盘触发。
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发 但是它不识别功能键比如ctrl shift箭头等 |
onkeyup、onkeydown、onkeypress(document.addEventListener表示给整个文档添加)
三个事件的执行顺序keydown——keypress——keyup
8.1 键盘事件对象
键盘事件对象 属性 | 说明 |
---|---|
keyCode | 返回该键的ASCII值 |
注意: onkeydown和 onkeyup不区分字母大小写, onkeypress区分字母大小写
在我们实际开发中,我们更多的使用keydown和keyup,它能识别所有的键(包括功能键)
Keypress不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值
案例:模拟京东按键输入内容
①核心思路:检测用户是否按下了s键,如果按下s键,就把光标定位到搜索框里面
②使用键盘事件对象里面的keyCode判断用户按下的是否是s键
③搜索框获得焦点:使用js里面的focus0方法
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input type="text" />
<script>
var inpt = document.querySelector('input');
//此处不用keydown,因为设置keydown事件后,键盘按下会有内容
document.addEventListener('keyup', function (e) {
if (e.keyCode == 83) {
inpt.focus();
}
});
</script>
</body>
</html>
案例:模拟京东快递单号查询
①快递单号输入内容时,上面的大号字体盒子( con )显示(这里面的字号更大)
②表单检测用户输入:给表单添加键盘事件
③同时把快递单号里面的值( value )获取过来赋值给con盒子( innerText )做为内容
④如果快递单号里面内容为空,则隐藏大号字体盒子(con)盒子
效果:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.search {
position: relative;
width: 178px;
margin: 100px;
}
.con {
/* 先隐藏 */
display: none;
position: absolute;
top: -40px;
width: 171px;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
padding: 5px 0;
font-size: 18px;
line-height: 20px;
color: #333;
}
.con::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 28px;
left: 18px;
border: 8px solid #000;
border-style: solid dashed dashed;
border-color: #fff transparent transparent;
}
</style>
</head>
<body>
<div class="search">
<div class="con">123</div>
<input type="text" placeholder="请输入您的快递单号" class="jd" />
</div>
<script>
var div = document.querySelector('.con');
var jd_input = document.querySelector('input');
jd_input.addEventListener('keyup', function () {
if (this.value == '') {
div.style.display = 'none';
} else {
div.style.display = 'block';
div.innerHTML = this.value;
}
});
</script>
</body>
</html>