js 实现ctrl f
在JavaScript中实现类似Ctrl+F的搜索功能
通过监听键盘事件和操作DOM元素,可以在网页中实现类似浏览器原生Ctrl+F的搜索功能。以下是具体实现方法:
监听Ctrl+F组合键
document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.key === 'f') {
event.preventDefault();
showSearchBox();
}
});
创建搜索框UI
function showSearchBox() {
const searchBox = document.createElement('div');
searchBox.innerHTML = `
<input type="text" id="searchInput" placeholder="搜索...">
<button id="searchNext">下一个</button>
<button id="searchPrev">上一个</button>
<span id="matchCount">0/0</span>
`;
searchBox.style.position = 'fixed';
searchBox.style.top = '10px';
searchBox.style.right = '10px';
searchBox.style.zIndex = '9999';
document.body.appendChild(searchBox);
document.getElementById('searchInput').focus();
}
实现搜索逻辑
let currentIndex = -1;
let matches = [];
function performSearch() {
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
if (!searchTerm) return;
const textNodes = [];
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
null,
false
);
let node;
while (node = walker.nextNode()) {
if (node.nodeValue.trim()) {
textNodes.push(node);
}
}
matches = [];
textNodes.forEach((node, i) => {
const content = node.nodeValue.toLowerCase();
let pos = content.indexOf(searchTerm);
while (pos !== -1) {
matches.push({
node,
pos,
length: searchTerm.length
});
pos = content.indexOf(searchTerm, pos + 1);
}
});
updateMatchCount();
}
高亮和导航搜索结果
function highlightMatch(index) {
if (matches.length === 0 || index < 0 || index >= matches.length) return;
const match = matches[index];
const range = document.createRange();
range.setStart(match.node, match.pos);
range.setEnd(match.node, match.pos + match.length);
// 移除之前的高亮
const oldHighlights = document.querySelectorAll('.search-highlight');
oldHighlights.forEach(el => {
const parent = el.parentNode;
parent.replaceChild(document.createTextNode(el.textContent), el);
parent.normalize();
});
// 添加新高亮
const span = document.createElement('span');
span.className = 'search-highlight';
span.style.backgroundColor = 'yellow';
range.surroundContents(span);
// 滚动到高亮位置
span.scrollIntoView({ behavior: 'smooth', block: 'center' });
currentIndex = index;
updateMatchCount();
}
function updateMatchCount() {
const countElement = document.getElementById('matchCount');
countElement.textContent = `${currentIndex + 1}/${matches.length}`;
}
添加事件监听器
document.getElementById('searchInput').addEventListener('input', performSearch);
document.getElementById('searchNext').addEventListener('click', () => {
if (matches.length === 0) return;
const nextIndex = (currentIndex + 1) % matches.length;
highlightMatch(nextIndex);
});
document.getElementById('searchPrev').addEventListener('click', () => {
if (matches.length === 0) return;
const prevIndex = (currentIndex - 1 + matches.length) % matches.length;
highlightMatch(prevIndex);
});
CSS样式
.search-highlight {
background-color: yellow;
color: black;
}
#searchInput {
padding: 5px;
margin-right: 5px;
}
#matchCount {
margin-left: 10px;
color: #666;
}
注意事项
- 此实现会在整个页面内容中搜索,包括动态加载的内容
- 搜索是区分大小写的,可以通过调整代码改为不区分大小写
- 对于大量文本内容,可能需要优化搜索性能
- 可以添加Esc键监听来关闭搜索框
- 考虑添加对正则表达式的支持以增强搜索功能
这种实现方式提供了基本的搜索功能,可以根据具体需求进一步扩展和完善。







