querySelectorAll with forEach函数不适用于轮播幻灯片上的切换按钮

问题描述 投票:1回答:4

我在PHP中创建了一个模板部分,它使用fullpage.js将按钮复制到轮播中的每个幻灯片。模板部分有一个隐藏的div,应该为每张幻灯片打开导航。尝试下面的代码,我只能在第一张幻灯片上使用此按钮。我认为迭代的类名可能会有所帮助,但不确定为什么querySelectorAll不会这样做。任何建议赞赏......

http://www.pulsecreative-clients.com/staging/hogshead/#golf

    const clickOnMe = document.querySelectorAll(".course-button");

    let clickOnMe = document.querySelectorAll(".course-button"); 
    Array.from(clickOnMe).forEach(el => {
        el.addEventListener("click", e => { 
            let showBox = e.currentTarget.nextElementSibling;
            showBox.classList.toggle("open-nav"); 
        }); 
    });
.subnav-content {
    position: fixed;
    bottom: 15%;
    z-index: 1;
    box-sizing: border-box;
    padding: 10px;
    background-color: #000;
    display: none;
}

.golfcoursebutton {
    box-sizing: content-box;
    min-width: 30px;
    height: 30px;
    padding: 4px;
    margin: 4px;
    background-color: #fff;
    color: #000; 
    text-align: center;
}

.open-nav {
    display: block;
}
<div id="jump-button" class="jumpbuttons-container">
    <div class="subnav">
        <button class="course-button">
            JUMP TO <i class="fa fa-angle-up"></i>
        </button>
        <div class="subnav-content">
            <div style="display: flex;">
                <div class="golfcoursebutton"><a href="#golf/1">1</a></div>
                <div class="golfcoursebutton"><a href="#golf/2">2</a></div>
                <div class="golfcoursebutton"><a href="#golf/3">3</a></div>
                <div class="golfcoursebutton"><a href="#golf/4">4</a></div>
                <div class="golfcoursebutton"><a href="#golf/5">5</a></div>
                <div class="golfcoursebutton"><a href="#golf/6">6</a></div>
            </div>

            <div style="display: flex;">
                <div class="golfcoursebutton"><a href="#golf/7">7</a></div>
                <div class="golfcoursebutton"><a href="#golf/8">8</a></div>
                <div class="golfcoursebutton"><a href="#golf/9">9</a></div>
                <div class="golfcoursebutton"><a href="#golf/10">10</a></div>
                <div class="golfcoursebutton"><a href="#golf/11">11</a></div>
                <div class="golfcoursebutton"><a href="#golf/12">12</a></div>
            </div>

            <div style="display: flex;">
                <div class="golfcoursebutton"><a href="#golf/13">13</a></div>
                <div class="golfcoursebutton"><a href="#golf/14">14</a></div>
                <div class="golfcoursebutton"><a href="#golf/15">15</a></div>
                <div class="golfcoursebutton"><a href="#golf/16">16</a></div>
                <div class="golfcoursebutton"><a href="#golf/17">17</a></div>
                <div class="golfcoursebutton"><a href="#golf/18">18</a></div>
            </div>
        </div>
    </div>
</div>

编辑更新解决方案

javascript html css3
4个回答
1
投票

我在PHP中创建了一个模板部分,它使用fullpage.js将按钮复制到轮播中的每个幻灯片。

不幸的是,重复使用代码会引发错误。如果我们查看您的来源,我们会看到:

div.jump-button
    button.course-button
    div.subnav-content

<script>
    const clickOnMe = ...
</script>

这重复约20次。

问题是const只能宣布一次。在那之后,JS将抛出一个错误。事实上,如果我们查看控制台,我们就会看到:

enter image description here

基本上,在第一次声明const clickOnMe之后,会抛出一个错误。这就是为什么只有第一个有效的原因。我会考虑移动(并整合)<script>,你将clickOnMe定义到底部,并在加载所有HTML后调用它。

Edit:

关于你的评论,我看到你所指的是什么。您现在通过将事件绑定移动到底部来正确查询所有元素(太棒了!),但您的事件监听器也需要更新。实际上,当切换classList时,通过引用here对象来回答event(由@ jeyko-caicedo提供)。

一个更完整的答案是你需要引用事件对象(引用被点击的元素),然后查询兄弟subnav-content。一种方式是jeyko建议(通过关闭forEach)。另一个是在事件处理程序中使用:1向上走DOM树(使用e.currentTarget.parentNode)或2:直接引用元素,如e.currentTarget.nextElementSibling

let clickOnMe = document.querySelectorAll(".course-button"); 
Array.from(clickOnMe).forEach(function(el) { // updated `e` to `el`
    el.addEventListener("click", (e) => { 
        let showBox = e.currentTarget.nextElementSibling;
        showBox.classList.toggle("open-nav"); 
    }); 
});

2
投票

querySelectorAll不返回数组,所以它没有forEach。幸运的是,你可以使用Array.from轻松地创建一个阵列:

// change this
clickOnMe.forEach(...
// to this
Array.from(clickOnMe).forEach(...

2
投票

您正在选择文档的第一个

document.querySelector(".subnav-content");

什么时候它应该是第一个元素

e.querySelector(".subnav-content");

1
投票

querySelectorAll返回NodeList。它本质上只是一个DOM节点数组,但它不支持您期望它拥有的所有数组方法。您必须先将其强制转换为数组,或者手动将其转换为数组,而不是使用forEach。

© www.soinside.com 2019 - 2024. All rights reserved.