Я пытаюсь добавить фильтр для ссылок/div, сгенерированных из данных JSON.
У меня уже есть поисковый фильтр, работающий здесь без проблем, ЕСЛИ данные не генерируются в формате JSON. Но мне действительно нужно использовать JSON для более быстрой загрузки и обработки.
Проблема в том, что при этом он не фильтрует ссылки. Предполагается фильтровать div на основе текста внутри тегов <a></a>, включая некоторые скрытые тексты внутри тегов <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, и я не мог понять эту проблему в течение некоторого времени. В любом случае, заранее спасибо за любую помощь.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Мне потребовалась целая вечность, чтобы заметить, что у вас есть ВСЕ элементы div в списке ссылок вместо load-json-data.
Вот улучшенная версия. Это упрощено, и поскольку я переключаю только div в load-json-data, он работает.
// 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.info(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>Это первый раз, когда я касаюсь данных JSON, поэтому я действительно не уверен во многих вещах, поэтому большое спасибо за вашу помощь!
Это выглядит так: jsfiddle.net/вымзапфх В этой демонстрации я просто изменил HTML, чтобы добавить еще несколько примеров div под <div id = "load-json-data"></div>. При этом фильтр не будет работать для этих дополнительных элементов.
Спасибо и увидимся, я буду продолжать пытаться, пока не получу его, надеюсь.
Боже мой, теперь он работает, изменив селекторы, как вы сказали! Спасибо любезно!
Смотрите обновленный селектор и HTML
Я использовал 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>Спасибо за ваш ответ, это тоже действительно хороший образец. Однако я пытался изменить ul и li's на divs, как в моем образце, но, похоже, это не сработало. Не могли бы вы показать мне, как это сделать, если вы используете div?
Я редактировал код с помощью div
О верно! Это действительно отличное решение, и оно работает! Однако меня беспокоит то, что мне нужно добавить другой набор ссылок, поэтому еще один вариант
<div id = "load-json-data"></div>, поэтому я действительно надеюсь отфильтровать<div id = "links-list">. Скажите, пожалуйста, возможно ли это? В любом случае, я посмотрю больше на это и посмотрю, смогу ли я его настроить. Благодарю вас!