我正在学习Wes Box Javascript30课程,并为“ Type Ahead”代码添加了自己的内容。原始代码接收单个数据源,并使用eventListener通过返回模板文字中的列表元素并使用用户输入内容中的innerHTML更新结果来更新搜索建议。我已经修改了代码以搜索另一组数据,但是现在我无法使用“提前输入”功能来正确更新建议。
由于我专注于构建纯Javascript知识,因此我没有使用任何库来编写此知识。我尝试了几种不同的技术,大多数无法在此处找到。
这个(答案最多的)建议使用insertAdjacentHTML()。我的代码中存在的问题是,匹配较少字母的结果永远不会被过滤掉,因此最终会有一长串不再适合输入的结果。
Javascript - Append HTML to container element without innerHTML
我尝试使用createElement和appendChild的组合,但是同样,我无法获得结果来过滤掉不再适用的匹配项。我引用了先前的问题,但是无法从此处接受的答案中解决问题。
Argument 1 of Node.appendChild is not an object when trying to append basic html
我还从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/
这仅适用于一个事件监听器(无论哪个位于底部)都可以正常工作。我知道问题是当使用innerHTML时,您添加/删除了元素,从而删除了eventListeners。我需要一个解决方案,使我可以在用户键入时立即显示来自两个“数据源”的建议。谢谢。
答案 0 :(得分:0)
我认为,如果要合并两个数组,可以使用concat()
,但是如果您还想删除重复的值,则需要创建一个新功能,例如被解释为here。
要实现它,您可以使用:
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));
例如,请参见jsFiddle Fork或代码段。
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>