innerHTML 在 Javascript "Type Ahead"代码中无法使用多个 eventListener



我正在学习Wes Box Javascript30课程,并对"Type-Ahead"代码进行自己的添加。原始代码接收单个数据源,并使用eventListener更新搜索建议,方法是在模板文本中返回列表元素,并在用户输入时使用innerHTML更新结果。我已经修改了代码以搜索另一组数据,但现在我无法获得"提前键入"功能来正确更新建议。

由于我专注于构建纯Javascript知识,所以我不使用任何库来编写这篇文章。我尝试了几种不同的技术,大多数都是在这里找到的,但我无法正常工作。

这个(支持率最高的答案)建议使用insertAdjacentHTML()。我的代码中的问题是,与较少字母匹配的结果永远不会被过滤掉,所以最终会有一长串不再适合输入的结果。

Javascript-在没有innerHTML 的情况下将HTML附加到容器元素

我尝试过使用createElement和appendChild的组合,但同样,我无法获得过滤出不再适用的匹配项的结果。我引用了前面的问题,但无法从这里接受的答案中找出问题。

尝试附加基本html 时,Node.appendChild的参数1不是对象

我还阅读了有关在MDN的参考资料中列出的代码中使用innerHTML的安全注意事项。我知道这只是一种实践,永远不会在网上发布,但我远离使用它?

https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML

这里的"数据"只是一个示例,但工作方式与我使用的数据相同。这只是一种缩短它的方法

<form class="search-form">
<input type="text" class="search" placeholder="Search">
<ul class="suggestions"></ul>
</form>
<script>
const arr1 = ['pink','blue','green','purple'];
const arr2 = ['red', 'orange', 'yellow', 'black'];
function displayArr1() {
const matchArray = findMatches(this.value, arr1)
const html = matchArray.map(item => {
const regex = new RegExp(this.value, 'gi');
const itemName = item.replace(regex, `<span class='hl'>${this.value}</span>`);
return `
<li>
<span class='name'>${itemName}</span>
</li>
`;
}).join('');
suggestions.innerHTML = html;
}
function findMatches(wordToMatch, arr) {
return arr.filter(item => {
const regex = new RegExp(wordToMatch, 'gi');
return item.match(regex);
});
}
function displayArr2() {
const matchArray = findMatches(this.value, arr2)
const html = matchArray.map(item => {
const regex = new RegExp(this.value, 'gi');
const itemName = item.replace(regex, `<span class='hl'>${this.value}</span>`);
return `
<li>
<span class='name'>${itemName}</span>
</li>
`;
}).join('');
suggestions.innerHTML = html;
}
const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
searchInput.addEventListener('keyup', displayArr1);
searchInput.addEventListener('keyup', displayArr2);
</script>

JSFiddle中的相同代码:https://jsfiddle.net/slawk/25bt8edw/

这只适用于一个eventListener(以底部的为准)。我知道问题是,当使用innerHTML时,您添加/销毁元素,这会删除eventListener。我需要一个解决方案,允许我在用户键入时同时显示来自两个"数据源"的建议。非常感谢。

我认为,如果您想组合两个数组,可以使用concat(),但如果您也想删除重复的值,则需要创建一个新函数,如这里所述。

要实现它,您可以使用:

function arrayUnique(array) {
var a = array.concat();
for (var i = 0; i < a.length; ++i) {
for (var j = i + 1; j < a.length; ++j) {
if (a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
}
var array3 = arrayUnique(arr1.concat(arr2));

例如,请参阅jsFiddleFork或snippet。

const arr1 = ['pink', 'blue', 'green', 'purple'];
const arr2 = ['red', 'orange', 'yellow', 'black'];
function arrayUnique(array) {
var a = array.concat();
for (var i = 0; i < a.length; ++i) {
for (var j = i + 1; j < a.length; ++j) {
if (a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
}
var array3 = arrayUnique(arr1.concat(arr2));
function displayArr() {
const matchArray = findMatches(this.value, array3)
const html = matchArray.map(item => {
const regex = new RegExp(this.value, 'gi');
const itemName = item.replace(regex, `<span class='hl'>${this.value}</span>`);
return `
<li>
<span class='name'>${itemName}</span>
</li>
`;
}).join('');
suggestions.innerHTML = html;
}
function findMatches(wordToMatch, arr) {
return arr.filter(item => {
const regex = new RegExp(wordToMatch, 'gi');
return item.match(regex);
});
}
const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
searchInput.addEventListener('keyup', displayArr);
<form class="search-form">
<input type="text" class="search" placeholder="Search">
<ul class="suggestions"></ul>
</form>

最新更新