我的想法是拥有一个简单的搜索功能,人们可以在搜索框中键入文本,然后查看html中是否有与文本匹配的内容。如果是这样,匹配的部分(假设它可能在整个HTML页面的后半部分,在您当前的屏幕/视口中看不到)将会跳转/滚动到视图中。如果没有,您将在#feedback标记中收到“找不到匹配项”消息。
HTML看起来像这样:
<input id="search-text">
<p id="feedback"></p>
<p>title1</p>
<p>title2</p>
<p>title3</p>
JS是这样的:
let searchText = ''
const titlesNodes = document.querySelectorAll('p')
const titles = Array.from(titlesNodes)
document.querySelector('#search-text').addEventListener('input', (e) => {
searchText = e.target.value
searchFunction()
})
const searchFunction = () => {
const filteredTitles = titles.filter((title) => title.innerText.toLowerCase().includes(searchText.toLowerCase()) )
const msg = document.querySelector('#feedback')
msg.innerHTML = ''
if (filteredTitles.length > 0){
filteredTitles[0].scrollIntoView()
} else {
msg.textContent = 'No match found'
}
}
到目前为止,我能够获得“找不到匹配项”,但是当我键入仅在页面后半部分的内容时,它不会跳转到视图。我在Chromium和Firefox上都进行了测试,并且使用Linux。
我的代码有什么问题?谢谢!
答案 0 :(得分:2)
这是因为默认情况下,浏览器会在您键入时将<input>
元素设置为屏幕。因此,您自己的调用会被浏览器的默认设置覆盖。
虽然不确定避免这种情况的最佳方法是什么...
您可能会尝试在短暂的超时后调用scrollIntoView
,因此发生在输入之一之后。如果使用requestAnimationFrame
计时功能,它应该在下一次绘制之前发生,因此您不会注意到其中一个输入发生了。
let searchText = '';
const titlesNodes = document.querySelectorAll('p')
const titles = Array.from(titlesNodes)
document.querySelector('#search-text').addEventListener('input', (e) => {
searchText = e.target.value
searchFunction()
})
const searchFunction = () => {
const filteredTitles = titles.filter((title) => title.innerText.toLowerCase().includes(searchText.toLowerCase()))
const msg = document.querySelector('#feedback')
msg.innerHTML = ''
if (filteredTitles.length > 0) {
requestAnimationFrame(() => { // wait just a bit
filteredTitles[0].scrollIntoView()
});
} else {
msg.textContent = 'No match found'
}
}
#feedback { margin-bottom: 125vh }
p { margin-bottom: 50vh }
<input id="search-text">
<p id="feedback"></p>
<p>title1</p>
<p>title2</p>
<p>title3</p>
答案 1 :(得分:0)
尝试更改:
- filteredTitles[0].scrollIntoView()
+ filteredTitles[0].scrollIntoView({alignToTop: true})
document.querySelector('#search-text').addEventListener('input', (e) => {
searchText = e.target.value
- searchFunction()
+ setTimeout(searchFunction, 500)})
})