css 下拉菜单,打开与mouseover和单击事件只 Flink

q3aa0525  于 2023-06-25  发布在  SEO
关注(0)|答案(1)|浏览(302)

我试图创建一个下拉菜单,点击一个按钮或悬停在它打开。
使用我的代码,点击或悬停时下拉菜单会 Flink 。换句话说,显示和不透明度不会停留。我希望能够要么点击或悬停在下拉菜单标题显示下拉菜单。
HTML:

<div class="menu-link dropdown">
    <p class="dropdown-select">Item</p>
    <div class="dropdown-menu">
        <div class="top">
            <div class="arr-wrap">
                <div class="arr"></div>
            </div>
        </div>
        <p class="menu-link"><a href="./link.html">Item</a></p>
        <p class="menu-link"><a href="./link.html">Item</a></p>
        <p class="menu-link"><a href="./item.html">Item</a></p>
        <p class="menu-link"><a href="./item.html">Item</a></p>
        <p class="menu-link"><a href="./item.html">Item</a></p>
    </div>
</div>

CSS:

.menu-link {
    width: 100px;
    text-align: right;
    transition: 0.3s;
    margin-right: 25px;
}
.dropdown .menu-link {
    width: 200px;
    text-align: left;
    padding: 15px 0px;
    margin-left: 35px;
    height: 25px;
}
.dropdown-menu {
    position: absolute;
    top: 100px;
    opacity: 0;
    width: fit-content;
    height: fit-content;
    margin-left: -8px;
    width: fit-content;
    flex-flow: column;
    z-index: 3;
    border-radius: 10px;
    transition: 0.2s;
    background-color: white;
    box-shadow: 2px 2px 10px lightgrey;
    display: none;
}

.dropdown-select {
    height: fit-content;
}

.menu .menu-link {
    width: 100px;
    text-align: right;
    transition: 0.3s;
    margin-right: 25px;
}
.dropdown .menu-link {
    width: 200px;
    text-align: left;
    padding: 15px 0px;
    margin-left: 35px;
    height: 25px;
}
.dropdown-menu {
    position: absolute;
    top: 100px;
    opacity: 0;
    width: fit-content;
    height: fit-content;
    margin-left: -8px;
    width: fit-content;
    flex-flow: column;
    z-index: 3;
    border-radius: 10px;
    transition: 0.2s;
    background-color: white;
    box-shadow: 2px 2px 10px lightgrey;
    display: none;
}
.dropdown-select {
    height: fit-content;
}
.display {
    display: flex;
    opacity: 1;
    z-index: 3;
}

JavaScript:

document.addEventListener('DOMContentLoaded', load, false);

function load() {
    document.getElementsByClassName("dropdown")[0].addEventListener("click", dropdown, false);
    document.getElementsByClassName("dropdown")[0].addEventListener("mouseover", dropdown, false);
}

function dropdown() {
    var dropdown = document.getElementsByClassName("dropdown-menu")[0];
    
    dropdown.classList.toggle("display");
}
dldeef67

dldeef671#

这是一个很容易犯的错误:菜单 Flink 是因为每次鼠标在元素上移动一点时都会触发“mouseover”。所以当你把鼠标移到下拉菜单上时,鼠标移过它会不断调用函数来切换“display”类,所以它会打开,然后关闭,然后再次打开,如此类推,直到无穷大。
要修复它,您应该尝试以下操作:

document.getElementsByClassName("dropdown")[0].addEventListener("click", dropdownClick, false);
document.getElementsByClassName("dropdown")[0].addEventListener("mouseenter", dropdownMouseEnter, false);
document.getElementsByClassName("dropdown")[0].addEventListener("mouseleave", dropdownMouseLeave, false);

function dropdownClick() {
    var dropdown = document.getElementsByClassName("dropdown-menu")[0];
    dropdown.classList.toggle("display");
}

function dropdownMouseEnter() {
    var dropdown = document.getElementsByClassName("dropdown-menu")[0];
    dropdown.classList.add("display");
}

function dropdownMouseLeave() {
    var dropdown = document.getElementsByClassName("dropdown-menu")[0];
    dropdown.classList.remove("display");
}

这不是最好的方式去做一个下拉菜单,但这将使你的工作更好,更像你最初的意图。
如前所述,mouseover将在每次鼠标光标移动到元素上时触发,而mouseenter将在鼠标第一次悬停元素时触发一次,而mouseleave将在鼠标不再悬停元素时再次触发它。
我擅自修改了一下让它更实用。结果见下文:

function _(id) { return document.getElementById(id); }

_("dropdown1").addEventListener("click", dropdownClick, false);
_("dropdown1").addEventListener("mouseenter", dropdownMouseEnter, false);
_("dropdown1").addEventListener("mouseleave", dropdownMouseLeave, false);

function dropdownClick() {
    _("dropdown1").classList.toggle("show");
}

function dropdownMouseEnter() {
    _("dropdown1").classList.add("show");
}

function dropdownMouseLeave() {
    _("dropdown1").classList.remove("show");
}
*, *::before, *::after {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
    font-family: 'Open Sans', sans-serif;
    font-weight: 500;
    margin: 0;
    padding: 0;
}

body {
    background-color: #eee;
    margin: 0.5rem;
}

.dropdown-wrap {
    position: absolute;
}

.dropdown-wrap .menu-link {
    padding: 1rem;
}

.dropdown-wrap .dropdown-select {
    padding: 1rem;
    cursor: pointer;
    width: 7rem;
    background-color: white;
    border-radius: 0.8rem;
}

.dropdown {
    min-width: 12rem;
    text-align: left;
    position: absolute;
    opacity: 0;
    display: flex;
    flex-flow: column;
    left: 0;
    top: calc(100% + 0.5rem);
    z-index: 3;
    border-radius: 0.8rem;
    transition: 0.2s;
    background-color: white;
    box-shadow: 2px 2px 10px lightgrey;
    transform-origin: top left;
    scale: 0;
}

.dropdown-wrap.show .dropdown {
    scale: 1;
    opacity: 1;
}
<div id="dropdown1" class="dropdown-wrap">
    <p class="dropdown-select">Item</p>
    <div class="dropdown">
        <p class="menu-link"><a href="./link.html">Item</a></p>
        <p class="menu-link"><a href="./link.html">Item</a></p>
        <p class="menu-link"><a href="./item.html">Item</a></p>
        <p class="menu-link"><a href="./item.html">Item</a></p>
        <p class="menu-link"><a href="./item.html">Item</a></p>
    </div>
</div>

相关问题