Javascript style.display 在我使用我的函数时没有更新样式

Javascript style.display is not updating the style when I use my function

我正在尝试创建一个功能,当您单击一个按钮时,它会删除一个 div,并添加另一个 div,然后当您再次按下该按钮时,它会删除那个div 和那个不同的 div。这大约进行了 4 次,直到我到达终点,然后当我再次按下按钮时它应该回到开头。我做错了什么?

let switchData = (selected, removed1, removed2, removed3) => {
    if(!document.getElementById("show-next-data")) {
        return;
    }
    document.getElementById("show-next-data").addEventListener("click", ()=> {
        let infoData = [selected, removed1, removed2, removed3];   

        document.getElementById(selected).style.display = "block";
        /*for (let i = 0; i < infoData.length; i++) {
            document.getElementById(infoData[i]).style.display = "none";
        }*/
        document.getElementById(removed1).style.display = "none";
        document.getElementById(removed2).style.display = "none";
        document.getElementById(removed3).style.display = "none";

    });
}
switchData("dog-care", "cat-care", "youtube-media", "table-data");
switchData("cat-care", "dog-care", "youtube-media", "table-data");
switchData("youtube-media", "cat-care", "dog-care", "table-data");
switchData("table-data", "cat-care", "youtube-media", "dog-care");
<div id="info-content">
    <div id="dog-care">
        <h1 id="animal-info">How To Take Care Of My Dog:</h1>
        <h4 id="animal-info">Make sure your dog is well fed 
        </h4>
    </div>
    <div id="cat-care">
        <h1 id="animal-info">How To Take Care Of My Cat:</h1>
        <h4 id="animal-info">Make sure your cat is well fed 
        </h4>
    </div>
    <div id="youtube-media">
        <iframe width="200%" height="300%" src="https://www.youtube.com/embed/Yzv0gXqoCkc" title="YouTube video player" 
        frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" ></iframe>
    </div>
    <div id="table-data">

        <h1>table goes here</h1>

    </div>

    <h1 id="show-next-data">︾</h1>
  </div>

问题是您添加了事件侦听器,而不是实际更改页面上的任何内容。调用函数 switchData() 将 EventHandler 添加到 show-next-data。当您单击 div 时,将触发 EventHandler 中的代码。在此之前什么也没有发生。

但这似乎不是您想要做的。因为当你多次调用 switchData() 时,你只是添加了更多的 EventHandlers。而且您无法确定 EventHandler 的触发顺序,因此您的代码变得不可预测。

您可能想要做的只是摆脱事件处理程序。那么您的函数将如下所示:

let switchData = (selected, removed1, removed2, removed3) => {
    if(!document.getElementById("show-next-data")) {
        return;
    }
    let infoData = [selected, removed1, removed2, removed3];   

    document.getElementById(selected).style.display = "block";
    /*for (let i = 0; i < infoData.length; i++) {
        document.getElementById(infoData[i]).style.display = "none";
    }*/
    document.getElementById(removed1).style.display = "none";
    document.getElementById(removed2).style.display = "none";
    document.getElementById(removed3).style.display = "none";
}

现在调用该函数实际上做了一些事情,但点击 show-next-data div 当然没有。所以你仍然需要一个 EventHandler(顺便说一句,EventHandler 和 EventListener 在这里意味着同样的事情)。因此,您可以在 switchData() 函数外部添加 EventHandler,然后从 EventHandler 内部调用 switchData

与您当前代码的不同之处在于,switchData 函数当前添加了新的 EventListener,当单击 div 时将触发该事件监听器。我建议在函数外添加一个 EventHandler,然后调用该函数。这可能是您首先想要的,并且不会在每次函数调用时都创建新的事件处理程序,从而使代码变得非常不可预测。

剩下的唯一问题是确定何时要显示哪些数据。目前你只需 hard-coded 它调用函数 4 次。这是糟糕的设计,因为它很难返回并更改某些内容(例如添加新部分、删除旧部分等。

为此,您可以遍历“info-content”div 的所有 children 个节点,并检查当前可见的节点和不可见的节点,然后显示下一个节点什么的。

在结束这篇长回复之前,我想给你一些最后的提示:

  • "show-next-data" 应该是一个按钮吧?把它变成一个按钮。不要将其设为 h1 header。浏览器甚至 headers 都不接受 onclick 实际上可能存在一些问题,但我没有对此进行测试。但无论如何请将其设为按钮元素,以使您的代码更具可读性。
  • 不要用“let”声明一个函数。 “让”是指您以后要再次更改的变量。对于函数,您最好使用“const”(与 let 相同,除了它不允许您稍后更改变量)或正常函数语法(即“function switchData(...) { ... }”或“const switchData = (...) { ... }").
  • 而不是“removed1、removed2、removed3”,您可能希望稍后更改函数以隐藏 4 div 秒或仅隐藏 2 div 秒(如果您的网站布局发生变化)。因此,更好的实现功能的方法是使用 rest parameter: switchData(selected, ...removed)。 “removed”现在是一个数组。您仍然会像 rn 那样调用 switchData,即 switchData("dog-care", "cat-care", "youtube-media", "table-data"); 仍然是调用该函数的方式,但在函数 body 中您现在将有 removed == ["cat-care", "youtube-media", "table-data"]。然后你可以像现在一样循环遍历数组并隐藏每个元素。这使您可以轻松更改参数的数量,而无需更改整个函数。

少写多做,让生活更轻松:

const divs = document.querySelectorAll("#info-content>div");
var idx=0;
divs.forEach(nextDiv); // step through all divs once to hide them all but the first ...
document.getElementById("show-next-data").onclick=nextDiv;
function nextDiv(){
 divs[idx].style.display="none";
 divs[idx=(idx+1)%divs.length].style.display="";
};
<div id="info-content">
  <div id="dog-care">
    <h1 id="animal-info">How To Take Care Of My Dog:</h1>
    <h4 id="animal-info">Make sure your dog is well fed
    </h4>
  </div>
  <div id="cat-care">
    <h1 id="animal-info">How To Take Care Of My Cat:</h1>
    <h4 id="animal-info">Make sure your cat is well fed
    </h4>
  </div>
  <div id="youtube-media">
    <iframe width="200%" height="300%" src="https://www.youtube.com/embed/Yzv0gXqoCkc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"></iframe>
  </div>
  <div id="table-data">
    <h1>A table goes here</h1>
  </div>

  <button id="show-next-data">︾</button>
</div>

函数nextDiv()显示从idx开始的下一个div(集合divs中的索引号(用选择器#info-content>div找到) . 当前 div 被隐藏,idx 增加,下一个 div 通过将其 .style.display 属性重置为 ""(空字符串)来显示。