javascript - 为什么我的搜索没有检查所有标签元素?引导程序,JS
问题描述
几乎绝对是菜鸟,正在使用 bootstrap 和 JS 进行我的第二个项目。所以我制作了搜索表格和几张卡片,每张卡片都有两段。
<div class="container">
<div class="row justify-content-center my-5">
<input class="form-control col-xs-12 col-lg-10 col-sm-8" id="myInput" type="text" onkeyup="myFunction()" placeholder="Поиск">
<button class="btn btn-outline ml-2 my-xs-2 col-xs-8 " style="font-family: Arial, Helvetica, sans-serif; font-weight: 700;">SEARCH</button>
</div>
</div>
<div class="container">
<ul class="row" id="myList" style="list-style-type: none;">
<li class="card mb-4 box-shadow"><p>Adele</p><p>2001</p></li>
<li class="card mb-4 box-shadow"><p>Agnes</p><p>1980</p></li>
<li class="card mb-4 box-shadow"><p>Billy</p><p>2010</p></li>
<li class="card mb-4 box-shadow"><p>Bob</p><p>1530</p></li>
<li class="card mb-4 box-shadow"><p>Calvin</p></li>
<li class="card mb-4 box-shadow"><p>Christina</p></li>
<li class="card mb-4 box-shadow"><p>Cindy</p></li>
</ul>
</div>
我的脚本:
function myFunction() {
var input, filter, ul, li, p, i, txtValue;
input = document.getElementById('myInput');
filter = input.value.toUpperCase();
ul = document.getElementById("myList");
li = ul.getElementsByTagName('li');
for (i = 0; i < li.length; i++) {
p = li[i].getElementsByTagName("p")[0];
txtValue = p.textContent || p.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
当我输入名称时它可以工作,但是当我输入年份时 - 不。为什么它忽略第二段,我应该如何更改脚本来解决问题?
解决方案
正如 Rich DeBourke 所提到的,问题在于在这一行使用 0 索引:
p = li[i].getElementsByTagName("p")[0];
我建议您使用以下方法:
function myFunction() {
const input = document.getElementById("myInput");
const inputValue = input.value.toUpperCase();
const ul = document.getElementById("myList");
const lis = ul.getElementsByTagName("li");
for (let li of lis) {
const [pName, pYear] = li.getElementsByTagName("p");
// We assume on this example that the name's paragraph
// will always exist, but the year may not
const textPName = pName.innerText.toUpperCase();
const textPYear = pYear?.innerText.toUpperCase();
if (
textPName.startsWith(inputValue) ||
(textPYear && textPYear.startsWith(inputValue))
) {
li.style.display = "block";
} else {
li.style.display = "none";
}
}
}
这种新方法的一些优点是:
- 变量被定义得更接近它们被使用的地方,并且被赋予的名称与它们在方法中的身份更紧密地耦合在一起。
- 我们在适当的地方使用 const 而不是 var。
- 我们使用 for/of 而不是基本的 for 循环,因为我们不需要索引。
- 我们将 li 数组的元素解构为可以立即使用的合理命名的变量。
- 我们在 if 语句中考虑边缘情况(年份可能不存在)。
- 我们在获取元素的内容时使用 innerText(更简单的替代方法),并在 if 语句中将显示设置为阻塞(而不是空字符串),因为这是默认显示。
希望这可以帮助!
推荐阅读
- azure - Azure 逻辑应用中的随机列表
- bash - 如何使用 sed 和正则表达式替换文件中的部分行?
- c++ - 无法让它重新循环。C++
- python-3.x - 递归python3代码中的溢出堆栈
- arrays - 当数组具有相同值的两个实例时,快速排序算法中的无限循环
- django - 如何在 DRF 的视图集中使用自定义列表方法和自定义操作?
- ios - 为什么 UIPickerView 不显示图片?
- ruby-on-rails - 从 Vue 模板生成 PDF
- https - 难以使用 Wiremock、微服务和外部 https 服务 - 没有捕获流量
- amazon-web-services - AWS Cloudwatch Metrics - 如何从 API 获取所有存储桶中的 S3/弹性存储总量