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
属性重置为 ""
(空字符串)来显示。
我正在尝试创建一个功能,当您单击一个按钮时,它会删除一个 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
属性重置为 ""
(空字符串)来显示。