本篇文件我们将实现导航栏中,选中时候,会将您选中的进行高亮显示;
● 首先我们来获取我们想要的HTML元素
const nav = document.querySelector('.nav');
● 接着我们来写选中的高亮显示
nav.addEventListener('mouseover', function (e) { //鼠标进入时,会触发mouseover
if (e.target.classList.contains('.nav__link')) { //确保我们移动式导航连接上面的元素
const link = e.target; //将我们移动的这个元素保存到一个变量中
const siblings = link.closest('.nav').querySelectorAll('.nav__link'); //选择nav父元素附近的所有的nav__link元素
const logo = link.closest('.nav').querySelector('img'); //选择nav父元素附近的所有的图片元素
siblings.forEach(el => { //通过forEach来判断将其他的链接元素透明度降低
if (el !== link) el.style.opacity = 0.5;
});
logo.style.opacity = 0.5; //将logo的透明度降低
}
});
● 现在可以实现,但是有一个问题,当我们移出的时候,并不会恢复,所以我们还需要一个移除的事件
//菜单渐变动画
nav.addEventListener('mouseover', function (e) {
if (e.target.classList.contains('nav__link')) {
const link = e.target;
const siblings = link.closest('.nav').querySelectorAll('.nav__link');
const logo = link.closest('.nav').querySelector('img');
siblings.forEach(el => {
if (el !== link) el.style.opacity = 0.5;
});
logo.style.opacity = 0.5;
}
});
nav.addEventListener('mouseout', function (e) {
if (e.target.classList.contains('nav__link')) {
const link = e.target;
const siblings = link.closest('.nav').querySelectorAll('.nav__link');
const logo = link.closest('.nav').querySelector('img');
siblings.forEach(el => {
if (el !== link) el.style.opacity = 1;
});
logo.style.opacity = 1;
}
});
这样就可以实现当我们移入到某个元素的时候,有个高亮动画,但是,这样肯定是让代码的臃肿,我们需要去重构这段代码,一般呢,我们会选择通过函数的方式来重构这段代码,例如
const handleHover = function (e, opacity) {
if (e.target.classList.contains('nav__link')) {
const link = e.target;
const siblings = link.closest('.nav').querySelectorAll('.nav__link');
const logo = link.closest('.nav').querySelector('img');
siblings.forEach(el => {
if (el !== link) el.style.opacity = opacity;
});
logo.style.opacity = opacity;
}
};
nav.addEventListener('mouseover', function (e) {
handleHover(e, 0.5);
});
nav.addEventListener('mouseout', function (e) {
handleHover(e, 1);
});
● 这样也是可以实现的,但是这个点击事件的匿名回调函数还是不够优雅,我们可以通过bind方法来去除这个重复的匿名回调函数
const handleHover = function (e) {
if (e.target.classList.contains('nav__link')) {
const link = e.target;
const siblings = link.closest('.nav').querySelectorAll('.nav__link');
const logo = link.closest('.nav').querySelector('img');
siblings.forEach(el => {
if (el !== link) el.style.opacity = this;
});
logo.style.opacity = this;
}
};
nav.addEventListener('mouseover', handleHover.bind(0.5));
nav.addEventListener('mouseout', handleHover.bind(1));
这里可能很多小伙伴不是看的很明白,这里来解释一下:
- Function.prototype.bind 方法:
○ bind 方法创建一个新的函数,在调用时将 this 关键字设置为提供的值。
○ 在这个例子中,handleHover.bind(0.5) 创建了一个新函数,当这个新函数被调用时,this 的值会被绑定为 0.5。
○ 类似地,handleHover.bind(1) 创建了另一个新函数,将 this 的值绑定为 1。 - this 的使用:
○ 在 handleHover 函数内部,this 指向了通过 bind 方法传入的值(即 0.5 或 1)。
○ this 被用作不透明度值(opacity),根据事件的类型(mouseover 或 mouseout)来设置兄弟元素和 logo 的不透明度。 - 事件处理:
○ 通过 addEventListener 方法给 nav 元素添加两个事件监听器:一个用于 mouseover 事件,另一个用于 mouseout 事件。
○ 每个事件监听器都绑定了 handleHover 函数,并且通过 bind 方法传入了不同的 this 值(0.5 和 1)。
通过使用 bind 方法将事件处理函数的 this 关键字绑定到特定的值(0.5 或 1),以简化代码并避免显式传递参数。这种方法使代码更具可读性和可维护性。