JavaScript学习笔记【DAY8(2020.8.26)周三】
事件
事件的组成:元素、事件类型、事件处理函数
事件对象e
当事件触发的时候 会产生很多的信息 这些信息被封装成一个对象 并传递到事件处理函数中
div.onclick = function(e) {
// e 就是事件对象 我们可以根据它获取到许多的信息
}
事件对象的重要属性
鼠标事件
altKey 热键alt键是否被按下
ctrlKey 热键ctrl键是否被按下
shiftKey 热键shift键是否被按下
offsetX 事件发生时鼠标位于元素内部的left位置(从鼠标位置到左边框内)
offsetY 事件发生时鼠标位于元素内部的top位置(从鼠标位置到上边框内)
clientX 事件发生时鼠标到视口的左边距离
clientY 事件发生时鼠标到视口的上边距离
pageX 事件发生时鼠标到页面的左边距离
pageY 事件发生时鼠标到页面的上边距离
currentTarget 绑定事件的元素
target 触发事件的元素
screenX 返回鼠标相对于电脑屏幕的X坐标
screenY 返回鼠标相对于电脑屏幕的Y坐标
键盘事件
key 表示当前的键对应的字符
keyCode 表示当前的键对应的字符的ASCII码
onkeyup 某个键盘按键被松开时触发
onkeydown某个键盘按键被按下时触发
onkeypress某个键盘按键被按下时触发但是它不识别功能键比如ctrl shift箭头等
注意:
1.如果使用addEventListener不需要加on
2. onkeypress 和前面2个的区别是,它不识别功能键,比如左右箭头, shift 等。
3.三个事件的执行顺序是: keydown-- keypress --- keyup
事件对象:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象。
比如:
1. 谁绑定了这个事件。
2. 鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。
3. 键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。
事件对象的使用:
事件触发发生时就会产生事件对象,并且系统会以实参的形式传给事件处理函数。
所以,在事件处理函数中声明1个形参用来接收事件对象。
事件对象的属性和方法
e.target 和 this 的区别:
this是事件绑定的元素(绑定这个事件处理函数的元素) 。
e.target 是事件触发的元素。
事件绑定方式
DOM 0级
绑定
元素.on事件类型 = 事件函数
只能够绑定一个事件 因为它是对属性进行赋值
移除
元素.on事件类型 = null
我们都知道,一个对象的属性只能够保存一个值。 如果对一个对象属性进行多次赋值,后面赋值的属性会替换掉前面的属性
DOM 2级
绑定
dom.addEventListener(type, handler, boolean)
type: 事件类型字符串 不带on
handler: 事件处理函数
boolean: 布尔值 决定绑定到捕获阶段还是冒泡阶段 默认是false false表示冒泡
结论: 可以通过addEventListener方法进行多个事件函数的绑定 执行时是按照代码的书写顺序执行 因为代码的书写顺序决定了绑定顺序 如果有DOM0级与DOM2级同时存在,依旧按照绑定顺序执行
移除
document.removeEventListener(type, handler, boolean);
type: 事件类型字符串 不带on
handler: 事件处理函数 一定要保证函数地址是绑定的那个
boolean: 布尔值 决定移除的是捕获阶段还是冒泡阶段 默认是false false表示冒泡
结论: 第二个参数是要移除的函数 函数是引用类型 引用类型的比较的是地址 所以一定要保证 移除的函数是当初绑定的那个函数本身
IE中的高级绑定方式(非DOM2级)
IE中没有实现DOM2级
绑定方式:
dom.attachEvent(type, handler);
type: 事件类型字符串 带on
handler: 事件处理函数
没有第三个参数 意味着不能够绑定到捕获阶段 特点: 可以对同一个元素绑定多个同类型事件的处理函数 执行起来是倒着执行 先绑定的后执行 后绑定的先执行 如果DOM0级与高级绑定方式同时存在,先执行DOM0级。再逆序执行高级绑定的函数。
移除方式:
dom.detachEvent(type, handler);
type: 事件类型字符串 带on
handler: 事件处理函数 要注意函数的地址问题
删除事件(解绑事件)
1.传统注册方式
eventTarget. onclick = null;
2.方法监听注册方式
①eventTarget. removeEventListener (type,listener[, useCapture] ) ;
②eventTarget . detachEvent (eventNameWithOn, callback) ;
事件流程:同一类事件的触发顺序
事件捕获: 当点击时 事件从最顶层元素 一层一层的往下触发 直到最精确元素
事件冒泡: 当点击时 事件从最精确的元素 一层一层往上触发 直到最顶层元素
最精确元素: 鼠标点到谁 谁就是最精确元素
最顶层元素:
高级浏览器 最顶层元素是window
IE中 最顶层元素是 document
注:当元素是最精确元素时,不区分它身上的捕获和冒泡,而是按照绑定顺序执行。
阻止冒泡
高级浏览器中 可以通过e.stopPropagation() 进行阻止事件的冒泡
// 高级浏览器中
// box1是box2的父元素
var box1 = document.querySelector(".box1");
var box2 = document.querySelector(".box2");
box1.onclick = function() {
console.log("这是BOX1");
}
box2.onclick = function(e) {
e.stopPropagation();
console.log("这是BOX2");
}
IE浏览器中 可以通过e.cancelBubble = true 进行阻止事件的冒泡
// IE浏览器中
// box1是box2的父元素
var box1 = document.querySelector(".box1");
var box2 = document.querySelector(".box2");
box1.onclick = function() {
console.log("这是BOX1");
}
box2.onclick = function(e) {
var e = e || window.event;
e.cancelBubble = true;
console.log("这是BOX2");
}
DOM 事件流会经历3个阶段:
1. 捕获阶段
2. 当前目标阶段
3. 冒泡阶段
停止默认行为
浏览器的一些事件中,带有一些默认行为 比如a标签的点击事件中 会带有跳转页面的行为 表单的点击事件中 带有提交的默认行为 滚轮事件中 带有改变页面卷动值的默认行为
(1)高级浏览器中 可以通过 e.preventDefault() 阻止默认行为
// 获取元素
var a = document.getElementsByTagName("a")[0];
// 设置点击事件
a.addEventListener("click", function(e) {
console.log("点击了a标签1111");
e.preventDefault();
}, false);
(2)IE浏览器中 可以通过 e.returnValue = false; 阻止默认行为
// 获取元素
var a = document.getElementsByTagName("a")[0];
// 设置点击事件
a.attachEvent("onclick", function(e) {
console.log("点击了a标签1111");
e.returnValue = false;
});
(3)DOM0级事件绑定方式中,可以通过return false进行阻止默认行为
// 获取元素
var a = document.getElementsByTagName("a")[0];
// 设置点击事件
a.onclick = function() {
return false;
}
事件委托(事件代理)
思想: 将原本子元素做的事情,委托给父元素去做。将事件绑定给父元素,父元素事件触发时,通过e.target判定触发事件的元素。决定执行对应代码。
// 1 获取元素 获取不可能被移除的父元素
var tbody = document.querySelector("tbody");
// 2 给tbody绑定事件
tbody.onclick = function(e) {
// e.target 这个属性指向触发事件的元素
console.log(e.target)
// 判定 点击到的是什么
if (e.target.className === "del") {
// 点击到的是移除按钮
e.target.parentNode.remove();
}
}
事件委托的作用:
我们只操作了一次 DOM ,提高了程序的性能。
动态新创建的子元素,也拥有事件。
事件委托:事件冒泡本身的特性,会带来的坏处,也会带来的好处。
什么是事件委托:把事情委托给别人,代为处理。
事件委托也称为事件代理,在 jQuery 里面称为事件委派。
说白了就是,不给子元素注册事件,给父元素注册事件,把处理代码在父元素的事件中执行。
生活中的代理:
js事件中的代理:
事件委托的原理
给父元素注册事件,利用事件冒泡,当子元素的事件触发,会冒泡到父元素,然后去控制相应的子元素。
<ul>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
</ul>
<script>
// 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
// e.target 这个可以得到我们点击的对象
e.target.style.backgroundColor = 'pink';
})
</script>
案例:禁止选中文字和禁止右键菜单
1禁止鼠标右键菜单
contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
document. addEventLi stener ('contextmenu',function(e){
e.preventDefault () ;
})
2.禁止鼠标选中(selectstart开始选中)
document. addEventLi stener ('selectstart', function(e) {
e.preventDefault();
})
<body>
我是一段不愿意分享的文字
<script>
// 1. contextmenu 我们可以禁用右键菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})
// 2. 禁止选中文字 selectstart
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})
</script>
</body>
获取鼠标在页面的坐标
<script>
// 鼠标事件对象 MouseEvent
document.addEventListener('click', function(e) {
// 1. client 鼠标在可视区的x和y坐标
console.log(e.clientX);
console.log(e.clientY);
console.log('---------------------');
// 2. page 鼠标在页面文档的x和y坐标
console.log(e.pageX);
console.log(e.pageY);
console.log('---------------------');
// 3. screen 鼠标在电脑屏幕的x和y坐标
console.log(e.screenX);
console.log(e.screenY);
})
</script>
立即执行函数:
// 1.立即执行函数: 不需要调用,立马能够自己执行的函数
function fn() {
console.log(1);
}
fn();
// 2. 写法 也可以传递参数进来
// 1.(function() {})() 或者 2. (function(){}());
(function(a, b) {
console.log(a + b);
var num = 10;
})(1, 2); // 第二个小括号可以看做是调用函数
(function sum(a, b) {
console.log(a + b);
var num = 10; // 局部变量
}(2, 3));
// 3. 立即执行函数最大的作用就是 独立创建了一个作用域, 里面所有的变量都是局部变量 不会有命名冲突的情况