Dom Api之事件

Dom Api之事件

1.绑定事件

比较常用的绑定事件由两种方式,以点击事件为例来看一下,界面搭建:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <title>event</title>
    <style>
        .content-box {
            width: 450px;
            height: 700px;
            background-color: pink;
            margin: 0 auto;
            text-align: center;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <div class="content-box">
        <button>button</button>
        <div class="num">
            0
        </div>
    </div>
</body>

</html>
//获取button
let button = document.querySelector('button');
//获取num盒子
let numDiv = document.querySelector('.num');
//声明点击时要执行的函数
let onClickBtn = function() {
    let num = Number(numDiv.innerText);
    numDiv.innerText = ++num;
}
//绑定点击事件
button.onclick = onClickBtn;

第一种方式,直接通过 element.on事件名 = 事件函数 的方式来绑定事件.

第2种方式,使用element.addEventListener(事件名, 事件函数) 来绑定:

//获取button
let button = document.querySelector('button');
//获取num盒子
let numDiv = document.querySelector('.num');
//声明点击时要执行的函数
let onClickBtn = function() {
    let num = Number(numDiv.innerText);
    numDiv.innerText = ++num;
}
//绑定点击事件
button.addEventListener('click', onClickBtn);

不同的是,通过onclick赋值绑定的话只能绑定一个点击事件,而通过addEventListener可以绑定多个点击事件:

//获取button
let button = document.querySelector('button');
//获取num盒子
let numDiv = document.querySelector('.num');
//声明点击时要执行的函数
let onClickBtn = function() {
    let num = Number(numDiv.innerText);
    numDiv.innerText = ++num;
}
//绑定点击事件
button.addEventListener('click', onClickBtn);

let onClickBtn2 = function() {
    console.log(233);
}
//绑定第二个事件
button.addEventListener('click', onClickBtn2);

2.解绑事件

通过onclick绑定的事件,解绑时给onclick赋值null即可:

//获取button
let button = document.querySelector('button');
//获取num盒子
let numDiv = document.querySelector('.num');
//声明点击时要执行的函数
let onClickBtn = function() {
   let num = Number(numDiv.innerText);
   numDiv.innerText = ++num;
   if (num == 5) {
       button.onclick = null;
   }
}
//绑定点击事件
button.onclick = onClickBtn;

同样,与addEventListener对应的是removeEventListener:

//获取button
let button = document.querySelector('button');
//获取num盒子
let numDiv = document.querySelector('.num');
//声明点击时要执行的函数
let onClickBtn = function() {
   let num = Number(numDiv.innerText);
   numDiv.innerText = ++num;
   if (num == 6) {
       button.removeEventListener('click', onClickBtn);
    }
}
//绑定点击事件
button.addEventListener('click', onClickBtn);

3.事件流

Dom事件触发分为3个阶段:1.捕获阶段 2.当前阶段 3.冒泡阶段.通过代码来了解一下这几个阶段:

<!DOCTYPE html>
<html>
<head>
	<title>事件流</title>
	<style type="text/css">
		.father {
			width: 600px;
			height: 600px;
			background-color: pink;
			margin: 0 auto;
			overflow: hidden;
		}
		.son {
			width: 400px;
			height: 400px;
			background-color: #ccc;
			margin: 100px auto;
		}
	</style>
</head>
<body>
	<div class="father">
		<div class="son"></div>
	</div>
</body>

<script type="text/javascript">
	let fDiv = document.querySelector ('.father');
	let sDiv = document.querySelector ('.son');

	fDiv.onclick = function () {
		console.log ('father click');
	}
	sDiv.onclick = function () {
		console.log ('son click');
	}
</script>

</html>

我们通过onclick分别为父盒子和子盒子添加绑定事件,然后点击子盒子,看一下打印面板:

这时会先执行子盒子的点击事件,这种由里到外的执行顺序,就是冒泡阶段,通过onclick绑定的事件会在冒泡阶段执行.下面看一下addEventListener:

let fDiv = document.querySelector ('.father');
let sDiv = document.querySelector ('.son');

fDiv.addEventListener ('click', function () {
	console.log ('father click');
});
sDiv.addEventListener ('click', function () {
	console.log ('son click');
});
let fDiv = document.querySelector ('.father');
let sDiv = document.querySelector ('.son');

fDiv.addEventListener ('click', function () {
	console.log ('father click');
}, false);
sDiv.addEventListener ('click', function () {
	console.log ('son click');
}, false);

addEventListener可以传递第三个参数,bool类型,省略的话默认为false,从上面可以看到,为false的时候为冒泡阶段执行.

let fDiv = document.querySelector ('.father');
let sDiv = document.querySelector ('.son');

fDiv.addEventListener ('click', function () {
	console.log ('father click');
}, true);
sDiv.addEventListener ('click', function () {
	console.log ('son click');
}, true);

当第三个参数为true时,为捕获阶段执行.

4.事件对象

当我们绑定事件时,dom会给我们的绑定事件传递一个参数,里面包含了事件的一些信息:

<!DOCTYPE html>
<html>
<head>
	<title>事件流</title>
	<style type="text/css">
		.father {
			width: 600px;
			height: 600px;
			background-color: pink;
			margin: 0 auto;
			overflow: hidden;
		}
		.son {
			width: 400px;
			height: 400px;
			background-color: #ccc;
			margin: 100px auto;
		}
	</style>
</head>
<body>
	<div class="father">
		<div class="son"></div>
	</div>
</body>

<script type="text/javascript">
	let fDiv = document.querySelector ('.father');

	fDiv.addEventListener ('click', function (e) {
		console.log (e);
	});
</script>

</html>

看一下里面的几个常用属性:

(1)target和currentTarget

target会保存触发事件的对象,currentTarget会保存绑定当前事件的对象,比如我点击一下子盒子:

let fDiv = document.querySelector ('.father');

fDiv.addEventListener ('click', function (e) {
	console.log (e.target);
	console.log (e.currentTarget);
});

由于点击了子盒子,所以这里target为.son的div;而绑定当前点击事件的是父盒子,所以currentTarget为.father的div

(2)type

type会保存当前的事件类型:

let fDiv = document.querySelector ('.father');

fDiv.addEventListener ('click', function (e) {
	console.log (e.type);
});

(3)阻止默认行为

有一些标签自带一些默认行为,比如a标签的跳转功能,有些时候我们不需要他们执行默认行为,下面看一下阻止默认行为的方法:

<!DOCTYPE html>
<html>
<head>
	<title>事件流</title>
</head>
<body>
	<a href="https://www.baidu.com/">百度</a>
</body>

<script type="text/javascript">
	let a = document.querySelector ('a');

	a.addEventListener ('click', function (e) {
		e.preventDefault();
	});
</script>

</html>

通过e.preventDefault()可以阻止默认事件,这时点击a链接不会跳转:

(4)阻止冒泡

有时候我们可能不需要冒泡来触发父标签的事件,可以通过下面的方法:

<!DOCTYPE html>
<html>
<head>
	<title>事件流</title>
	<style type="text/css">
		.father {
			width: 600px;
			height: 600px;
			background-color: pink;
			margin: 0 auto;
			overflow: hidden;
		}
		.son {
			width: 400px;
			height: 400px;
			background-color: #ccc;
			margin: 100px auto;
		}
	</style>
</head>
<body>
	<div class="father">
		<div class="son"></div>
	</div>
</body>

<script type="text/javascript">
	let fDiv = document.querySelector ('.father');
	let sDiv = document.querySelector ('.son');

	fDiv.addEventListener ('click', function (e) {
		console.log ('father click');
	});
	sDiv.addEventListener ('click', function (e) {
		console.log ('son click');
		e.stopPropagation ();
	});
</script>

</html>

通过在子标签事件中调用事件参数的stopPropagetion()方法,可以阻止事件继续往上冒泡:

所以,这里点击子盒子,父盒子的点击事件不会触发.