简介
一个仿浏览器Ctrl+F的小功能,可以搜索页面指定内容并进行跳转
- 未进行搜索点击上一个、下一个会提示
请先进行搜索!
- 搜索不存在的内容会提示
没有找到内容!
- 没有上一个、下一个时会提示
已是第一个
、已是最后一个
使用教程
代码放置于子比主题后台菜单的 文章列表/文章页面
中的 文章插入内容
插入在前还是在后都无所谓,看你自己喜欢放哪里
<style>
#searchBox {
position: fixed;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
z-index: 1000;
box-shadow: 0 0 10px rgb(116 116 116 / 46%);
}
.highlight {
background-color: yellow;
}
</style>
<!-- 搜索功能 -->
<div id="searchBox" class="zib-widget main-shadow">
<input type="text" id="searchInput" placeholder="键入页内关键词搜索..." class="form-control search-input focus-show">
<button onclick="highlightSearch()" class="but c-red pw-1em mt6">搜索</button>
<button onclick="navigateToPrevious()" class="but c-blue pw-1em mt6">上一个</button>
<button onclick="navigateToNext()" class="but c-green pw-1em mt6">下一个</button>
</div>
<script>
let currentHighlightIndex = -1; // 当前高亮的索引
let allMatches = []; // 所有匹配项的位置
function highlightSearch() {
const searchText = document.getElementById('searchInput').value.trim();
if (!searchText) return;
// 移除之前的高亮
removeHighlights();
// 获取所有文本节点
const allTextNodes = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, false);
allMatches = []; // 重置所有匹配项的位置
while (allTextNodes.nextNode()) {
const node = allTextNodes.currentNode;
const text = node.textContent;
// 查找并记录匹配项的位置
let startIndex = 0;
while ((startIndex = text.toLowerCase().indexOf(searchText.toLowerCase(), startIndex)) !== -1) {
allMatches.push({
node: node,
start: startIndex,
end: startIndex + searchText.length
});
startIndex += searchText.length;
}
}
// 如果有匹配项,高亮第一个匹配项
if (allMatches.length > 0) {
currentHighlightIndex = 0;
highlightCurrentMatch();
} else {
notyf("没有找到内容!", "danger");
}
}
function highlightCurrentMatch() {
if (allMatches.length === 0 || currentHighlightIndex < 0 || currentHighlightIndex >= allMatches.length) return;
const match = allMatches[currentHighlightIndex];
const node = match.node;
const text = node.textContent;
// 创建高亮的b元素
const b = document.createElement('b');
b.className = 'highlight';
b.textContent = text.substring(match.start, match.end);
// 插入高亮的b元素,并删除已处理的部分
node.parentNode.insertBefore(b, node);
node.textContent = text.substring(0, match.start) + text.substring(match.end);
// 滚动到当前高亮的元素
b.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
function navigateToNext() {
if (allMatches.length === 0) {
notyf("请先进行搜索!", "danger");
return;
}
if (currentHighlightIndex === allMatches.length - 1) {
notyf("已经是最后一个了~", "danger");
return;
}
// 移除当前高亮
removeCurrentHighlight();
currentHighlightIndex = (currentHighlightIndex + 1) % allMatches.length;
highlightCurrentMatch();
}
function navigateToPrevious() {
if (allMatches.length === 0) {
notyf("请先进行搜索!", "danger");
return;
}
if (currentHighlightIndex === 0) {
notyf("已经是第一个了~", "danger");
return;
}
// 移除当前高亮
removeCurrentHighlight();
currentHighlightIndex = (currentHighlightIndex - 1 + allMatches.length) % allMatches.length;
highlightCurrentMatch();
}
function removeCurrentHighlight() {
if (currentHighlightIndex < 0 || currentHighlightIndex >= allMatches.length) return;
const match = allMatches[currentHighlightIndex];
const node = match.node;
// 查找并移除高亮的b元素
const bs = node.parentNode.querySelectorAll('.highlight');
for (const b of bs) {
const text = b.textContent;
b.parentNode.replaceChild(document.createTextNode(text), b);
}
}
function removeHighlights() {
for (const match of allMatches) {
const node = match.node;
// 查找并移除高亮的b元素
const bs = node.parentNode.querySelectorAll('.highlight');
for (const b of bs) {
const text = b.textContent;
b.parentNode.replaceChild(document.createTextNode(text), b);
}
}
allMatches = [];
currentHighlightIndex = -1;
}
</script>
© 版权声明
THE END
喜欢就支持一下吧
相关推荐
暂无评论内容