【问题标题】:Need help toggling dropdown menus using the same class (Javascript)需要帮助使用相同的类切换下拉菜单(Javascript)
【发布时间】:2018-03-19 00:26:03
【问题描述】:

我试图让它适用于使用类名“.sub-menu-parent”的所有元素,但我只能让它适用于它的第一个实例。

我尝试使用带有 parentClass 索引的 for 循环,但它似乎不起作用。 '.sub-menu-child' 类也是如此。

HTML

        <nav>
            <div class="row">
                <img src="resources/img/logos/HTH_Logo_1_2.png" alt="A logo that says 'hearts that heal'" class="logo">
                <ul class="main-nav">
                    <li><a href="index.html">Home</a></li>
                    <li><a href="#" class="sub-menu--parent">About Us <i class="ion-android-arrow-dropdown"></i></a>
                        <ul class="drop-down-main sub-menu--child">
                            <li><a href="#">Who We Are</a></li>
                            <li><a href="#">Mission Statement</a></li>
                            <li><a href="#">Vision Statement</a></li>
                            <li><a href="#">Our Values</a></li>
                            <li><a href="#">Goals</a></li>
                            <li><a href="#">Objectives</a></li>
                        </ul>
                    </li>
                    <li><a href="#" class="sub-menu--parent">Photo Gallery <i class="ion-android-arrow-dropdown"></i></a>
                        <ul class="drop-down-main sub-menu--child">
                            <li><a href="#">Group Photos</a></li>
                            <li><a href="#">Retreat Photos</a></li>
                            <li><a href="#">Members Photos</a></li>
                            <li><a href="#">Honorary Members Photos</a></li>
                            <li><a href="#">Our Beloved Children</a></li>
                            <li><a href="#">Activities and Sponsorship Photos</a></li>
                        </ul>
                    </li>
                    <li><a href="contact.html">Contact</a></li>

                </ul>
            </div>
        </nav>

CSS

/* ----- MAIN NAV ----- */

.main-nav   {
    float: right;
    list-style-type: none;
    margin-top: 32.5px;
}

.main-nav li    {
    display: inline;
    text-align: center;

}

.main-nav li a:link, 
.main-nav li a:visited {
    text-decoration: none;
    color: #fff; 
    padding: 5px 10px;
    font-weight: 400;
    font-size: 80%;  
    background-color: #c95a6c;  /* #484066 */
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
}

.main-nav li a:hover, 
.main-nav li a:active {
    background-color: #fff;
    color: #c95a6c;
}

/* ----- For colors ----- */

.main-nav-color:focus {
    color: #c95a6c !important; 
    background-color: #fff !important;  /* #484066 */
}


/* ----- NESTED NAV ----- */

.drop-down-main {
    position: absolute;
    z-index: 9990;
    background-color: #fff; 
    display: none;
    margin-top: 5px;
    border: 1px solid #484066;
    border-top: none;
}

.show {
    display: block;
}

.drop-down-main li  {
    display: block;
    text-align: left;
    border-bottom: 1px solid #484066;
    width: 100%;

}

.drop-down-main li a:link, 
.drop-down-main li a:visited {
    display: block;
    text-decoration: none;
    color: #c95a6c; 
    font-weight: 400;
    font-size: 80%;  
    background: none;  /* #484066 */
    border-radius: 0;
    padding: 5px 24px 5px 5px;
}

.drop-down-main li:hover, 
.drop-down-main li:active {
    background-color: #c95a6c;
}

.drop-down-main li a:hover, 
.drop-down-main li a:active {
    color: #fff;
}

.drop-down-main li:first-child {
    margin-top: 10px;
    border-top: 1px solid #484066;
}

.drop-down-main li:last-child {
    border: none;
}

Javascript

var menuToggle = (function() {
    var DOMstrings = {
        displayToggle: 'show',
        dropParent: '.sub-menu--parent',
        dropChild: '.sub-menu--child',
        colorToggle: 'main-nav-color',
    };

    var parentClass = document.querySelector(DOMstrings.dropParent);
    var childClass = document.querySelector(DOMstrings.dropChild);


    parentClass.addEventListener('click', toggleDropdown, false);

    function toggleDropdown() {
        childClass.classList.toggle(DOMstrings.displayToggle);
        parentClass.classList.toggle(DOMstrings.colorToggle);
    };

    window.addEventListener('click', function(event) {
        if(event.target !== parentClass && event.target.parentNode !== parentClass) {
            childClass.classList.remove(DOMstrings.displayToggle);
            parentClass.classList.remove(DOMstrings.colorToggle);
        }
    });   
})();

我也尝试过使用 querySelectorAll,但似乎你不能使用 classList 方法。

【问题讨论】:

  • 你能发布你的css吗?
  • @JonathanChaplin 使用 css 更新
  • 我已经更新了我的答案,看看它是否适合你。

标签: javascript html css


【解决方案1】:

你应该使用querySelectorAll

基于此答案:Add event listener to DOM elements based on class

document.querySelector('.class-name'); 只会选择具有class='class-name' 的第一个元素。 要为所有此类元素添加事件侦听器,请使用 querySelectorAll()

然后更新你附加监听器的代码。

var parentClasses = document.querySelectorAll(DOMstrings.dropParent);

for (var i = 0; i < parentClasses.length; i++) {
    parentClasses[i].addEventListener('click', setupEventListener(parentClasses[i]), false);
}

function setupEventListener(element){
    return function(){
        toggleDropdown(element);
    }
}

function toggleDropdown(element) {
    // since `ul` is a sibling of `a` 
    element.nextElementSibling.classList.toggle(DOMstrings.displayToggle);
    element.classList.toggle(DOMstrings.colorToggle);
};

我相信这应该适用于您当前的实现,但是这不包括用于关闭显示的代码。

【讨论】:

  • 当我输入上面的代码时出现此错误:未捕获的类型错误:无法读取 HTMLAnchorElement 的 toggleDropdown (scripts.js:61) 处未定义的属性 'children'。 (scripts.js: 52)
  • 哦,我明白了,因为您在 a 元素中有 parent 类。我会更新我的答案。
  • 谢谢,但更新代码仍然出现错误:无法读取未定义的属性“nextElementSibling”
  • 我再次更新了我的答案,我在 jsfiddle 中尝试过,我会尝试解决关闭显示的问题。
  • 谢谢,这适用于使用元素打开和关闭它。为什么这与前面的示例不同?你不只是通过另一个函数返回一个函数吗?是什么让这个工作,而不是其他方式?这让我有点困惑。
猜你喜欢
  • 2017-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
相关资源
最近更新 更多