什么是事件:
js -> 交互 人可以去操作页面
js -> 事件驱动的方式
用户 -> 操作html元素 -> 产生一个事件 -> 事件主动调用 -> 设定的方法或函数
主要包括了四部分:
事件源: 产生事件的地方
事件的类型: 点击 键盘
事件对象: 记录当时发生事件的所有信息
事件的处理程序: 函数
注册
方法一:
把事件类型和方法注册到html元素上,如<div οnclick="fn()"></div>;
<div id="div1" onclick="fn()">点击我调用方法</div>
<script>
function fn() {
alert('事件函数被调用')
}
</script>
和在js中获取元素后注册,如果div1.onclick,在js中方法后不需要加()。
<div id="div1">点击我调用方法</div>
<script>
function fn() {
alert('事件函数被调用')
}
var div1 = document.getElementById('div1');
div1.onclick = fn;
</script>
方法二:
通过调用 系统提供的方法 可以绑定多个事件
addEventListener(事件类型click, 函数fn, 事件处理方式默认冒泡false)
<div id="div1">点击我调用方法</div>
<script>
function fn() {
alert('事件函数被调用')
}
div1.addEventListener('click', fn);
// div1.removeEventListener('click', fn); // 移出事件方法,参数必须和addEventListener一致
</script>
ie8不支持addEventListener方法,使用attachEvent()和detachEvent()方法兼容。

事件函数
事件函数比其他普通函数多了一个event参数,这个参数提供了事件的详细信息,如:具体发生的事件元素,鼠标事件:鼠标的位置,点击的状态,键盘事件:键盘的按键等。
<div id="div1">点击我调用方法</div>
<script>
function fn(event) {
console.log(event);
}
var div1 = document.getElementById('div1');
var input1 = document.getElementById('input1');
div1.addEventListener('click', fn);
input1.addEventListener('keydown', fn)
</script>


screenX: 741, screenY: 146, (表示屏幕左上角到点击的坐标位置)
clientX: 91, clientY: 2(表示浏览器左上角到点击的坐标位置)

事件默认行为:
如果点击了a标签,但是不想让它跳转,可以使用event.preventDefault()取消默认操作。
ie8中没有event,只有window.event对象,所有要写兼容。
var e = event || window.event
<a id="a1" href="https://www.baidu.com" target="_blank">百度一下,你就知道</a>
<script>
function fn(event) {
event.preventDefault(); // 取消默认操作
console.log(event);
}
var a1 = document.getElementById('a1');
a1.addEventListener('click', fn);
</script>
如果是addEventListener注册的事件函数,只能使用event.preventDefault()这种取消默认事件的方式;如果是使用a1.onclick注册的,可以使用event.preventDefault()和return false皆可。
如果是ie8,使用event.returnValue = false(默认true) 来取消默认行为。
事件流
事件的传播:在默认的情况下,处在传播路径上的标签都会监听到对应的事件。
传播路径:

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>事件基础</title>
<style>
#div1 {
width: 200px;
height: 200px;
background: #faff72;
text-align: center;
border-radius: 10%;
}
#div2 {
width: 100px;
height: 100px;
background: #3eede7;
text-align: center;
margin-left: 50px;
border-radius: 10%;
}
</style>
</head>
<body>
<div id="div1">
我是div1
<div id="div2">
我是div2
</div>
</div>
<script>
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
div1.addEventListener('click', div1Click);
div2.addEventListener('click', div2Click);
function div1Click() {
console.log('我是div1的事件函数')
}
function div2Click() {
console.log('我是div2的事件函数')
}
</script>
</body>
</html>

事件流: 对应标签接收到事件的顺序。
两大阶段:
捕获阶段: 从起始点(document) -> 目标位置
冒泡阶段: 目标位置 -> 起始点

addEventListener('click', div1Click, false); 在冒泡阶段执行
addEventListener('click', div1Click, true); 在捕获阶段执行
两个阶段一起执行的样子: 先执行捕获,再执行冒泡。
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
// 捕获阶段
div1.addEventListener('click', div1Clicktrue, true);
div2.addEventListener('click', div2Clicktrue, true);
function div1Clicktrue() {
console.log('我是div1 捕获阶段')
}
function div2Clicktrue() {
console.log('我是div2 捕获阶段')
}
// 冒泡阶段
div1.addEventListener('click', div1Clickfalse, false);
div2.addEventListener('click', div2Clickfalse, false);
function div1Clickfalse() {
console.log('我是div1 冒泡阶段')
}
function div2Clickfalse() {
console.log('我是div2 冒泡阶段')
}

终止冒泡事件:
function div2Clickfalse(e) {
e.stopPropagation(); // 使用这个方法终止冒泡事件
console.log('我是div2 冒泡阶段')
}

事件代理:
假设有一个ul, 它地下有一些li(动态),每个li都要绑定事件。
因为li的父级是ul,所有可以利用冒泡找target目标来实现。
<ul id="ul1">
<li>li1</li>
<li>li2</li>
<li>li3</li>
<li>li4</li>
<li>li5</li>
</ul>
<script>
var ul1 = document.getElementById('ul1');
ul1.addEventListener('click', ulClick, false)
function ulClick(e) {
console.log(e)
console.log(e.target)
e.target.style.color = "red";
}
</script>

再来一段:
<div id="div1">
<div>我是div2</div>
<div>我是div3</div>
<div>我是div4</div>
</div>
<script>
var div1 = document.getElementById('div1');
// 冒泡阶段
div1.addEventListener('click', div1Clickfalse, false);
function div1Clickfalse(e) {
console.log(e.target)
console.log('我是div1 冒泡阶段')
}
</script>
