文章目录
1. 事件高级
1.1 注册事件
1.1.1 注册事件概述
- 给元素添加事件,称为注册事件
- 注册事件有两种方式:传统方式和方法监听注册方式
1.1.1.1 传统注册方式
- 事件为on开头,如onclick
- 注册事件具有唯一性,后注册的函数会把先注册的覆盖
<body>
<button id="btn1">tradition</button>
<script>
var btn1 = document.querySelector('#btn1');
btn1.onclick = function () {
alert('hi');
};
btn1.onclick = function () {
alert('how are u')
};
// => alert('how are u')
</script>
</body>
1.1.1.2 方法监听注册方式
- w3c标准,同一个元素可以注册多个监听器,按注册顺序执行
- ie9前用attachEvent()代替
- eventTarget.addEventListener(type, listener, useCapture)
- type: 事件类型,click, mouseover…
- listener: 事件处理函数,事件发生时会调用该监听函数
- useCapture: 可选参数,布尔类型
<body>
<button id="btn2">standard</button>
<script>
var btn2 = document.querySelector('#btn2');
btn2.addEventListener('click', function () {
alert('hi');
})
btn2.addEventListener('click', function () {
alert('how are u');
})
// => alert('hi') alert('how are u')
</script>
</body>
1.2 删除事件
1.2.1 传统方式
- eventTarget.onclick = null
1.2.2方法监听方式
- eventTarget.removeEventListener(type, listener, useCapture)
- eventTarget.detachEvent(eventName, callback) (兼容ie9以前)
<body>
<button>button</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', f);
function f() {
alert('you click me');
btn.removeEventListener('click',f)
}
</script>
</body>
1.3 DOM事件流
-
事件流描述从页面接收事件的顺序
-
事件发生时会在元素节点之间按照特定的顺序传播,这个过程叫DOM事件流
-
比如给一个div注册点击事件,DOM事件流分为三个阶段
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
-
事件冒泡:事件由最具体元素接收,然后逐级向上传播到DOM最顶层节点的过程
-
事件捕获: 由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接收的过程
-
js代码只能执行捕获/冒泡其中一个阶段
-
addEventListener(type, listener, useCapture) 第三个参数如果是true,在事件捕获阶段调用事件处理程序,如果是false,在事件冒泡阶段调用处理程序
扫描二维码关注公众号,回复: 12006373 查看本文章 -
onclick, attachEvent 只能得到冒泡阶段
<body>
<div class="father">
<div class="son">click me</div>
</div>
<script>
var father = document.querySelector('.father');
var son = document.querySelector('.son');
father.addEventListener('click', function () {
alert('father');
}, true)
son.addEventListener('click', function () {
alert('son');
}, true)
father.addEventListener('click', function () {
alert('father');
})
son.addEventListener('click', function () {
alert('son');
})
document.addEventListener('click', function () {
alert('document')
})
// => alert father son son father document
</script>
</body>
1.4 事件对象
1.4.1 事件对象概述
- event对象代表事件的状态,比如键盘按键的状态,鼠标的位置,鼠标按钮的状态
- 事件对象发生后,跟事件相关的一系列数据合集都放在这个对象里面,比如绑定事件的元素,鼠标位置,键盘按键是哪一个按键
1.4.2 事件对象的使用
- 事件对象由系统创建,不需要传递参数
- 事件对象写到监听函数的小括号里,当作形参
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
height: 66px;
width: 66px;
background-color: #ff2235;
}
</style>
</head>
<body>
<div class="box" id="box1">123</div>
<div class="box" id="box2">456</div>
<script>
var box1 = document.querySelector('#box1');
var box2 = document.querySelector("#box2");
box1.onclick = function (e) {
console.log(e);
}
// => MouseEvent {isTrusted: true, screenX: 56, screenY: 141, clientX: 56, clientY: 38, …}
box2.addEventListener('click', function (e) {
console.log(e);
})
// => MouseEvent {isTrusted: true, screenX: 41, screenY: 215, clientX: 41, clientY: 112, …}
</script>
</body>
1.4.3 兼容性写法
- ie678不支持直接log(e)的写法
- 解决方法:
e = e || window.event;
1.4.4 事件对象的常用属性
- e.target 返回触发事件的对象
- e.target和this的区别:e.target返回的是触发事件的元素,this返回的是绑定事件的对象
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
width: 66px;
height: 66px;
background-color: #ff2a58;
}
</style>
</head>
<body>
<div class="box">123</div>
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
console.log(e.target); // => <li>abc</li>
console.log(this); // => <ul><li>abc</li><li>abc</li><li>abc</li></ul>
})
</script>
</body>
- e.preventDefault() 阻止默认事件,比如不让链接跳转或让提交按钮失效
- DOM 标准写法
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="http://www.baidu.com">百度</a>
<script>
var a = document.querySelector('a');
a.addEventListener('click', function (e) {
e.preventDefault();
})
</script>
</body>
- e.stopPropagation() 阻止冒泡
- IE678利用事件对象的cancelBubble属性 来阻止冒泡
- e.cancelBubble = true
<body>
<div class="father">
<div class="son">click me</div>
</div>
<script>
var father = document.querySelector('.father');
var son = document.querySelector('.son');
father.addEventListener('click', function () {
alert('father');
})
son.addEventListener('click', function (e) {
alert('son');
e.stopPropagation();
})
document.addEventListener('click', function () {
alert('document')
})
// => alert son 不再向上冒泡
</script>
</body>
1.4.5 事件委托
- 假如要给很多个并列的元素添加事件,为了少访问DOM,提高性能,要用上事件委托
- 事件委托原理:给父节点添加监听器,用事件冒泡影响每一个子节点
- 下例中:点击li冒泡给ul,ul点击事件触发里面的内容
<body>
<ul>
<li>li1</li>
<li>li2</li>
<li>li3</li>
<li>li4</li>
<li>li5</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
e.target.style.backgroundColor = "black";
})
</script>
</body>
1.4.6 常用的鼠标事件
1.4.6.1常用的鼠标事件
- onclick 鼠标点击左键触发
- onmouseover 鼠标经过
- onmouseout 鼠标离开触发
- onfocus 获得鼠标焦点触发
- onmousemove 鼠标移动触发
- onmouseup 鼠标弹起触发
- onmousedown 鼠标按下触发
1.4.6.2 鼠标事件对象
e.clientX
e.clientY
坐标原点是浏览器的左上角e.pageX
e.pageY
坐标原点是当前页面的左上角,距离页面的最左上角多远就是哪个坐标,IE9+支持e.screenX
e.screenY
坐标原点是当前显示器屏幕的左上角
1.4.7 常用键盘事件
1.4.7.1 常用键盘事件
- onkeyup 键盘松开时触发 (可识别功能键)
- onkeydown 键盘按下时触发
- onkeypress 键盘松开时触发 (不能识别功能键)
- 事件执行顺序:keydown -> keypress -> keyup
<body>
<script>
document.addEventListener('keypress', function () {
console.log('keypress触发');
})
document.addEventListener('keydown', function () {
console.log('keydown触发');
})
document.addEventListener('keyup', function () {
console.log('keyup触发');
})
</script>
</body>
1.4.7.2 键盘事件对象
Listener(‘keypress’, function () {
console.log(‘keypress触发’);
})
document.addEventListener(‘keydown’, function () {
console.log(‘keydown触发’);
})
document.addEventListener(‘keyup’, function () {
console.log(‘keyup触发’);
})
[外链图片转存中…(img-s7W8uqHv-1602077884794)]
1.4.7.2 键盘事件对象
- e.keyCode 获得所按下键的ASCII码(十进制)