JS / CSS问题-隐藏父元素后,Mouseenter事件不起作用

时间:2018-11-28 17:41:40

标签: javascript css

我正在尝试使用Javascript实现两种效果: 1)将鼠标悬停在图标上时,使页面左侧菜单中的导航链接的说明从左侧飞入,而当鼠标不再位于图标上时,使导航栏的说明飞回。 2)使用户可以通过按钮隐藏菜单。

我在此链接中将所有代码都保存在了一个代码笔中... https://codepen.io/anon/pen/JemLER

效果#1正常运行,直到菜单被效果#2隐藏为止。然后,当鼠标悬停在图标上时,说明将不再从左侧显示。

我做#1的方法是使用javascript向元素添加或删除一个类,该元素使用mouseenter和mouseout事件侦听器将其转换为页面的左侧。

这是javascript函数...

document.querySelector('.home-icon').addEventListener('mouseenter', () => {
    document.querySelector('.home-desc').classList.remove('side-menu__list-item-desc-hide');
    console.log('hover');
});

document.querySelector('.home-icon').addEventListener('mouseout', () => {
    document.querySelector('.home-desc').classList.add('side-menu__list-item-desc-hide');
});

这是隐藏元素的类。

.side-menu__list-item-desc-hide {
  transform: translateX(-10rem); 
}

对于#2,我以类似的方式通过单击事件隐藏菜单。

javascript代码是...

const foldBtn = document.querySelector('.side-menu__fold-btn');

let isHidden = false;

foldBtn.addEventListener('click', () => {

    if (isHidden == false) {
        sideMenu.classList.add('side-menu-hide');
        sideMenuList.innerHTML = '';
        isHidden = true;
        foldIcon.innerHTML = 'chevron_right'; 
    }
    else {
        sideMenu.classList.remove('side-menu-hide');
        isHidden = false;
        foldIcon.innerHTML = 'chevron_left';
        
        setTimeout(() => {
            sideMenuList.innerHTML = sideMenuListContent;
        }, 400); 
    }
});

CSS类是...

.side-menu-hide {
  transform: translateX(-100%); 
}

任何想法都可能导致此问题?

谢谢!

1 个答案:

答案 0 :(得分:1)

嗨,约翰,欢迎来到SO。代码有点过于复杂,实际上有很多很多简单的解决方案。

整个按钮的点击均是该行代码:)

foldBtn.addEventListener('click', () => {
    sideMenu.classList.toggle('side-menu-hide');
});

尝试一下。该错误已消失。我将在修改中添加更多链接和进一步的说明。

MDN: Element.classList

Element.classList.toggle是非常有用的功能,它可以为您节省很多行代码,并且在调试时可能会头疼。 IT基本上可以完全按照您使用addremove的方式进行操作。 “技巧”是它为您检查班级是否存在。因此,您不必编写if / else语句。如果没有课程,它将添加它。反之亦然。 有了这些新知识,您能想到如何重构其余代码的方式(提示:图标的类)吗?

编辑-错误的说明 您已将ul的完整子级硬编码为一个字符串,并将其存储在名为const的{​​{1}}中。首次单击按钮时(要隐藏菜单时),出于某种原因,您决定使用以下代码行销毁/删除“ ul”的“ innerHtml”:

sideMenuListContent

然后稍后再次单击按钮(菜单返回)时,您只需将sideMenuList.innerHTML = ''; 的{​​{1}}分配给先前定义的innerHtml(使用setTimeout进行所有操作)。

ul

但是在此过程中,您已经销毁了所有事件侦听器。这就是为什么您的JS代码不起作用的原因。这至少是多余的步骤(我希望在下面的评论中对此进行了解释),但不仅如此,它是将孩子附加到某些DOM元素上的“不是最好的方法”(至少可以这样说)。如果真的需要真正附加子项,则首先需要使用sideMenuListContent创建该子项,然后再使用setTimeout(() => { sideMenuList.innerHTML = sideMenuListContent; }, 400); 。 您可以在SO的thisthis答案中了解更多有关它的信息。 我知道希望我的回答是完整的,并且您对您的代码和DOM有更好的了解。