给元素绑定事件:元素.事件名 = function(){ }
但是如果给某元素添加和系统同名的事件,在默认情况下,自定义的同名事件不能覆盖系统默认事件。如果想覆盖,需要在自定义的同名事件中添加return false语句
事件
用户和浏览器之间的交互行为。如:点击、移入移出某个元素等
添加事件的三种方式
1.通过 onXXX 的形式添加事件
如:onclick等
注意点:对象.onXXX = function(){} 相当于是给该对象的onXXX属性赋值。如果给同一对象的某onXXX属性多次赋值,后面赋值的会覆盖前面的(只执行最后一次赋值的函数)
<head>
<meta charset="utf-8">
<link href="fonts/iconfont.css" rel="stylesheet">
<script>
window.onload = function () {
let btn = document.querySelector('button');
btn.onclick = function(){
console.log('onclick111')
};
btn.onclick = function(){
console.log('onclick222');
}
}
</script>
</head>
<body>
<button>我是按钮</button>
</body>
2.通过addEventListener方法添加
注意点:多次添加同一事件不会覆盖 + 只支持IE9及以上的浏览器 + 事件名称不用添加on
<head>
<meta charset="utf-8">
<link href="fonts/iconfont.css" rel="stylesheet">
<script>
window.onload = function () {
let btn = document.querySelector('button');
btn.addEventListener('click',function () {
console.log('click111');
});
btn.addEventListener('click',function () {
console.log('click222');
})
}
</script>
</head>
<body>
<button>我是按钮</button>
</body>
3.通过attachEvent方法添加
注意点:多次添加同一事件不会覆盖 + 只支持低级浏览器 + 事件名要添加on
4.兼容各种浏览器:自定义添加事件的方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="fonts/iconfont.css" rel="stylesheet">
<script>
window.onload = function () {
let btn = document.querySelector('button');
addEvent(btn,'click',function () {
console.log('aaaaa');
});
addEvent(btn,'click',function () {
console.log('bbbbb');
})
function addEvent(ele,name,func) {
if(ele.attachEvent){
ele.attachEvent('on'+name,func);
}else{
ele.addEventListener(name,func);
}
}
}
</script>
</head>
<body>
<button>我是按钮</button>
</body>
</html>
事件对象
当事件的响应函数被触发时 浏览器每次都会将一个事件对象作为实参传递给响应函数
在事件对象中封装了当前事件的一切信息 如:鼠标的坐标 键盘的哪个按键被按下 鼠标的滚轮滚动的方向等
注意点:在ie8及以下的浏览器中,将事件对象作为window的一个属性保存。需要考虑不同版本的浏览器的兼容性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="fonts/iconfont.css" rel="stylesheet">
<script>
window.onload = function () {
let btn = document.querySelector('button');
btn.onclick = function (event) {
event = event || window.event;//兼容
console.log(event);
}
}
</script>
</head>
<body>
<button>我是按钮</button>
</body>
</html>
阻止默认行为
- 在事件的最后 return false;(最常用)
- 给事件对象添加preventDefault方法 event.preventDefault();(只适用于IE9及以上浏览器)
- IE8及以下浏览器:event.returnValue = false;
事件执行的三个阶段:捕获 执行 冒泡
-
捕获阶段:从最外层的祖先元素开始捕获,一直到目标元素(从外到内)。
-
当前阶段:事件捕获到目标元素,捕获结束,在目标元素上触发事件。
-
冒泡阶段:事件从目标元素向祖先元素传递,依次触发祖先元素上的相同事件(从内到外)。
-
三个阶段只有两个会被同时执行:要么捕获和当前, 要么当前和冒泡
-
设置事件是捕获:addEventListener()的第三个参数设置为true
-
设置事件是冒泡:addEventListener()的第三个参数设置为false
-
onXXX事件默认都是冒泡
8
冒泡的应用和阻止冒泡
应用:
事件对象event的属性event.target中保存的是当前点击的元素
效果:点击某个li,其背景显示红色。同时清空其他li的背景颜色。
思路:不再通过遍历li数组的形式给li点击onclick事件修改其样式。而是直接给li的父元素ul添加点击事件,获取event.target能得到鼠标点击的li。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="fonts/iconfont.css" rel="stylesheet">
<script>
window.onload = function () {
//以前的做法是先获取到li的数组,对该数组进行遍历,点击到哪个li,给其添加className为current,并将上次点击的li的className删除
// event.target中保存的是当前点击的元素
let ul = document.querySelector('ul');
let preItem = document.querySelector('ul>li:first-child');//初始状态下,第一个li是被选中的状态
ul.onclick = function (event) {
event = event || window.event;//兼容
//console.log(event.target);
preItem.className = '';//清空上次点击的li的样式
let item = event.target; //event.target保存的是当前点击的li
item.className = 'current';
preItem = item;
}
}
</script>
<style>
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
margin: 100px auto;
width: 300px;
border: 1px solid #000000;
}
ul>li{
cursor: pointer;
}
.current{
background-color: red;
}
</style>
</head>
<body>
<ul>
<li class="current">我是第一个li</li>
<li>我是第二个li</li>
<li>我是第三个li</li>
<li>我是第四个li</li>
<li>我是第五个li</li>
</ul>
</body>
</html>
阻止冒泡:
- IE9及以上浏览器:event.stopPropagation()
- IE8及以下浏览器:event.cancelBubble = true;
- 兼容:
oSDiv.onclick = function (event) {
event = event || window.event;
if(event.cancelBubble){
event.cancelBubble = true;
}else{
event.stopPropagation();
}
console.log("son");
}
常用事件
移入事件和移出事件
/*
1.onmouseover和onmouseenter的区别
onmouseover移入到子元素,父元素的移入事件也会被触发
onmouseenter移入到子元素,父元素的移入事件不会被触发
*/
/*
2.onmouseout和onmouseleave的区别
onmouseout移出到子元素,父元素的移入事件也会被触发
onmouseleave移出到子元素,父元素的移入事件不会被触发
*/