如何将 search/filter 用于使用 JavaScript 从 JSON 数据生成的 HTML Div?

How to use search/filter for HTML Divs generated from JSON data using JavaScript?

我正在尝试为从 JSON 数据生成的 links/divs 添加过滤器。

如果数据不是通过 JSON 格式生成的,我已经有一个在这里工作的搜索过滤器没有问题。但我真的需要使用 JSON 来加快加载和处理速度。

问题是,这样做时无法过滤链接。它应该根据 <a></a> 标签内的文本过滤 div,包括 <span>..

内的一些隐藏文本

在此示例中,它只能过滤 JSON 中的第一项,但不能过滤其余项。

// Links Filter
var input = document.getElementById("search-filter-cards");
input.addEventListener("input", searchFilterDivsMenu);

function searchFilterDivsMenu(e) {
  var filter = e.target.value.toUpperCase();
  var list = document.getElementById("links-list");
  var divs = list.getElementsByTagName("div");
  for (var i = 0; i < divs.length; i++) {
    var a = divs[i].getElementsByTagName("a")[0];
    if (a) {
      if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
        divs[i].style.display = "";
      } else {
        divs[i].style.display = "none";
      }
    }
  }
}

// JSON Data for each links
const maincards = {
  "linksList": [{
      'name': 'Java Bookmarks',
      'title': 'Java Bookmarks',
      'favicon': '../assets/links-favicons/java-bookmarks.png',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel="noopener noreferrer" target="_blank"'
    },
    {
      'name': 'Chrono',
      'title': 'Chrono',
      'favicon': '../assets/links-favicons/chrono.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel="noopener noreferrer" target="_blank"'
    },
    {
      'name': 'Kanban (May)',
      'title': 'EDEN Kanban',
      'favicon': '../assets/links-favicons/kanban.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out, Kanban board',
      'linkattributes': 'rel="noopener noreferrer" target="_blank"'
    },
  ]
};

const createMainCardLinks = ({
  name,
  title,
  favicon,
  url,
  tags,
  linkattributes
}) => `
    <div class="card link-container">
      <img class="link-img" src="${favicon}"/>
      <a class="link-title stretched-link" href="${url}" ${linkattributes} title="${title}">${name} <span class="h-0">${tags}</span></a>
    </div>
  `;

const links = maincards.linksList.map(createMainCardLinks);
links.forEach(links => {
  document.getElementById("load-json-data").innerHTML += links;
});
.h-0 {
  display: none;
}
<body>
  <input id="search-filter-cards" type="text" autocomplete="off" placeholder="Type here to search">
  <div id="links-list">
    <div class="link-headers"><a class="mb-0">Sample Links</a></div>
    <div id="load-json-data"></div>
  </div>
</body>

我是 JS 的初学者,我有一段时间没弄清楚这个问题。无论如何,提前感谢您的帮助。

我花了很长时间才注意到你得到了 links-list 中的所有 div,而不是 load-json-data

这是一个改进的版本。它被简化了,因为我只在 load-json-data 中切换 div,所以它有效

// Links Filter
var input = document.getElementById("search-filter-cards");
input.addEventListener("input", searchFilterDivsMenu);

function searchFilterDivsMenu(e) {
  const filter = e.target.value.toUpperCase();
  const cards = document.querySelectorAll("#links-list .card");
  cards.forEach(card => {
    var a = card.querySelector("a");
    // console.log(filter, "|", a.textContent.toUpperCase(), "|", a.textContent.toUpperCase().indexOf(filter))
    card.hidden = !a || (filter && a.textContent.toUpperCase().indexOf(filter) === -1);
  })
}

// JSON Data for each links
const maincards = {
  "linksList": [{
      'name': 'Java Bookmarks',
      'title': 'Java Bookmarks',
      'favicon': '../assets/links-favicons/java-bookmarks.png',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel="noopener noreferrer" target="_blank"'
    },
    {
      'name': 'Chrono',
      'title': 'Chrono',
      'favicon': '../assets/links-favicons/chrono.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel="noopener noreferrer" target="_blank"'
    },
    {
      'name': 'Kanban (May)',
      'title': 'EDEN Kanban',
      'favicon': '../assets/links-favicons/kanban.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out, Kanban board',
      'linkattributes': 'rel="noopener noreferrer" target="_blank"'
    },
  ]
};

const createMainCardLinks = ({
  name,
  title,
  favicon,
  url,
  tags,
  linkattributes
}) => `
    <div class="card link-container">
      <img class="link-img" src="${favicon}"/>
      <a class="link-title stretched-link" href="${url}" ${linkattributes} title="${title}">${name} <span class="h-0">${tags}</span></a>
    </div>
  `;

const links = maincards.linksList.map(createMainCardLinks);
document.getElementById("load-json-data").innerHTML = links.join("")
.h-0 {
  display: none;
}
<input id="search-filter-cards" type="text" autocomplete="off" placeholder="Type here to search">
<div id="links-list">
  <div class="link-headers"><a class="mb-0">Sample Links</a></div>
  <div id="load-json-data"></div>
  <div class="card link-container">
    <img class="link-img" src="../assets/links-favicons/plus.ico" />
    <a class="link-title stretched-link" href="#" rel="noopener noreferrer" target="_blank" title="Plus">Plus <span class="h-0">Quick Links</span></a>
  </div>
  <div class="card link-container">
    <img class="link-img" src="../assets/links-favicons/google.ico" />
    <a class="link-title stretched-link" href="#" rel="noopener noreferrer" target="_blank" title="Google">Google <span class="h-0">Quick Links</span></a>
  </div>
</div>

我用了jquery追加,你也可以用javascript

const dataJSON = {
  "linksList": [{
      'name': 'Java Bookmarks',
      'title': 'Java Bookmarks',
      'favicon': '../assets/links-favicons/java-bookmarks.png',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel="noopener noreferrer" target="_blank"'
    },
    {
      'name': 'Chrono',
      'title': 'Chrono',
      'favicon': '../assets/links-favicons/chrono.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel="noopener noreferrer" target="_blank"'
    },
    {
      'name': 'Kanban (May)',
      'title': 'EDEN Kanban',
      'favicon': '../assets/links-favicons/kanban.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out, Kanban board',
      'linkattributes': 'rel="noopener noreferrer" target="_blank"'
    },
  ]
};

dataJSON.linksList.forEach((element) => {
$('#myDiv').append(`
<div><a href="${element.url}"><img style="margin-right:10px;" src="${element.favicon}"/>${element.name}</a></div>
`);
})


function myFunction() {
    var input, filter, parentDiv, childDiv, a, i, txtValue;
    input = document.getElementById("myInput");
    filter = input.value.toUpperCase();
    parentDiv = document.getElementById("myDiv");
    childDiv = parentDiv.getElementsByTagName("div");
    for (i = 0; i < childDiv.length; i++) {
        a = childDiv[i].getElementsByTagName("a")[0];
        txtValue = a.textContent || a.innerText;
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
            childDiv[i].style.display = "";
        } else {
            childDiv[i].style.display = "none";
        }
    }
}
* {
  box-sizing: border-box;
}

#myInput {
  background-position: 10px 12px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myDiv {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

#myDiv div a {
  border: 1px solid #ddd;
  margin-top: -1px; /* Prevent double borders */
  background-color: #f6f6f6;
  padding: 12px;
  text-decoration: none;
  font-size: 18px;
  color: black;
  display: block
}

#myDiv div a:hover:not(.header) {
  background-color: #eee;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

<h2>Links Search</h2>

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">

<div id="myDiv">
  
</div>