先看效果:
更新:增加切换显示
折腾了老半天,记录一下
注意事项都写注释了
代码:
<template>
<div class="absolute-lt wh-full overflow-hidden p-10">
<div style="width: 200px">
<el-input v-model="keyword" @input="search"></el-input>
</div>
<code>
<pre v-html="html"></pre>
</code>
</div>
</template>
<script setup>
import { onMounted, computed, reactive, ref } from "vue";
import hljs from "highlight.js";
// 这不引入样式防止干扰高亮显示
// import "highlight.js/styles/arta.css";
const str = `
Server: cloudflare
Date: Tue, 02 Jan 2024 15:40:15 GMT
Content-Type: text/html
Content-Length: 553
Connection: keep
CF-RAY: 83f419748811fa1a-SJC
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>cloudflare</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
`;
const html = ref("");
const keyword = ref("");
let saveValue = ref("");
// 注册自定义语言,防止生成多余标签匹配
hljs.registerLanguage("custom", function () {
return {};
});
html.value = saveValue.value = hljs.highlight(str, { language: "custom" }).value;
function search() {
if (!keyword.value) return (html.value = saveValue.value);
let reg = new RegExp(keyword.value, "g", "i");
html.value = saveValue.value.replace(
reg,
"<span class='abc'> " + keyword.value + " </span>"
);
}
</script>
<style lang="less">
span.abc {
color: red;
}
</style>
更新后代码:
<template>
<div class="absolute-lt wh-full overflow-hidden p-10">
<!-- <code>
<pre>{{ str }}</pre>
</code> -->
<!-- <pre>
<code>{{ str }}</code>
</pre> -->
<div class="flex">
<div style="width: 200px">
<el-input v-model="keyword" @input="search"></el-input>
</div>
<div>{{ cur }}/{{ total }}</div>
<div>
<el-button @click="pre">上一个</el-button>
<el-button @click="next">下一个</el-button>
</div>
</div>
<div class="box">
<code>
<pre v-html="html"></pre>
</code>
</div>
</div>
</template>
<script setup>
import { onMounted, computed, reactive, ref } from "vue";
import hljs from "highlight.js";
// import "highlight.js/styles/arta.css";
const str = `
Server: cloudflare
Date: Tue, 02 Jan 2024 15:40:15 GMT
Content-Type: text/html
Content-Length: 553
Connection: keep
CF-RAY: 83f419748811fa1a-SJC
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>cloudflare</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
Server: cloudflare
Date: Tue, 02 Jan 2024 15:40:15 GMT
Content-Type: text/html
Content-Length: 553
Connection: keep
CF-RAY: 83f419748811fa1a-SJC
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>cloudflare</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->Server: cloudflare
Date: Tue, 02 Jan 2024 15:40:15 GMT
Content-Type: text/html
Content-Length: 553
Connection: keep
CF-RAY: 83f419748811fa1a-SJC
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>cloudflare</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
`;
const html = ref("");
const keyword = ref("");
let saveValue = ref("");
let total = ref(0);
let cur = ref(0);
let nodeList = ref([]);
hljs.registerLanguage("custom", function () {
return {};
});
html.value = saveValue.value = hljs.highlight(str, { language: "custom" }).value;
// html.value = saveValue.value = hljs.highlightAuto(str).value;
window.hljs = hljs;
function search() {
if (!keyword.value) return (html.value = saveValue.value);
let reg = new RegExp(keyword.value, "g", "i");
html.value = saveValue.value.replace(
reg,
"<span class='abc'>" + keyword.value + "</span>"
);
count();
}
function pre() {
if (cur.value <= 0) {
cur.value = 0;
} else {
cur.value--;
}
scorll();
}
function scorll() {
for (let index = 0; index < nodeList.value.length; index++) {
const element = nodeList.value[index];
element.style = index == cur.value ? "color:blue" : "color:red";
}
let box = document.querySelector(".box");
let top = nodeList.value[cur.value].offsetTop;
let offset = nodeList.value[0].offsetTop;
box.scrollTop = top - offset;
}
function next() {
if (cur.value >= nodeList.value.length) {
cur.value = nodeList.value.length;
} else {
cur.value++;
}
scorll();
}
function count() {
setTimeout(() => {
nodeList.value = document.querySelectorAll("span.abc");
total.value = nodeList.value.length;
nodeList.value[cur.value].style = "color:blue";
}, 300);
}
</script>
<style lang="less">
span.abc {
color: red;
}
.box {
height: 300px;
overflow-y: auto;
}
</style>