Javascript 使用 indexOf 搜索失败
Javascript search failures with indexOf
我有多个元素(称为卡片),每个元素都有动态数量的关键字。我想通过它们搜索搜索输入的匹配项。
问题 - 有时功能似乎损坏,如果我将 "L" 写入搜索输入,它只会指示红牌匹配,当我添加 "U" 时,它只会显示蓝卡。但是 "L" 应该是两张卡上的匹配项并显示它们。
此故障可重现。有各种各样的问题。尝试输入 "Manager",如果你只写第一个字母,则不会显示匹配项,在 "Ma" 上,卡片显示为匹配项。
我的功能出了什么问题?
document.getElementById('cardSearch').addEventListener('input', function(){
var cards = document.getElementsByClassName('card');
var input = this.value.toUpperCase().replace(/ +(?= )/g,'').split(' ');
var search = input.filter(Boolean);
var noMatch = document.getElementById('noMatch');
mismatchCount = 0;
keywords = search.length;
cardCycle = 0;
searchCycle();
//search cycle for every card
function searchCycle() {
var cycleMax = cards.length;
cardMatch = 0;
valueCycle = 0;
searchValues();
if(cardMatch == keywords) {
cards[cardCycle].classList.remove('hidden');
} else {
cards[cardCycle].classList.add('hidden');
mismatchCount++;
}
//check for mismatches - if all cards missmatched, show no matches text
if(mismatchCount == cards.length) {
noMatch.classList.remove('hidden');
} else {
noMatch.classList.add('hidden');
}
cardCycle++;
if(cardCycle < cycleMax) {
searchCycle();
}
}
//search cycle for every input string, splitted by space
function searchValues() {
var metaData = cards[cardCycle].getAttribute('data-meta').toUpperCase().replace(/\s+/g, '').split(',');
for(i = 0; i < metaData.length; i++) {
if(metaData[i].indexOf(search[valueCycle]) > -1) {
cardMatch++;
}
}
valueCycle++;
if(valueCycle < keywords) {
searchValues();
}
}
})
#cardSearch {
width: 300px;
padding: 10px;
margin: 10px 0 20px 0;
}
.card {
padding: 20px;
margin-top: 10px;
color: #fff;
}
.hidden {
display: none;
}
.blue {
background: blue;
}
.red {
background: red;
}
.green {
background: green;
}
<header>
<input id="cardSearch" type="text">
</header>
<span id="noMatch" class="hidden">no match</span>
<div class="card blue" data-meta="Manager, Lumpadau, public">
<span>Manager, Lumpadau, public</span>
</div>
<div class="card red" data-meta="Worker, Reinde, public">
<span>Worker, Reinde, public</span>
</div>
<div class="card green" data-meta="Cleaner, Rolls, private">
<span>Cleaner, Rolls, private</span>
</div>
for(i = 0; i < metaData.length; i++) {
if(metaData[i].indexOf(search[valueCycle]) > -1) {
cardMatch++;
}
}
在这部分代码中,cardMath 不仅在卡片上递增,而且在找到每个新的匹配符号时递增。因此,如果卡片中只有一个符号 "L",它会正确计算,但如果有多个符号 "L" - 它会将 cardMatch 的值设置得太高。
要解决此问题,请在找到卡片中的第一个符号后添加 break 语句。
for(i = 0; i < metaData.length; i++) {
if(metaData[i].indexOf(search[valueCycle]) > -1) {
cardMatch++;
break;
}
}
这是更新的 jsFiddle - https://jsfiddle.net/kupdwj5q/14/
我有多个元素(称为卡片),每个元素都有动态数量的关键字。我想通过它们搜索搜索输入的匹配项。
问题 - 有时功能似乎损坏,如果我将 "L" 写入搜索输入,它只会指示红牌匹配,当我添加 "U" 时,它只会显示蓝卡。但是 "L" 应该是两张卡上的匹配项并显示它们。
此故障可重现。有各种各样的问题。尝试输入 "Manager",如果你只写第一个字母,则不会显示匹配项,在 "Ma" 上,卡片显示为匹配项。
我的功能出了什么问题?
document.getElementById('cardSearch').addEventListener('input', function(){
var cards = document.getElementsByClassName('card');
var input = this.value.toUpperCase().replace(/ +(?= )/g,'').split(' ');
var search = input.filter(Boolean);
var noMatch = document.getElementById('noMatch');
mismatchCount = 0;
keywords = search.length;
cardCycle = 0;
searchCycle();
//search cycle for every card
function searchCycle() {
var cycleMax = cards.length;
cardMatch = 0;
valueCycle = 0;
searchValues();
if(cardMatch == keywords) {
cards[cardCycle].classList.remove('hidden');
} else {
cards[cardCycle].classList.add('hidden');
mismatchCount++;
}
//check for mismatches - if all cards missmatched, show no matches text
if(mismatchCount == cards.length) {
noMatch.classList.remove('hidden');
} else {
noMatch.classList.add('hidden');
}
cardCycle++;
if(cardCycle < cycleMax) {
searchCycle();
}
}
//search cycle for every input string, splitted by space
function searchValues() {
var metaData = cards[cardCycle].getAttribute('data-meta').toUpperCase().replace(/\s+/g, '').split(',');
for(i = 0; i < metaData.length; i++) {
if(metaData[i].indexOf(search[valueCycle]) > -1) {
cardMatch++;
}
}
valueCycle++;
if(valueCycle < keywords) {
searchValues();
}
}
})
#cardSearch {
width: 300px;
padding: 10px;
margin: 10px 0 20px 0;
}
.card {
padding: 20px;
margin-top: 10px;
color: #fff;
}
.hidden {
display: none;
}
.blue {
background: blue;
}
.red {
background: red;
}
.green {
background: green;
}
<header>
<input id="cardSearch" type="text">
</header>
<span id="noMatch" class="hidden">no match</span>
<div class="card blue" data-meta="Manager, Lumpadau, public">
<span>Manager, Lumpadau, public</span>
</div>
<div class="card red" data-meta="Worker, Reinde, public">
<span>Worker, Reinde, public</span>
</div>
<div class="card green" data-meta="Cleaner, Rolls, private">
<span>Cleaner, Rolls, private</span>
</div>
for(i = 0; i < metaData.length; i++) {
if(metaData[i].indexOf(search[valueCycle]) > -1) {
cardMatch++;
}
}
在这部分代码中,cardMath 不仅在卡片上递增,而且在找到每个新的匹配符号时递增。因此,如果卡片中只有一个符号 "L",它会正确计算,但如果有多个符号 "L" - 它会将 cardMatch 的值设置得太高。
要解决此问题,请在找到卡片中的第一个符号后添加 break 语句。
for(i = 0; i < metaData.length; i++) {
if(metaData[i].indexOf(search[valueCycle]) > -1) {
cardMatch++;
break;
}
}
这是更新的 jsFiddle - https://jsfiddle.net/kupdwj5q/14/