如何解决无法在嵌套函数中打印正确的innerHTML消息
我正在制作一个食谱页面,其中有一系列相互关联的按钮和帖子。这些按钮具有配方类别的名称,例如饼图和蛋糕。当您单击“派”按钮时,只会显示归类为“派”的帖子。按钮和帖子都具有数据属性,这些属性的配方类别位于该属性中。
我可以使用它,但是,当您单击食谱类别按钮时,我遇到了问题,并且没有相应的帖子。为此,我创建了一个空的'#message'div,如果没有找到食谱发布,它将输出一条消息,如果有食谱发布,则会输出一个空字符串。
当我单击包含帖子的食谱按钮时,消息中将显示“无食谱”文本。同样奇怪的是,它似乎仅将正确的消息应用于最后一个按钮/帖子,在此示例中为“蛋糕”。
有人可以解释为什么这行不通吗?我知道这可能是作用域/关闭问题,但是我不确定发生了什么。
//BUTTONS
<section>
<button class="recipe_button" data-btncategory="Pie">
Pie
</button>
<button class="recipe_button" data-btncategory="Cake">
Cake
</button>
</section>
//POSTS
<div id="message"></div>
<section class="recipe" data-postcategory="Pie">
<h2>Pie Recipe</h2>
</section>
<section class="recipe" data-postcategory="Cake">
<h2>Cake Recipe</h2>
</section>
let posts = document.querySelectorAll(".recipe");
let postsArr = Array.from(posts);
let btn = document.querySelectorAll(".recipe_button");
let btnArray = Array.from(btn);
let message = document.getElementById("message");
btnArray.forEach((button) => {
button.onclick = (el) => {
let match = el.target.dataset.btncategory;
postsArr.filter(function(post,i) {
if (post.dataset.postcategory == match) {
posts[i].style.display = "grid";
<-- message not working properly -->
message.innerHTML = "";
} else {
posts[i].style.display = "none";
<-- message not working properly -->
message.innerHTML = "Sorry No Recipes Available";
}
});
}
});
解决方法
查看过滤器的运行方式。您将始终获得匹配的匹配项,而不匹配的匹配项-因此if和else代码将始终运行
您要执行的操作是在过滤器中隐藏/显示帖子,对于显示的内容返回true,而在隐藏时返回false
这样,如果不匹配,结果数组长度将为0,如果匹配则为1或更多
在确定是否显示任何内容以显示/隐藏消息之后,再显示另一个if / else
let posts = document.querySelectorAll(".recipe");
let postsArr = Array.from(posts);
let btn = document.querySelectorAll(".recipe_button");
let btnArray = Array.from(btn);
let message = document.getElementById("message");
btnArray.forEach((button) => {
button.onclick = (el) => {
let match = el.target.dataset.btncategory;
let found = postsArr.filter(function(post) {
if (post.dataset.postcategory == match) {
post.style.display = "grid";
return true;
} else {
post.style.display = "none";
return false;
}
}).length;
message.innerHTML = found ? "" : "Sorry No Recipes Available";
}
});
<section>
<button class="recipe_button" data-btncategory="Pie">
Pie
</button>
<button class="recipe_button" data-btncategory="Cake">
Cake
</button>
</section>
//POSTS
<div id="message"></div>
<section class="recipe" data-postcategory="Pie">
<h2>Pie Recipe</h2>
</section>
<section class="recipe" data-postcategory="Cake">
<h2>Cake Recipe</h2>
</section>
话虽如此,该消息永远不会显示Sorry No Recipes Available
,因为您的按钮可以保证显示一个按钮
这是使您的想法可行的直接方法。
它使用带有event delegation的事件监听器。
有关进一步的说明,请参见代码中的注释。
// Identifies DOM elements
const
btnsDiv = document.getElementById("btns"),posts = [...document.getElementsByClassName("recipe")],message = document.getElementById("message");
// Calls `filterPosts` when btnsDiv is clicked
btnsDiv.addEventListener("click",filterPosts);
// Defines `filterPosts`
function filterPosts(event){
// Ignores irrelevant clicks
if(!event.target.classList.contains("btn")){ return; }
// Shows message while there is no match
let match = false;
message.classList.remove("hidden");
// Remembers category
const category = event.target.dataset.category;
// Iterates through recipes
posts.forEach( (post) => {
// Hides recipe until it matches
post.classList.add("hidden");
// If recipe matches,shows it and notes the match
if(post.dataset.category == category) {
post.classList.remove("hidden");
match = true;
}
});
// If any match occurred,hides message
if(match == true){
message.classList.add("hidden");
}
}
.hidden{ display: none; }
<div id = "btns">
<button class="btn" data-category="Pie">Pie </button>
<button class="btn" data-category="Cake"> Cake </button>
<button class="btn" data-category="Pasta"> Pasta </button>
</div>
<div id="message" class="hidden">Sorry No Recipes Available</div>
<div class="recipe hidden" data-category="Pie">
<h2>Pie Recipe 1</h2>
</div>
<div class="recipe hidden" data-category="Cake">
<h2>Cake Recipe 1</h2>
</div>
<div class="recipe hidden" data-category="Cake">
<h2>Cake Recipe 2</h2>
</div>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。