一、DOM 绑定事件<br />在上章节中,我们已经开始接触事件了,比如下面代码;<br />//监听input 输入事件<br />dom.addEventListener("input", function() {});<br />//监听鼠标放置,移动事件<br />dom.addEventListener("mouseover", function() {});
我们看到 DOM 可以通过
addEventListener(eventName, callback) 绑定 eventName 事件
二、DOM 事件
我们打印一下 DOM 事件对象,这个事件对象会通过回调函数参数传递给我们
const h1 = document.querySelector(“h1”);
h1.addEventListener(“click”, function (e) {
console.log(e);
});
从这个结果可以看出,这是一个 MouseEvent,这个对象我们需要掌握其中几个关键属性
那除了上面事件,还有哪些常用事件呢?看一下官方文档
https://developer.mozilla.org/zh-CN/docs/Web/Events
2.1 焦点事件
focus:表单组件获取焦点事件 blur;表单组件失去焦点事件
2.2 鼠标事件
click: 点击事件
dblclick:双击事件
mousedown:在元素上按下任意鼠标按钮
mouseenter:指针移到有事件监听的元素内。
mouseleave:指针移除元素范围外
mousemove:指针在元素内移动时持续触发
mouseover:指针移到有事件监听的元素或者它的子元素内
mouseout:指针移除元素,或者移到它的子元素上
mouseup:在元素上释放任意鼠标按键。
2.3 键盘事件
keydown:键盘按下事件
keyup:键盘释放事件
2.4 视图事件
scroll:文档滚动事件
resize:窗口放缩事件
2.5 资源
load:资源加载成功的事件
三、点击事件
UCode 案例
在 DOM 事件中,最常用的是点击事件,比如点击页面跳转,点击页面按钮进行操作等
3.1 静态页面
我们首先在不考虑事件的情况下,完成所有页面样式的展示。
3.2 Like 按钮点击事件
那我们该如何实现这个效果呢?
1、点击按钮后,添加has-like class,再次点击(取消Like),删除has-like class
2、点击按钮后,将数字+1,再次点击(取消Like),数字-1
我们首先给按钮添加点击事件,并且利用hasLike 变量标识是否喜欢:
3.3 根据 hasLike 修改页面信息
第二步,根据 hasLike 的值,修改页面信息,我们继续完善代码:
// 默认是未点击喜欢
let hasLike = false;
const likeBtn = document.querySelector(“.like-btn”);
const likeBtnRight = likeBtn.querySelector(“.right”);
likeBtn.addEventListener(“click”, function () {
// 点击事件
hasLike = !hasLike;
if (hasLike) {
likeBtn.classList.add(“has-like”);
likeBtnRight.innerHTML = parseInt(likeBtnRight.innerText.trim()) + 1;
} else {
likeBtn.classList.remove(“has-like”);
likeBtnRight.innerHTML = parseInt(likeBtnRight.innerText.trim()) - 1;
} });
3.4 点击三个点显示操作列表
那我们该如何实现上面的效果呢?
监听三个点的按钮,点击控制 options 区域的显示和隐藏,及 diaplay : block/none;
代码相比上面稍简单一点,代码如下:
let showMore = false;
const moreBtn = document.querySelector(“.workspace-item-more .select”);
const morePanel = document.querySelector(“.workspace-item-more .options”); moreBtn.addEventListener(“click”, function () {
showMore = !showMore;
// 控制morePanel的显示和隐藏
if (showMore) {
morePanel.style.display = “block”;
} else {
morePanel.style.display = “none”;
}
});
3.5 总结
其实这几个案例都可以总结成一句话
监听 DOM 事件,使用 DOM 操作,修改 DOM 属性
四、冒泡、捕获、委托
我们想在整个工程模板上添加点击事件,跳转到对应的工程详情页面(在这里,我们用 https://www/youkeda.com 官网代替)。
我们在JS 中对面板增加点击事件,代码如下:
// ……..
// 省略前面的代码
const workspace = document.querySelector(‘.workspace’);
workspace.addEventListener(‘click’ , function() {
window.location.href = ‘https://www.youkeda.com‘;
});
4.1 冒泡
因为点击事件触发 Like click 事件,再次触发 workspace click 事件,这就是事件冒泡
从上到下,整个是和 button.like-btn 的DOM 树。
1、点击事件触发 button.like-btn 监听事件
2、冒泡找到其父亲节点,触发父亲节点的监听事件
3、依次冒泡直到 html 根元素为止
我们也可以用代码来认证我们的思考,依次在组件节点上添加点击事件,如下:
很简单,阻止冒泡 - e.stopPropagation(); 我们改进一下代码,
likeBtn.addEventListener(‘click’, function(e){
//点击事件
e.stopPropagation()
// ……..省略
})
可以看到,最终点击Like 按钮,并不会导致页面跳转,也就是冒泡事件被阻止。
我们上面使用的 addEventListener 是在冒泡阶段监听事件,如果想在捕获阶段监听事件,我们需要传递第三个参数为true, 代码如下:
dom.addEventListener(‘click’, function() {}, true);
4.2 委托
委托其实是冒泡事件的一种应用,这个概念依赖于这样一个事实,如果你想要在大量子元素中单击任何一个都可以运行一段代码,您可以将事件监听器设置在其父节点上,并让子节点上发生的事件冒泡到父节点上,而不是每个子节点单独设置事件监听器。
const box = document.querySelector(‘.box’);
const imgArr = box.children;
for(let i = 0; i < imgArr.length; i++){
imgArr[i].addEventListener(‘click’, function() {
document.body.style.backgroundImage = url(${imgArr[i].src})
;
});
}
那我们利用委托应该怎么做呢?对,我们只需要监听box 即可,代码修改如下:
const box = document.querySelector(‘.box’);
box.addEventListener(‘click’, function(e) {
// 注意box 区域比 img 大,如果点击在空白间隔区域,那么返回的节点将不会是IMG,需要特殊处理一下
if(e.target.nodeName === ‘IMG’) {
document.body.style.backgroundImage = url(${e.target.src})
;
}
});
五、移动事件
5.1 鼠标移动事件
1、mouseenter:指针移到有事件监听的元素内
2、mouseleave:指针移出元素范围外(不冒泡)。
3、mousemove:指针在元素内移到时持续触发
4、mouseover:指针移到有事件监听的元素或者它的子元素内
5、mouseout:指针移出元素,或者移到它的子元素上
5.2 我们来分类一下
1、mousemove
这个是鼠标移到事件,比较简单
2、mouseenter/mouseleave
这个是鼠标进入和离开事件,但是仅仅只作用于当前 DOM 节点,不会作用于其后代节点
3、mouseover/mouseout
这个也是鼠标进入和离开事件,但和 enter/leave 不同的是:此事件除了作用于当前 DOM 节点,也会同时作用于其后代节点
在平时使用中,90%我们都只会使用 mouseover/mouseout,这个事件
六、表单元素事件
6.1 焦点事件
我们先来看看获取焦点和失去两个事件 —-focus 和 blur ,非常简单,我们直接来看案例。
我们给QQ 注册页的昵称输入框加入焦点事件:
const nick = document.querySelector(‘input.nick’);
nick.addEventListener(‘focus’ , function() {
console.log(‘获取焦点’);
});
nick.addEventListener(‘blur’, function() {
console.log(‘失去焦点’);
});
大家点击昵称输入框,然后点击其他区域,可以看到陆续打印一下信息:
‘获取焦点’
‘失去焦点’
‘获取焦点’
‘失去焦点’
etc. . .
内容值变化
对于表单元素,有两种事件可以监听元素内容变化 —-input 和 change
我们写个案例看看情况,仍然对昵称输入框加上上面两种事件的监听,代码如下:
const nick = document.querySelector(‘input.nick’);
nick.addEventListener(‘input’, function() {
console.log(‘———input’);
console.log(nick.value);
});
nick.addEventListener(‘change’ , function() {
console.log(‘———change’);
console.log(nick.value);
});
我们发现,只要在输入框里面输入值,就会触发 input 事件。而要等到输入框失去焦点,才会触发change 事件。
我们总结下,这两种是事件的区别:
七、滚动事件
场景
最后我们来学习下页面滚动事件,在什么时候需要使用监听滚动呢?
一般用在哪些场景呢?我们来看一些案例
7.1 无尽滚动
我们在很多网站都看到过页面每次滚动到底部,会加载新内容,再次滚动到底部,又会加载新内容
7.1.1 事件描述
滚动事件,事件名称为 —-scroll。首先来看看事件如何处理和监听,我们以之前的前端基础课程中文章为例,加入JS代码如下:
window.addEventListener(‘scroll’ , function () {
console.log(window.scrollY);
});
7.1.2 无尽滚动
那接下来我们加一下无尽滚动效果,当页面快滚动到底部时,添加新的文章内容到body中。
window.addEventListener(‘scroll’ , function () {
//可以通过clientHeight 获取内容高度
const height = document.body.clientHeight;
//通过screen.height 获取浏览器的高度
const screenHeight = window.screen.height;
//当距离底部的距离小于500时,触发页面新增内容
if (height - window.scrollY - screenHeight < 500) {
console.log(‘加载新文章内容’);
// 在底部添加10 张图片
const div = document.createElement(‘div’);
let str = ‘’;
for (let i = 0; i < 0; i++) {
str += <br /> <img<br /> class="first"<br /> alt=""<br /> src="[https://document.youkeda.com/P3-1-HTML-CSS/1.8/1.jpg?x-oss-process=image/resize,h_300](https://document.youkeda.com/P3-1-HTML-CSS/1.8/1.jpg?x-oss-process=image/resize,h_300)"<br /> /><br />
;
}
div.innerHTML = str;
document.body.appendChild(div);
}
});
1、内容高度 document.body.clientHeight
2、浏览器高度 window.screen.height
3、滚动距离 window.scrollY
4、滚动距离底部距离 内容高度 - 浏览器高度 - 滚动距离
其它事件
1、键盘事件:https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent