我正在过滤通过我们的CMS创建的组件提供的目录,但我无法控制该组件.我试图过滤的每个目录成员的标记都在类为d-one的div中.我正在使用的脚本工作,只是它只显示我想要过滤的项目,当它们是卡片中的第一个div时.如果标签不是卡片中的第一件物品,我想知道如何过滤标签.

例如,在下面的代码中,筛选器按钮一直有效,直到您按下All Employees按钮.然后只显示Christina的名字,因为"Employee"是她卡片上的第一个标签.

<h1>Employees</h1>
    <p>
      <button onclick="queryButton('FULL TIME')">Full Time</button>
      <button onclick="queryButton('PART TIME')">Part Time</button>
      <button onclick="queryButton('SEASONAL')">Seasonal</button>
      <button onclick="queryButton('EMPLOYEE')">All Employees</button>
    </p>

    <div class="cpFeed">
      <div class="card-news">
        <div style="display: none;" class="d-none">Part Time</div>
        <div style="display: none;" class="d-none">Employee</div>
        <div>Adele</div>
      </div>
      <div class="card-news">
        <div style="display: none;" class="d-none">Full Time</div>
        <div style="display: none;" class="d-none">Employee</div>
        <div>Agnes</div>
      </div>
      <div class="card-news">
        <div style="display: none;" class="d-none">Seasonal</div>
        <div style="display: none;" class="d-none">Employee</div>
        <div>Billy</div>
      </div>
      <div class="card-news">
        <div style="display: none;" class="d-none">Part Time</div>
        <div style="display: none;" class="d-none">Employee</div>
        <div>Bob</div>
      </div>
      <div class="card-news">
        <div style="display: none;" class="d-none">Seasonal</div>
        <div style="display: none;" class="d-none">Employee</div>
        <div>Calvin</div>
      </div>
      <div class="card-news" class="d-none">
        <div style="display: none;" class="d-none">Employee</div>
        <div style="display: none;" class="d-none">Seasonal</div>
        <div>Christina</div>
      </div>
      <div class="card-news" class="d-none">
        <div style="display: none;" class="d-none">Part Time</div>
        <div style="display: none;" class="d-none">Employee</div>
        <div>Cindy</div>
      </div>
    </div>

    <script>
      function queryButton(queryFilter) {
        var filter, feedDiv, cardDiv, unnamedDiv, i, txtValue;
        filter = queryFilter;
        feedDiv = document.querySelector("div.cpFeed");
        cardDiv = feedDiv.querySelectorAll("div.card-news");
        for (i = 0; i < cardDiv.length; i++) {
          unnamedDiv = cardDiv[i].querySelector(".d-none");
          [0];
          txtValue = unnamedDiv.textContent || div.div.innerHTML;
          if (txtValue.toUpperCase().indexOf(filter) > -1) {
            cardDiv[i].style.display = "";
          } else {
            cardDiv[i].style.display = "none";
          }
        }
      }
    </script>

我try 在下面的代码行中将querySelector更改为querySelectorAll.这个

unnamedDiv = cardDiv[i].querySelectorAll(".d-none");

这会导致按钮的功能停止工作.我在控制台中看到以下错误:

Uncaught ReferenceError: div is not defined
    at queryButton (example.html:56:44)
    at HTMLButtonElement.onclick (example.html:5:45)

我是不是漏掉了什么?

推荐答案

我可以看到您的代码中存在一些问题,所以这里有一个解释.

首先,这是我自己写<script>的方法,希望能让它更容易理解.如果你不想这样做,你可以不这样做.此块不会更改代码所做的任何操作.

function queryButton(filter) {

  let feedDiv = document.querySelector("div.cpFeed"), // Get's the first <div> with a class of cpFeed
      cardDiv = feedDiv.querySelectorAll("div.card-news"), // Get's all <div> children of feedDiv with a class of card-news
      unnamedDiv, // pre-sets to a variable to undefined
      i, // pre-sets to a variable to undefined
      txtValue // pre-sets to a variable to undefined

  for (i = 0; i < cardDiv.length; i++) { // Sets a previously undefined variable to 0, to be looped through

    unnamedDiv = cardDiv[i].querySelector(".d-none") // Gets first of any element, child of the indexed (i) cardDiv, with a class d-none

    [0] // Does nothing

    txtValue = unnamedDiv.textContent || div.div.innerHTML // returns unnamedDiv.textContent if unnamedDiv.textContent is not undefined. Otherwise, returns div.div.innerHTML, which is not assigned, so it will error out.

    // Returned error from div.div.innerHTML:
    // Uncaught ReferenceError: div is not defined
    // at queryButton (example.html:56:44)
    // at HTMLButtonElement.onclick (example.html:5:45)

    if (txtValue.toUpperCase().indexOf(filter) > -1) { // Checks whether an uppercase string's index of the filter param is greater than -1

      cardDiv[i].style.display = "" // Sets the indexed (i) cardDiv's display to empty / it's default value.

    } else {

      cardDiv[i].style.display = "none" // Sets the indexed (i) cardDiv's display to "none"

    }
  }
}

希望仅通过上面的 comments ,您就能够以自己的方式解决您的错误.

当然,如果您只想要一个可工作的示例,这里是我实际让脚本工作的例子.

function queryButton(filter) {

  // Switched to const since these variable will not be changed
  const feedDiv = document.querySelector(".cpFeed"), // Get's the first of any element with a class of cpFeed
        cardDivs = feedDiv.querySelectorAll(".card-news") // Get's all of any element, children of feedDiv, with a class of card-news
        // unnamedDiv, – Removed to be assigned per cardDiv later
        // i, – Removed because for loop is swtiched to forEach()
        // txtValue – Removed to be assigned per cardDiv later

  // New forEach() instead of for loop
  cardDivs?.forEach((cardDiv) => {
    
    // Adding variables as const since they do not change
    const unnamedDivs = cardDiv.querySelectorAll(".d-none") // Gets all of any element, child of the the current cardDiv, with a class d-none
    
    let display = "none" // preset to none
    
    unnamedDivs?.forEach((unnamedDiv) => {
      
      // Checks whether display has already succeeded in one of the unnamedDivs
      if (display !== "none") display = unnamedDiv.textContent.toUpperCase() === filter ? "" : "none"

      // Always returns something
      cardDiv.style.display = display

    })
  })
}

正如您所看到的,我在这里做了一些事情来简化代码,使其更具可读性,并添加了一些安全判断,这样我们就可以避免尽可能多的错误.

我还注意到您的HTML中有几个错误:

<!-- Two class attributes will break things -->
<!-- BEFORE: <div class="card-news" class="d-none"> -->
<div class="card-news">
      
  <div style="display: none;" class="d-none">Employee</div>
      
  <div style="display: none;" class="d-none">Seasonal</div>
      
  <div>Christina</div>
      
</div>
    
<!-- Two class attributes will break things -->
<!-- BEFORE: <div class="card-news" class="d-none"> -->
<div class="card-news">
      
  <div style="display: none;" class="d-none">Part Time</div>
      
  <div style="display: none;" class="d-none">Employee</div>
      
  <div>Cindy</div>
      
</div>

我还做了一支CodePen,这样你就可以看到它的运行情况:Go to CodePen

Javascript相关问答推荐

如何访问Json返回的ASP.NET Core 6中的导航图像属性

如何在表格上拥有水平滚动条,在正文页面上拥有垂直滚动条,同时还对html表格的标题使用位置粘性?

从mat—country—select获取整个Country数组

如何解决chrome—extension代码中的错误,它会实时覆盖google—meet的面部图像?'

如何在Javascript中的控制台上以一行形式打印循环的结果

用JavaScript复制C#CRC 32生成器

如何从Intl.DateTimeFormat中仅获取时区名称?

为什么Mutations 观察器用微任务队列而不是macrotask队列处理?

我怎么才能得到Kotlin的密文?

S文本内容和值不必要的不同

try 使用PM2在AWS ubuntu服务器上运行 node 进程时出错

使用类型:assets资源 /资源&时,webpack的配置对象&无效

我正在试着做一个TicTacToe Ai来和我玩.但是,我试着在第一个方块被点击时出现一个X,然后在第二个方块之后出现一个O

是否可以在不更改组件标识的情况下换出Reaction组件定义(以维护状态/引用等)?如果是这样的话,是如何做到的呢?

Clip-Path在网页浏览器(Mozilla、Edge、Chrome)上不能正常工作,但在预览版Visual Code Studio HTML、CSS、JS上却能很好地工作

Angel Auth Guard-用户只有在未登录时才能访问登录页面,只有在登录时才能访问其他页面

如何向内部有文本输入字段的HTML表添加行?

Refine.dev从不同的表取多条记录

在不使用AJAX的情况下将JavaScript数组值传递给Laravel控制器?

JQuery-无法 Select 使用elementor添加的元素的值