1. 注册事件
1.1 注册事件的两种方式:
- 传统方式注册事件
- 使用on开头
- 兼容性较好
- 同一元素只能绑定一个处理函数,后面的会覆盖前面的处理函数
var btn = document.querySelectorAll('button');
//传统方式
btn[0].onclick = function(){
alert('1');
}
- 事件侦听注册事件
- 使用addEventListener()方法添加,使用removeEventListener()删除
- IE9之前版本不兼容
- 可同时注册多个事件处理程序,按照添加顺序触发
1.2 addEventListener() 方法
eventTarget.addEventListener(type, listener[, useCapture])
该方法接收三个参数:
- type : 事件类型字符串,比如click、mouseover,注意这里不带on,是字符串,带引号
- listener : 事件处理函数,事件发生时,会调用该监听函数
- useCapture : 可选函数,是一个布尔值,默认是false ,表示在冒泡阶段调用事件处理程序;若为true,表示在事件捕获阶段调用事件处理程序。
var btn = document.querySelectorAll('button');
//事件侦听
btn[1].addEventListener('click', function(){//不带on,是字符串,带引号
alert('1');
})
//可同时注册多个事件处理程序
btn[1].addEventListener('click', function(){
alert('2');
})
1.3 attachEvent()事件监听方式(了解)
eventTarget.attackEvent(eventNameWithon, callback)
eventTarget.attackEvent方法将指定的监听器注册到eventTarget 上,当该对象触发指定的事件时,指定的回调函数将会被执行。
该方法接收两个参数:
- ventNameWithon : 事件类型字符串,比如onclick,
onmouseover, 这里要带on - callback : 事件处理函数,当目标触发事件时回调函数将被调用
1.4 注册事件的兼容性解决方案
<button>点击我</button>
<script>
var btn = document.querySelector('button');
function alertWarn () {
alert ('warning');
}
function addEventListener(element, eventName, fn) {
//判断浏览器是否支持addEventListener方法
if (element.addEventListener) {
element.addEventListener (eventName, fn); //第三个参数,默认是false
} else if (element.attachEvent) {
element.attachEvent ('on' + eventName, fn);
} else {
//相当于element.onclick = fn;
element['on' + eventName] = fn;
}
}
addEventListener(btn, 'click', alertWarn);
</script>
2. 删除事件
2.1 删除事件的方式
- 传统方式
eventTarget.onclick = null;
btn[0].onclick = function(){
alert('1');
btn[0].onclick = null;
}
- removeEventListener()删除事件
btn[1].addEventListener('click', fn)// 里面的fn不需要加小括号
function fn(){
alert('2');
btn[1].removeEventListener('click', fn);
}
3. 事件流
事件流描述的是从页面接收事件的顺序,事件流分为三个阶段
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段
- 事件冒泡由IE最先提出,事件开始由最具体的元素接收,然后逐级向上传播到较为不具体的节点
- 事件捕获由网景公司最先提出,由DOM最顶层开始,然后逐级向下传播到最具体的元素接收的过程
注意:
- JS代码只能执行捕获或者冒泡其中的一个阶段
- onclick 和 attachEvent 只能得到冒泡阶段
- addEventListener (type, listener[, useCapture]) 第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认就是false),表示在事件冒泡阶段电泳事件处理程序。
- 在实际开发中,我们很少使用事件捕获,我们更关注事件冒泡
- 有些事件是没有冒泡的,比如onblur、onfocus、onmouseover、onmouseleave
- 虽然事件冒泡有时候会带来麻烦,但是有时候又会巧妙的做某些事情,我们后面讲解
4. 事件对象
eventTarget.onclick = function(event){};
eventTarget.addEventListener('click', function(event){})
- 其中,event 就是一个事件对象,写到侦听函数的小括号里面,当形参来看
- 事件对象只有有了事件才会存在,他是系统给我们自动创建的,不需要我们传递参数
- 事件对象是我们的事件的一系列相关数据的集合,比如鼠标点击里面就包含了鼠标的相关信息
- 这个事件对象我们可以自己命名,比如 event、evt 、e 等
- 事件对象也有兼容性问题。 IE 6、7、8通过 window.event 实现,解决方法:event = event || 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.stopPropageation() | 该方法阻止默认冒泡(标准) |
4.2 e.target与this
this 返回的是绑定事件的对象(元素)
e.target 返回的是触发了这个事件
<body>
<div>123</div>
<ul>
<li>123</li>
<li>123</li>
<li>123</li>
</ul>
<script>
var div = document.querySelector('div');
div.addEventListener('click', function(e){
console.log(e.target);//<div>123</div>
console.log(this);//<div>123</div>
});
var ul = document.querySelector('ul');
//给ul绑定事件,this指向ul
ul.addEventListener('click',function(e){
//点击的是ul,所以e.target指向li
console.log(e.target);//<li>123</li>
console.log(this);//<ul>...</ul>
});
</script>
</body>
4.3 阻止对象默认行为
阻止对象默认行为的三种方法:
- 普通浏览器使用e.preventDefault()方法
- IE6~8使用e.returnValue属性
- return false
- 没有兼容性问题
- 后面语句不执行
- 只限于传统注册事件方式
var a = document.querySelector('a');
// a.addEventListener('click',function(e){
// e.preventDefault();
// });
a.onclick = function(e){
// e.preventDefault();
//ie6~ie8使用e.returnValue
//e.returnValue;
return false;
}
5. 阻止事件冒泡
阻止冒泡的两种方式
e.stopPropagation(); // 一般浏览器停止冒泡
e.cancelBubble; // IE 6 7 8 的停止冒泡
<script>
var father = document.querySelector('.father');
var son = document.querySelector('.son');
father.addEventListener('click',function(){
alert('father');
},false);
son.addEventListener('click', function(e){
e.stopPropagation();//一般浏览器停止冒泡
// e.cancelBubble;//IE 6 7 8 的停止冒泡
alert('son');
},false);
</script>
6. 事件委托
6.1 事件委托原理
不给每个子节点单独设置事件监听器,而是设置在其父节点上,然后利用冒泡原理设置每个子节点。
例如: 给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li ,然后事件冒泡到 ul 上, ul 有注册事件,就会触发事件监听器。
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e){
e.target.style.backgroundColor = 'skyblue';
}, false);
6.2 事件委托的作用
只操作了一次 DOM ,提高了程序的性能。
7. 常用鼠标事件
7.1 常用鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
7.2 鼠标事件对象
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对于浏览器窗口可视区域的X坐标 |
e.clientY | 返回鼠标相对于浏览器窗口可视区域的Y坐标 |
e.pageX | 返回鼠标相对于文档页面的X坐标 IE9+ 支持 |
e.pageY | 返回鼠标相对于文档页面的Y坐标 IE9+ 支持 |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
案例:跟随鼠标的天使
分析:
- 鼠标不断的移动,使用鼠标移动事件: mousemove
在页面中移动,所以给 document 注册事件 - 图片要移动距离,而且不占位置,我们使用绝对定位即可
- 核心原理,每次鼠标移动,我们都会获得最新的鼠标坐标,把这个 X 和 Y 的坐标做为图片的 top 和 left 值就可以移动图片
var img = document.querySelector('img');
document.addEventListener('mousemove', function(e){
var x = e.pageX;
var y = e.pageY;
//千万别忘记加上单位px
//若想使图片居中,则还需分别减去图片高度和宽度的一半
img.style.top = y + 'px' ;
img.style.left = x + 'px';
});
8. 常用键盘事件
8.1 常用键盘事件
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发 不识别功能键,如shift,ctrl |
8.2 键盘事件对象
键盘事件对象 属性 | 说明 |
---|---|
keyCode | 返回该键的ASCII码值 |
案例:模拟京东按键输入内容
- 需求:按下s键后,搜索框自动获得焦点
- 分析:
- ·使用键盘事件判断用户是否按下s键
- 搜索框获得焦点,使用focus()方法
var input = document.querySelector('input');
document.addEventListener('keyup', function(e){
if(e.keyCode == 83){
input.focus();
}
});
案例:模拟京东快递单号查询
分析:
-
快递单号输入内容时,上面的大号字体盒子(con)显示
-
同时把快递单号里面的值(value)获取过来赋值给con盒子
-
如果快递单号里面内容为空,则隐藏大号字体盒子(con)
-
失去焦点时,隐藏盒子
-
获得焦点,且内容文本不为空时,显示盒子
注意:keydown和keypress触发时,文字还没落入在文本框中,keyup触发时,文字已经落入文本框
<script>
var con = document.querySelector('.con');
var inp = document.querySelector('input');
inp.addEventListener('keyup', function(){
if(this.value == ''){
con.style.display = 'none';
}else{
con.style.display = 'block';
con.innerText = this.value;
}
})
inp.addEventListener('blur',function(){
con.style.display = 'none';
})
inp.addEventListener('focus', function(){
if(this.value != ''){
con.style.display = 'block';
}
})
</script>
参考资料:
1.黑马程序员pink老师——常用Web APIs教程