微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法在嵌套函数中打印正确的innerHTML消息

如何解决无法在嵌套函数中打印正确的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 举报,一经查实,本站将立刻删除。