1.复习
2.call和apply
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 定义函数
function demo() {
console.log('demo', this, arguments);
}
// 函数自执行
// window.demo();
// 改变函数的作用域
// 作为事件函数
// document.onclick = demo;
// // 定义对象
var obj = {
msg: 'hello',
fn: demo
}
// // 作为对象的属性调用
// obj.fn();
// 使用call方法改变函数的作用域(做了两件事:1执行函数 2改变函数的作用域)
// 第一个参数是将原来的作用域变成参数上的作用域
// 从第二个参数开始 表示原函数需要的参数
// demo.call(document, 100, true, 'abc');
// apply方法改变函数的作用域
// 第一个参数表示改变的作用域对象
// 第二个参数是一个数组 数组中的每一项是原函数需要的参数
demo.apply(obj, [1, 2, 3]);
</script>
</body>
</html>
3.事件流程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 500px;
height: 500px;
background-color: pink;
}
#box1 {
width: 350px;
height: 350px;
margin: 0 auto;
background-color: green;
}
#box2 {
width: 150px;
height: 150px;
margin: 0 auto;
background-color: skyblue;
}
</style>
</head>
<body>
<div id="box">
box
<div id="box1">
box1
<div id="box2">box2</div>
</div>
</div>
<script>
// 获取元素
var box = document.getElementById('box');
var box = document.getElementById('box1');
var box = document.getElementById('box2');
// 注意:dom.onclick = fn 这种绑定事件的方式 DOM0级事件 绑定的是冒泡阶段
// 冒泡:事件从最精致的元素开始执行,一层一层往上执行,直到最顶层的元素
// 分别每一个元素绑定点击事件
box.onclick = function() {
console.log('box');
}
box.onclick = function() {
console.log('box1');
}
box.onclick = function() {
console.log('box2');
}
</script>
</body>
</html>
4.dom2级事件绑定方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 500px;
height: 500px;
background-color: pink;
}
#box1 {
width: 350px;
height: 350px;
margin: 0 auto;
background-color: green;
}
#box2 {
width: 150px;
height: 150px;
margin: 0 auto;
border-color: skyblue;
}
</style>
</head>
<body>
<div id="box">
box
<div id="box1">
box1
<div id="box2">box2</div>
</div>
</div>
<script>
// 获取元素
var box = document.getElementById('box');
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
// 完整的事件流程分为捕获和冒泡
// 捕获:事件从最顶层元素开始执行 一层一层往下执行 直到最精准的元素
// 冒泡: 事件从最精致的元素开始 一层一层往上执行 直到最顶层的元素
// 完整流程: 事件 捕获找到元素 触发事件 事件冒泡到最顶层元素
// 绑定事件
box.addEventListener('click', function() {
console.log('box 冒泡');
}, false);
box1.addEventListener('click', function() {
console.log('box1 冒泡');
}, false);
box2.addEventListener('click', function() {
console.log('box2 冒泡');
}, false);
box.addEventListener('click', function() {
console.log('box 捕获');
}, true);
box1.addEventListener('click', function() {
console.log('box1 捕获');
}, true);
box2.addEventListener('click', function() {
console.log('box2 捕获');
}, true);
</script>
</body>
</html>
5.ie中高级绑定事件方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 500px;
height: 500px;
background-color: pink;
}
#box1 {
width: 350px;
height: 350px;
margin: 0 auto;
background-color: green;
}
#box2 {
width: 150px;
height: 150px;
margin: 0 auto;
border-color: skyblue;
}
</style>
</head>
<body>
<div id="box">
box
<div id="box1">
box1
<div id="box2">box2</div>
</div>
</div>
<script>
// 获取元素
var box = document.getElementById('box');
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
// 绑定事件
box.attachEvent('onclick', function() {
console.log('box attachEvent');
})
box1.attachEvent('onclick', function() {
console.log('box1 attachEvent');
})
box2.attachEvent('onclick', function() {
console.log('box2 attachEvent');
})
</script>
</body>
</html>
6.dom0级事件和dom2级事件绑定方式的区别
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box1 {
width: 350px;
height: 350px;
margin: 0 auto;
background-color: green;
}
</style>
</head>
<body>
<div id="box1">
box1
</div>
<script>
// 获取元素
var box1 = document.getElementById('box1');
// dom0级事件
// box1.onclick = function() {
// console.log('box 2222', this);
// }
// box1.onclick = function() {
// console.log('box 1111');
// }
// 绑定dom2级事件
box1.addEventListener('click', function() {
console.log('box1 addEventListener1', this);
})
box1.addEventListener('click', function() {
console.log('box1 addEventListener2');
})
/*
绑定数量
dom0级事件:只能够给一个元素的一个事件绑定一个函数
dom2级事件:能够给一个元素的一个事件绑定多个函数
执行顺序
按照代码的绑定顺序执行
是否可以同时存在
dom2级可以,不受dom0级事件的影响
this指向
都指向出发事件的元素
*/
//
</script>
</body>
</html>
7.dom2级事件和attachEvent事件之间的区别
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 350px;
height: 350px;
margin: 0 auto;
background-color: green;
}
</style>
</head>
<body>
<div id="box">
box
</div>
<script>
// 获取元素
var box = document.getElementById('box');
box.attachEvent('onclick', function() {
console.log('box attachEvent');
})
/*
绑定数量
dom0级:只能给一个元素的一个事件绑定一个函数
attachEvent事件:可以给一个元素的一个事件绑定多个函数
执行顺序
优先执行dom0级事件,然后再逆序执行attachEvent事件
是否可以同时存在
attachEvent可以
this指向
dom0指向触发事件的元素
attachEvent:指向window
*/
</script>
</body>
</html>
8.封装bindEvent方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 350px;
height: 350px;
margin: 0 auto;
background-color: green;
}
</style>
</head>
<body>
<div id="box">
box
</div>
<script>
// 获取元素
var box = document.getElementById('box');
// // dom0级事件
// box.onclick = function() {
// console.log("box onclick");
// }
// // ie中高级事件绑定方式
// box.attachEvent('onclick', function() {
// console.log('box attachEvent');
// })
// // dom2级事件绑定方式
// box.addEventListener('click', function() {
// console.log('box addEventListener', this);
// })
// 问题: 在ie中不支持addEventListener 在高级浏览器中不支持attachEvent
// 于是我们希望通过封装一个方法来解决浏览器绑定事件统一的方式
/***
* bindEvent 方法 解决浏览器绑定事件统一的方法
* @dom 绑定事件的元素
* @type 事件类型
* @callback 事件执行函数
**/
function bindEvent(dom, type, callback) {
// 能力检查
// 判断浏览器支持哪种能力
// 本质是从一个对象身上访问一个数据的时候 如果存在就使用 如果不存在 不会报错的这一特点
if (dom.addEventListener) {
// console.log(('高级浏览器'));
// 绑定dom2级事件
dom.addEventListener(type, callback, false)
} else if (dom.attachEvent) {
// console.log('IE');
dom.attachEvent('on' + type, callback);
} else {
// 说明是一些不知名浏览器
// dom['on' + type] = callback;
dom['on' + type] = function() {
oldFn && oldFn();
callback();
}
}
}
// // 说明是一些不知名浏览器
// dom['on' + type] = callback;
// 拓展: 希望把之前的dom0级事件一起执行
// 获取之前的事件函数
// box.onclick = function() {
// console.log('box onclick');
// }
// var oldFn = dom['on' + type];
// 添加事件
// dom['on' + type] = function() {
// // 执行之前的事件函数
// oldFn && oldFn();
// // 执行事件函数
// callback();
// }
// console.log(oldFn);
// 测试
bindEvent(box, 'click', function() {
// console.log('事件执行了');
});
</script>
</body>
</html>
9.dom2级事件移除方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 350px;
height: 350px;
background-color: green;
}
</style>
</head>
<body>
<button id="btn">点我移除事件</button>
<div id="box">
box
</div>
<script>
// 获取元素
var box = document.getElementById('box');
var btn = document.getElementById('btn');
// 提取为有名函数
function click() {
console.log("事件执行了");
}
// dom2级事件
box.addEventListener('click', click);
// 点击按钮移除事件
btn.addEventListener('click', function() {
box.removeEventListener('click', click);
})
// 总结:
// 匿名 函数无法移除,因为移除的时候,要获取函数的引用,因此为了能够移除事件,要为函数起名字
// 当绑定多个事件的时候,移除的事件对其他事件没有影响
// 在哪个阶段绑定就在哪个阶段移除
// removeEventLisener不能移除DOM0级事件,DOM0级事件可以通过dom。onclick = null 方式移除
// 相同的事件回调函数,多次绑定只能保留一个
</script>
</body>
</html>
10.ie中移除事件的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 350px;
height: 350px;
background-color: green;
}
</style>
</head>
<body>
<button id="btn">点我移除事件</button>
<div id="box">
box
</div>
<script>
// 获取元素
var box = document.getElementById('box');
var btn = document.getElementById('btn');
// 提取为有名函数
function click() {
console.log("事件执行了");
}
// 绑定 attachEvent事件
box.attachEvent('onclick', click);
// 点击按钮的时候移除事件
btn.onclick = function() {
box.detachEvent('onclick', click);
}
// 总结:
// 匿名函数无法移除
// 当绑定多个事件的时候,移除的事件对其他事件没有影响
// detachEvent不能移除Dom0级事件
// 相同事件回调函数多次绑定,会共存,删除的时候要多次移除
</script>
</body>
</html>
11.事件对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 350px;
height: 350px;
background-color: green;
margin: 0 auto;
}
</style>
</head>
<body>
<div id="box">
box
</div>
<script>
// 获取元素
var box = document.getElementById('box');
// 绑定事件
box.onclick = function(e) {
// console.log(this, e);
// offsetX、offsetY:这两个属性标记的是鼠标位于元素内部的位置(padding),会受到子元素的影响
// console.log(e.offsetX, e.offsetY);
// clientX、clientY:这两个属性标记的是鼠标视口中的位置(x,y等价),不会受到子元素的影响
// console.log(e.clientX, e.clientY);
// console.log(e.x, e.y);
// pageX pageY:这两个属性标记的是鼠标位于页面中的距离(layerX layerY等价)
// console.log(e.pageX, e.pageY);
// console.log(e.layerX, e.layerY);
// screenX screenY:这两个属性标记了鼠标位于屏幕中的位置
// console.log(e.screenX, e.screenY);
// 在dom0级事件中,IE中并没有将事件对象传递到事件函数中
// 事件对象存储在window上,获取:window.event
// 兼容方式:var e = e || window.event
// 在IE中的事件对象中 没有pageX pageY
// console.log(window.event);
var e = e || window.event;
console.log(e);
}
</script>
</body>
</html>
12.事件对象的总结
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 350px;
height: 350px;
background-color: green;
margin: 0 auto;
}
</style>
</head>
<body>
<div id="box">
box
</div>
<script>
// 获取元素
var box = document.getElementById('box');
// 绑定事件
box.onclick = function(e) {
console.log(e);
}
// 总结
// dom0级事件:
// 高级浏览器传递了事件对象
// IE中没有传递事件对象
// this指的都是触发事件的元素
// dom2级事件
// 传递了事件对象
// this指向触发事件的对象
// 执行顺序是代码绑定的顺序
// attachEvent事件
// 可以传递了事件对象
// this指向是window
// 执行顺序:优先执行dom0级事件, 逆序执行attachEvent事件
</script>
</body>
</html>
13.拖拽模型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#container {
width: 800px;
height: 500px;
margin: 0 auto;
border: 1px solid red;
}
#box {
position: relative;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: orange;
}
</style>
</head>
<body>
<div id="container">
<div id="box"></div>
</div>
<script>
// 获取元素
var box = document.getElementById('box');
// 鼠标按下
box.onmousedown = function(e) {
// console.log(111, e);
// 获取按下时候的鼠标位置
var x = e.clientX;
var y = e.clientY;
// 获取当前元素的定位值
var b_left = parseInt(getComputedStyle(box)['left']);
var b_top = parseInt(getComputedStyle(box)['top']);
// 鼠标移动事件
document.onmousemove = function(e) {
// 获取移动时候的鼠标位置
var b_x = e.clientX;
var b_y = e.clientY;
// 赋值box的定位值 = 移动后的位置 - 移动前的位置 + 当前定位值
box.style.left = b_x - x + b_left + 'px';
box.style.top = b_y - y + b_top + 'px';
}
}
// 鼠标抬起移除事件(dom0级事件)
box.onmouseup = function() {
document.onmousemove = null;
}
</script>
</body>
</html>
14.阻止冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 500px;
height: 500px;
background-color: pink;
}
#box1 {
width: 350px;
height: 350px;
margin: 0 auto;
background-color: green;
}
#box2 {
width: 150px;
height: 150px;
margin: 0 auto;
background-color: skyblue;
}
</style>
</head>
<body>
<div id="box">
box
<div id="box1">
box1
<div id="box2">box2</div>
</div>
</div>
<script>
// 获取元素
var box = document.getElementById('box');
var box = document.getElementById('box1');
var box = document.getElementById('box2');
// 分别每一个元素绑定点击事件
box.onclick = function() {
console.log('box');
}
box.onclick = function() {
console.log('box1');
}
box.onclick = function(e) {
// 兼容事件对象
var e = e || window.event;
console.log('box2');
// e.stopPropagation();
e.cancelBubble = true;
}
// 在高级浏览器中阻止冒泡的方式:
// e.stopPropagation();
// 在ie中阻止冒泡的方式:
// e.cancelBubble = true;
</script>
</body>
</html>
15.阻止默认事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<a href="https://www.baidu.com" id="a">跳转到百度</a>
<script>
// 绑定事件
a.onclick = function(e) {
// 兼容ie
var e = e || window.event;
// 在高级浏览器中阻止默认事件的方法: e.preventDefault()
e.preventDefault();
// 在ie中阻止默认事件的方式: e.returnValue = false;
// e.returnValue = false;
// 如果使用dom0级事件绑定方式, 还可以使用return false 阻止默认行为
}
</script>
</body>
</html>
16.其他事件属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 500px;
height: 500px;
margin: 0 auto;
background-color: pink;
}
#box1 {
width: 350px;
height: 350px;
margin: 0 auto;
background-color: green;
}
</style>
</head>
<body>
<div id="box">
box
<div id="box1">box1</div>
</div>
<script src="./js/tools.js"></script>
<script>
// 绑定事件
// box.onclick = function(e) {
// // 兼容ie
// var e = e || window.event;
// // console.log(e);
// // type 获取事件的类型。
// // console.log(e.type);
// // target 返回触发此事件的元素(事件的目标节点,IE:srcElement)。
// // console.log(e.target);
// console.log('ie', e.srcElement.id);
// // currentTarget 返回的是绑定事件的元素对象
// // console.log(e.currentTarget);
// // timeStamp 返回事件生成的日期和时间。
// // console.log(e.timeStamp);
// }
// 统一方式:
bindEvent(box, 'click', function(e) {
console.log(111, e);
console.log(e.target);
console.log(e.currentTarget);
})
</script>
</body>
</html>