【JS】事件

一、事件监听

1. 给元素监听事件的三种方式

  • 第一种方式: 事件作为HTML标签的属性:

    <div onclick="JS代码……" ondblclick="JS代码……"></div>
    
  • 第二种方式: 事件作为元素对象的方法:

    元素对象.onclick = function() {};
    元素对象.ondblclick = function() {};
    
  • 第三种方式:使用 addEventListenrer 方法:

    元素对象.addEventListener('click',回调函数);
    
  1. 第三种事件监听方式可以给同一个元素,监听多次相同的事件
  2. IE8浏览器不支持addEventListenrer,可以使用attachEvent('onclick',回调函数)

2. 解除事件的监听

  • 第一种和第二种方式监听的事件:

    给元素对象重新设置事件,设置为空,将原来的覆盖

    元素对象.onclick = null;
    
  • 第三种方式监听的事件:

    元素对象.removeEventListener('click',回调函数名)
    
  1. addEventListenrer 方法监听的事件,如果需要接触监听,不能使用匿名的回调函数
  2. IE8以及以下,使用datachEvent()解除

二、事件流

从用户在元素上发生动作到回调函数执行,会经历三个阶段:

  1. 捕获阶段:从window、document、html元素一直层层向下,找到目标元素(具体发生了动作的动作)

  2. 目标阶段:标志着捕获阶段的结束以及冒泡阶段的开始

  3. 冒泡阶段:从目标元素开始向上冒泡,直到html元素、document、window

    事件的回调函数在冒泡阶段执行(事件在冒泡阶段触发)

    addEventListener()设置第三个参数为true,回调函数将在捕获阶段执行

image-20230720101140861.png

三、事件的回调函数中 this 的指向

事件的回调函数中,this的值是监听事件的元素!

<button onclick="func(this)">按钮1</button>
<button id="btn02">按钮2</button>
<button id="btn03">按钮3</button>
<script>
    function func(cb) {
        cb();
    }
    func(function () {
        console.log(this);//window调用
    });

    // 定义函数 
    function func(ele) {
        for (var i = 0; i < 10; i++) {
            console.log('按钮1 被点击了');
        }
        console.log(ele);   //ƒ () {console.log(this);//window调用}
        console.log(this);  //window
    }

    // 第二种方式 将事件作为元素对象的方法
    var btn02 = document.querySelector('#btn02');
    btn02.onclick = function () {
        console.log('btn02 被点击了!', this);   //<button id="btn02">按钮2</button>
    };

    // 第三种 使用元素对象的 addEventListner()
    var btn03 = document.querySelector('#btn03');
    btn03.addEventListener('click', function () {
        console.log('btn03 被点击了!', this);  //<button id="btn03">按钮3</button>
    });
</script>

四、常用事件总结

1. 鼠标事件

事件含义
click单击
dblclick双击
contextmenu右击
mousedown鼠标按键按下
mouseup鼠标按键抬起
mousemove鼠标移动
mouseover鼠标移入
mouseout鼠标移出
mouseenter鼠标移入
mouseleave鼠标移出

2. 键盘事件

事件含义
keydown键盘按键按下
keyup键盘按键抬起
keypress键盘按键按下

keypress 和 keydown 的区别:

  1. 只有可输入字符对应的按键按下,可以press才能触发,所有的按键按下keydown都可以触发
  2. keypress会对输入的字符进行处理判断,可以区分大小写字母

哪些元素可以监听键盘事件?

  1. document对象
  2. 表单输入框、文本域

3. 文档事件

事件含义
load文档加载完毕(页面中所有一切加载完毕)
DOMContentLoaded文档加载完毕(页面中所有的元素加载完毕)只能使用addEventListener监听
beforeunload文档关闭前触发(所在窗口关闭)

文档事件需要监听到window或者body元素上

4. 表单事件

事件含义
submit监听给form元素,当表单提交的时候触发
reset监听给form元素,当表单重置的时候触发
focus()监听给表单控件,当获取到焦点时触发
blur()监听给表单控件,当失去焦点的时候触发
change监听给表单控件,当表单控件发生改变
select监听给输入框或文本域,里面的内容被选中时触发
input监听给输入框或文本域,里面的内容发生改变时触发

change事件:监听给输入框,触发change需要满足两个条件:输入框内容变换;输入框失去焦点

5. 图片事件

事件含义
load图片文件加载完毕
error图片加载失败
abort图片加载中断(了解)

6. 其他事件

  • 过渡事件

    事件含义
    transitionstart过渡开始,延迟结束
    transitionrun延迟开始的时候
    transitionend过渡结束
  • 动画事件

    事件含义
    animationstart动画开始的时候,延迟结束
    animationend动画结束的时候,最后结束
    animationiteration动画执行多次,每次结束都触发
  • 其他事件

    事件含义
    scroll滚动事件,可以监听给window或者内容会滚动的元素
    resize监听给window,视口大小发生改变,触发

五、Event 对象

1. 获取 Event 对象

事件的回调函数中可以接收到参数,该参数就是事件对象

// 第二种方式 将事件作为元素对象的方法
var btn02 = document.querySelector('#btn02');
btn02.onclick = function(ev) {
    // var ev = ev || window.event;  // 兼容性获取事件对象
    console.log('btn02 被点击了!', ev);
};

// 第三种 使用元素对象的 addEventListner()
var btn03 = document.querySelector('#btn03');
btn03.addEventListener('click', function(event){
    console.log('btn03 被点击了!', event); 
});

2. 鼠标事件对象 MouseEvent 的属性和方法

事件含义
button鼠标按键的值0:左键;1:中间;2:右键
offsetX/offsetY鼠标在目标元素上的位置
clientX/clientY鼠标在视口上的位置
pageX/pageY鼠标在页面上的位置
screenX/screenY鼠标在屏幕上的位置
// 监听鼠标移动
box.onmousemove = function(event) {
    // 获取鼠标的位置
    p.innerHTML = '鼠标在目标元素上的位置:' + event.offsetX + ' , ' + event.offsetY + '<br>';
    p.innerHTML += '鼠标在视口上的位置:' + event.clientX + ' , ' + event.clientY + '<br>';
    p.innerHTML += '鼠标在页面上的位置:' + event.pageX + ' , ' + event.pageY + '<br>';
    p.innerHTML += '鼠标在屏幕上的位置:' + event.screenX + ' , ' + event.screenY + '<br>';


    // 计算鼠标在box上的位置 鼠标在视口上位置 - box元素在视口上的位置
    var boxX = event.clientX - box.getBoundingClientRect().left;
    var boxY = event.clientY - box.getBoundingClientRect().top;
    p.innerHTML += '鼠标在box元素上的位置:' + boxX + ' , ' + boxY + '<br>';
};

image-20230720110356645.png

3. 键盘事件对象 KeyborardEvent 的属性和方法

事件含义
which获取键盘按键对应的ASCII码
keyCode同which
key获取键盘按键的值(字符串)
document.onkeydown = function(event) {
    console.log('which:',event.which);
    console.log('keyCode:',event.keyCode);
    console.log('key:',event.key);
}

4. 所有类型的事件对象都有的属性和方法

事件含义
type获取事件名称
timeStamp触发事件时的时间戳,从打开页面时间开始计算
target获取目标元素
document.onkeydown = function(event) {
    console.log('type:', event.type);
}        

document.onclick = function(event) {
    console.log('type:', event.type);
    console.log('timeStamp:', event.timeStamp);
    console.log('目标元素:', event.target);
    console.log('');
}

image-20230720110722978.png

5. 阻止事件冒泡

调用事件对象.stopPropagation()	

6. 浏览器的默认行为

  • 浏览器有哪些默认行为

    1. 超链接点击可以跳转(click事件)
    2. 表单可以提交和重置(submit和reset事件)
    3. 点击提交按钮可以提交表单(click事件)
    4. 点击重置按钮可以重置表单(click事件)
    5. 右键菜单(任何元素都具有该默认行为)
  • 阻止浏览器默认行为

    1. 事件对象.preventDefault()调用该方法可以阻止

    2. 如果使用第二种事件监听方式,在回调函数 return false;同样可以阻止

    浏览器的默认行为在整个事件流程结束后(冒泡也结束了)才会发生

六、事件委托

事件委托的原理:

  1. 在祖先元素上监听事件,动作发生在后代元素上,会冒泡到祖先元素
  2. 利用event.target获取到目标元素,如果目标元素是符合条件的元素就执行相应的操作

事件委托能解决什么问题?

  1. 让新增的元素也具有事件
  2. 通过事件委托给大量元素监听事件
// 遍历删除按钮 添加单击事件
// deleteBtns.forEach(function(deleteBtn){
//     deleteBtn.onclick = function() {
//         tableBox.deleteRow(deleteBtn.parentElement.parentElement.rowIndex);
//     };
// });


// 使用事件委托
tableBox.onclick = function(event) {
    // 判断如果 目标元素是删除按钮再进行相关操作
    if (event.target.classList.contains('delete-btn')) {
        tableBox.deleteRow(event.target.parentElement.parentElement.rowIndex);
    }
};

七、DOM 对象深入分析

1. 元素对象的原型链关系

div元素对象 -> HTMLDivElement.prototype -> HTMlElement.prototype -> Element.prototype -> Node.prototype -> EventTarget.prototype -> Object.prototype

2. 事件对象的原型链关系

鼠标事件对象 -> MouseEvent.prototype -> UIEvent.prototype -> Event.prototype -> Object.prototype

3. HTMLCollection 和 NodeList 的区别

  • HTMLCollection 对象

    1. 能够返回HTMLCollection 对象的属性和方法: getElementsByTagName()、getElementsByClassName()、children
    2. HTMLCollection 对象的成员只能是元素类型对象
    3. 没有 forEach 方法
    4. 是动态的集合,如果文档中新增了满足条件的元素,集合会自动更新
  • NodeList

    1. 能够返回 NodeList 对象的属性和方法: querySelectorAll()、getElementsByName()、childNodes
    2. NodeList 对象的成员可以是节点类型的对象(包括元素类型、document 等)
    3. 具有 forEach 方法
    4. 静态的集合
// 获取到所有li的集合,得到 HTMLCollection 对象
var liCollection = document.getElementsByTagName('li');
// 获取到所有li的集合,得到 NodeList 对象
var liNodes = document.querySelectorAll('li');


console.log(liCollection);
console.log(liNodes);
console.log('');

// 获取到ul元素
var ulBox = document.querySelector('#box');
// 创建一个li元素,并添加到 ul 中
var newLi = document.createElement('li');
newLi.innerHTML = '我是一个新的 LI';
ulBox.appendChild(newLi);

console.log(liCollection);
console.log(liNodes);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值