Prism & highlight.js高亮代码 & 手动添加行号 & 一键复制
/ 使用代码添加行号(这里是使用jquery给所有的 pre标签 加上 line-number 这个类名,也可以如上面自己手动加入这个类名),然后,再去引入prism.js,让prism生成行号相关的dom结构出来。
学习链接
漂亮的代码语法高亮插件Prism.js简单使用文档
Prism官网
Prism高亮代码(html版)
官网下载js和css
代码1
效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入prism.css -->
<link rel="stylesheet" href="./prism/prism.css">
</head>
<body>
<div style="width:500px;margin: 10px auto;">
<!-- 一定要满足下面代码的dom结构,然后,再引入从prism官网下载的js -->
<!-- 试了一下:将language-语言, 加在pre这个标签里面也是可以的; 将line-numbers加在code这个标签里也是可以的,都是一样的效果 -->
<pre class="line-numbers">
<code class="language-css">p { color: red }</code>
</pre>
<pre>
<code class="language-java">
package com.zzhua;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class);
}
}
</code>
</pre>
</div>
</body>
<!-- 引入jquery操作dom -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js"></script>
<script>
// 使用代码添加行号(这里是使用jquery给所有的 pre标签 加上 line-number 这个类名,也可以如上面自己手动加入这个类名),然后,再去引入prism.js,让prism生成行号相关的dom结构出来
$('pre').each(function () {
$(this).addClass('line-numbers');
})
</script>
<!-- 让prism.js处理代码高亮 -->
<script src="./prism/prism.js"></script>
</html>
代码2
但通常使用这个插件的时候,是通过异步加载数据再渲染成html的,所以需要在加载完成之后,再高亮代码
效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入prism.css -->
<link rel="stylesheet" href="./prism/prism.css">
</head>
<body>
<div style="width:500px;margin: 10px auto;" id="div1">
<!-- 一定要满足下面代码的dom结构,然后,再引入从prism官网下载的js -->
<!-- 试了一下:将language-语言, 加在pre这个标签里面也是可以的; 将line-numbers加在code这个标签里也是可以的,都是一样的效果 -->
<pre class="line-numbers">
<code class="language-css">p { color: red }</code>
</pre>
<pre>
<code class="language-java">
package com.zzhua;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class);
}
}
</code>
</pre>
</div>
</body>
<!-- 引入jquery操作dom -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js"></script>
<script>
// 使用代码添加行号(这里是使用jquery给所有的 pre标签 加上 line-number 这个类名,也可以如上面自己手动加入这个类名),然后,再去引入prism.js,让prism生成行号相关的dom结构出来
$('pre').each(function () {
$(this).addClass('line-numbers');
})
</script>
<!-- 让prism.js处理代码高亮 -->
<script src="./prism/prism.js"></script>
<!-- 让prism.js处理代码高亮 -->
<script>
setTimeout(()=>{
$('#div1').append($(`
<pre class="line-numbers">
<code class="language-java">
public class Result {
private Integer code;
private String msg;
private T data;
}
</code>
</pre>
`))
// 会全局注册一个Prism对象,里面有方法:highlight、highlightAll、highlightElement、highlightAllUnder等书方法
console.log(Prism)
// Prism.highlightAll(); // 也可以这样
let blocks = document.querySelectorAll("pre code");
blocks.forEach((block) => {
Prism.highlightElement(block);
});
}, 2000)
</script>
</html>
Prism高亮代码(vue版)
Vue页面代码高亮展示之Prism语法高亮工具
Vue中使用Prism来显示代码高亮
babel-plugin-prismjs -> www.npmjs.com
Nuxt3中使用prismjs高亮代码
基础使用
已添加行号插件,未添加复制代码插件的dom示意图
添加行号 和 一键复制插件的dom示意图
安装prismjs
Prism官网上有这部分内容
npm i prismjs
vue组件中使用
- 需要引入prismjs
- 需要引入prismjs的样式
- 需要引入对应的语言,它默认只引入了js、css、markup、clike这几种语言
- 需要使用language-xxx的类名,来指定语言
- 下面还引入了其它的插件的例子:行号插件 和 一键复制插件
<style lang="scss">
body {
margin: 0;
}
/* 整个滚动条 */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
/* 滚动条上的滚动滑块,参考: 滚动条样式修改->https://blog.csdn.net/coder_jxd/article/details/124213962 */
::-webkit-scrollbar-thumb {
background-color: #49b1f5;
/* 关键代码 */
background-image: -webkit-linear-gradient(45deg,
rgba(255, 255, 255, 0.4) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.4) 50%,
rgba(255, 255, 255, 0.4) 75%,
transparent 75%,
transparent);
border-radius: 32px;
}
/* 滚动条样式,参考: */
/* 滚动条轨道 */
::-webkit-scrollbar-track {
background-color: #dbeffd;
border-radius: 32px;
}
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
.article {
width: 800px;
margin: 0 auto;
margin-top: 50px;
.article-content {
padding: 15px;
border-radius: 5px;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.16);
}
}
</style>
<template>
<div class="article ">
<div id="div01"></div>
<el-button @click="doTest">div01</el-button>
<!-- 需要在pre或code上,使用language-xxx类名指定xxx语言,否则,prismjs是不会拆掉code标签里的代码内容的
对于下面这3个已经预先写好的代码内容,在引入prismjs后,文档加载完后,前面2个就会自动拆掉的,第3个没有指定语言,因此不会拆 -->
<pre id="pre01" class="language-java"><code class="line-numbers" data-prismjs-copy="复制代码" data-prismjs-copy-success="复制成功" data-prismjs-copy-timeout="1000">
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class);
}
}
</code></pre>
<pre id="pre02" class="line-numbers"><code class="language-java">
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class);
}
}
</code></pre>
<pre id="pre03" class="line-numbers"><code>
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class);
}
}
</code></pre>
<div ref="artcileContentRef" class="article-content" id="article-content" v-html="htmlContent"></div>
</div>
</template>
<script>
import { getArticle } from '@/api/articleApi'
/* 引入prismjs */
import prismjs from 'prismjs'
/* 引入样式主题 */
import 'prismjs/themes/prism-okaidia.css'
/* 如果要支持高亮java语言的话,需要引入这个,其它的语言需要引入prism-{language}
否则,无法处理java语言。 */
import 'prismjs/components/prism-java';
/* 引入行号插件,对应的js和css都要引入, 然后在code或pre上添加line-numbers这个类名就行了 */
import 'prismjs/plugins/line-numbers/prism-line-numbers.js'
import 'prismjs/plugins/line-numbers/prism-line-numbers.css'
import 'prismjs/plugins/toolbar/prism-toolbar.js'
import 'prismjs/plugins/toolbar/prism-toolbar.css'
/* 在引入拷贝到剪贴板这个插件之前,要先引入上面这个prism-toolbar.js和prism-toolbar.css
然后,代码的右上角在高亮操作之后,就会出现拷贝代码的按钮,不过是英文的,可以使用data-prismjs-copy等属性修改为中文 */
import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.js'
console.log(Prism);
console.log(Prism === prismjs); // true 说明它会全局注册一个Prism对象供我们使用
/* 输出:// ['manual', 'disableWorkerMessageHandler', 'util', 'languages', 'plugins', 'highlightAll', 'highlightAllUnder', 'highlightElement', 'highlight', 'tokenize', 'hooks', 'Token', 'filename'] */
console.log('Prism', Object.keys(Prism));
const code = `var data = 1;`;
const html = Prism.highlight(code, prismjs.languages.javascript, 'javascript'); // 它默认已经引入了css/javascript,不需要引入js语言
/* 输出:<span class="token keyword">var</span> data <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> */
console.log(html);
const code2 = `SpringApplication.run(VueApp.class);`;
const html2 = Prism.highlight(code2, prismjs.languages.java, 'java'); // 如果未引入java语言,这里会报错:Error: The language "java" has no grammar.
/* 输出: <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">VueApp</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>*/
console.log(html2);
export default {
name: 'ArticleView2',
data() {
return {
htmlContent: '',
content: '',
}
},
created() {
getArticle(this.$route.params.articleId).then(data => {
this.htmlContent = data.htmlContent
this.$nextTick(()=>{
/* 给文章里的代码添加行号,否则只有前面写在html里的code才有行号 */
let preBlocks = document.querySelectorAll('pre')
preBlocks.forEach(preBlock => {
if(!preBlock.classList.contains('line-numbers')) {
preBlock.classList.add('line-numbers')
}
})
// 当渲染完成之后,高亮所有代码(注意,只有pre或code里带了language-xxx语言的才会处理)
Prism.highlightAll()
})
})
},
mounted() {
// 虽然在created里面已经发出请求了,这里获取的innerHTML是空的(不要被控制台的打印的this.$refs['artcileContentRef']迷惑了)
// 因为上面getArticle是用的Promise,是异步的。所以不能在这里去做高亮的操作。应该在created里面发出请求并且得到响应后的$nextTick中去做高亮操作
console.log('articleContentRef',this.$refs['artcileContentRef'],this.$refs['artcileContentRef'].innerHTML);
},
methods: {
doTest() {
let div01 = document.querySelector('#div01')
div01.innerHTML = `<pre id="pre04" class="line-numbers language-java"><code>@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class);
}
}</code></pre>`
// Prism.highlightElement(div01) // 不能传入div01
// Prism.highlightElement(document.querySelector('#pre04')) // 不能传入pre,它会把code给删了,虽然代码内容拆了并且样式还在
Prism.highlightElement(document.querySelector('#pre04 code'))
}
},
components: {
}
}
</script>
配合babel-plugin-prismjs使用
文章中的代码,并没有加上行号,是因为没有加上line-numbers
这个类名,使用js加上类名就可以了。
安装prismjs
npm install prismjs
配置babel.config.js
在babel.config.js中添加如下插件,其它配置项,可以直接看prism这个包的源码里面找到对应的名字,写在这里就可以了。
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
"plugins": [
["prismjs", {
"languages": ["javascript", "css", "markup","java", "sql","yml","properties"],
"plugins": ["line-numbers","copy-to-clipboard",'previewers'],
"theme": "okaidia",
"css": true
}]
]
}
main.js中引入prismjs
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import 'prismjs' // 引入即可,它会注册一个Prism对象到window上面
Vue.config.productionTip = false
Vue.use(ElementUI);
new Vue({
router,
render: h => h(App)
}).$mount('#app')
vue组件中使用
<style lang="scss">
body {
margin: 0;
}
/* 整个滚动条 */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
/* 滚动条上的滚动滑块,参考: 滚动条样式修改->https://blog.csdn.net/coder_jxd/article/details/124213962 */
::-webkit-scrollbar-thumb {
background-color: #49b1f5;
/* 关键代码 */
background-image: -webkit-linear-gradient(45deg,
rgba(255, 255, 255, 0.4) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.4) 50%,
rgba(255, 255, 255, 0.4) 75%,
transparent 75%,
transparent);
border-radius: 32px;
}
/* 添加行号插件后,它默认把滚动条给覆盖了,所以将padding-left改成margin-left */
[class*=v-md-prism-] {
margin-left: 72px !important;
padding-left: 0 !important;
}
/* 滚动条样式,参考: */
/* 滚动条轨道 */
::-webkit-scrollbar-track {
background-color: #dbeffd;
border-radius: 32px;
}
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
.article {
width: 800px;
margin: 0 auto;
margin-top: 50px;
.article-content {
padding: 15px;
border-radius: 5px;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.16);
}
}
</style>
<template>
<div class="article ">
<div id="div01"></div>
<el-button @click="doTest">div01</el-button>
<pre id="pre01" class="language-java"><code class="line-numbers" data-prismjs-copy="复制代码" data-prismjs-copy-success="复制成功" data-prismjs-copy-timeout="1000">
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
}
</code></pre>
<pre id="pre02" class="line-numbers"><code class="language-java">
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class);
}
}
</code></pre>
<pre id="pre03" class="line-numbers"><code>
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class);
}
}
</code></pre>
<pre class="language-css"><code>div {
/* Only the previewer for color and time are enabled */
color: red;
transition-duration: 1s;
/* The previewer for angles is not enabled. */
transform: rotate(10deg);
}</code></pre>
<div ref="artcileContentRef" class="article-content" id="article-content" v-html="htmlContent"></div>
</div>
</template>
<script>
import { getArticle } from '@/api/articleApi'
export default {
name: 'ArticleView2',
data() {
return {
htmlContent: '',
content: '',
}
},
created() {
console.log(Prism);
getArticle(this.$route.params.articleId).then(data => {
this.htmlContent = data.htmlContent
this.$nextTick(()=>{
Prism.highlightAll()
})
})
},
mounted() {
},
methods: {
doTest() {
let div01 = document.querySelector('#div01')
div01.innerHTML = `<pre id="pre04" class="line-numbers language-java"><code>@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class);
}
}</code></pre>`
// Prism.highlightElement(document.querySelector('#pre04')) // 使用这个方法代码有高亮,但没有加行号
Prism.highlightAll() // 使用这个方法,有高亮,有行号
}
},
components: {
}
}
</script>
highlight.js高亮代码(html版本)
highlight.js -> www.npmjs.com
JS库之Highlight.js高亮代码
程序员必备的代码高亮插件 Highlight.JS
highlight.js官网
1. 发现highlight.js官网下面的原来可以直接点击选择语言和主题,实时预览效果的阿
2. 在线选字体,使用在线链接:谷歌在线字体
也可以试试:highlight.js中文网,也可以在线预览效果的
代码
效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js"></script>
<style>
.box {
width: 500px;
margin: 10px auto;
}
pre code.hljs {
display: block;
padding: 0;
overflow-x: auto;
font-family: 'Consolas', 'Courier New', monospace;
font-weight: 400;
}
</style>
<!-- 可以直接引入cdn -->
<!-- <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script> -->
<!-- 可以在官网下载 -->
<script src="./hljs/highlight.min.js"></script><!-- 导入这个highlight.min.js,不要导入highlight.js,不然还要注册语言,有点麻烦 -->
<link rel="stylesheet" href="./hljs/styles/atom-one-dark.min.css">
<script>
window.onload = function () {
// 它会在全局注册一个hljs,里面有highlightAll、highlightElement、highlightBlock、highlight等方法
console.log(hljs);
hljs.highlightAll()
html = hljs.highlight('<h1>Hello World!</h1>', { language: 'xml' }).value
console.log(html); // 输出:<span class="hljs-tag"><<span class="hljs-name">h1</span>></span>Hello World!<span class="hljs-tag"></<span class="hljs-name">h1</span>></span>
setTimeout(() => {
$('#div1').append($(`<pre><code>
public class Result {
private Integer code;
private String msg;
private T data;
}
</code>
</pre>`))
// hljs.highlightAll() // 也可以这样
let blocks = document.querySelectorAll("pre code");
document.querySelectorAll('pre code').forEach((el) => {
hljs.highlightElement(el);
});
}, 1000)
}
</script>
</head>
<body>
<div class="box">
<pre>
<code class="language-java">
package com.zzhua;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class);
}
}
</code>
</pre>
<div id="div1"></div>
</div>
</body>
</html>
原生js实现手动添加行号
代码
主要的实现思路:使用highlight.js给pre code添加高亮后,获取code标签下的所有html,在这个html里面,行与行之间有换行符的存在,按换行符分割,创建li,把行号添加进去,塞到ul里面,然后,使用定位把行号定到左边去。滚动条的样式是固定代码。
以下代码的资源代码都是在线的,可以随时复制粘贴测试使用,比较方便,这个字体也是在线的,可能要翻墙才能用吧
效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 整个滚动条 */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
/* 滚动条上的滚动滑块,参考: 滚动条样式修改->https://blog.csdn.net/coder_jxd/article/details/124213962 */
::-webkit-scrollbar-thumb {
background-color: #49b1f5;
/* 关键代码 */
background-image: -webkit-linear-gradient(45deg,
rgba(255, 255, 255, 0.4) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.4) 50%,
rgba(255, 255, 255, 0.4) 75%,
transparent 75%,
transparent);
border-radius: 32px;
}
/* 添加行号插件后,它默认把滚动条给覆盖了,所以将padding-left改成margin-left */
[class*=v-md-prism-] {
margin-left: 72px !important;
padding-left: 0 !important;
}
/* 滚动条样式,参考: */
/* 滚动条轨道 */
::-webkit-scrollbar-track {
background-color: #dbeffd;
border-radius: 32px;
}
* {
margin: 0;
padding: 0;
font-size: 18px;
font-family: 'Dancing Script';
list-style: none;
}
body {
height: 100vh;
padding-top: 10px;
}
#code-box {
width: 500px;
border-radius: 6px;
overflow: hidden;
margin: 0 auto;
position: relative;
}
#code {
padding-left: 61px;
background-color: #282c34;
}
#number-line {
position: absolute;
color: #cdcdcd;
padding: 0px 15px 18px 10px;
text-align: right;
width: 30px;
margin-top: 18px;
font-size: 14px;
font-family: 'Courier New', Courier, monospace;
border-right: 1px solid #7d7d7d;
}
</style>
<link rel="stylesheet" href="//unpkg.com/@highlightjs/cdn-assets@11.7.0/styles/atom-one-dark.min.css">
<script src="//unpkg.com/@highlightjs/cdn-assets@11.7.0/highlight.min.js"></script>
<script>
window.onload = () => {
hljs.highlightAll()
/* <<span class="hljs-selector-tag">span</span>>Hello World!</<span class="hljs-selector-tag">span</span>> */
console.log(hljs.highlightAuto('<span>Hello World!</span>').value);
/* <span class="hljs-tag"><<span class="hljs-name">span</span>></span>Hello World!<span class="hljs-tag"></<span class="hljs-name">span</span>></span> */
console.log(hljs.highlight('<span>Hello World!</span>', {language: 'xml'}).value);
let EL_NUMBER_LINE = document.getElementById('number-line')
/*
打印如下:
<span class="hljs-variable">@SpringBootApplication</span>
<span class="hljs-variable">@MapperScan</span>(<span class="hljs-string">"com.zzhua.mapper"</span>)
public class VueApp {
<span class="hljs-selector-tag">public</span> <span class="hljs-selector-tag">static</span> <span class="hljs-selector-tag">void</span> <span class="hljs-selector-tag">main</span>(String[] args) {
<span class="hljs-selector-tag">SpringApplication</span><span class="hljs-selector-class">.run</span>(VueApp.class); <span class="hljs-selector-tag">SpringApplication</span><span class="hljs-selector-class">.run</span>(VueApp.class);
}
}
*/
console.log(document.getElementById('code').childNodes[0].innerHTML);
let LINE = document.getElementById('code').childNodes[0].innerHTML.split('\n').length
console.log(LINE);
for (let i = 1; i <= LINE; i++) {
let li = document.createElement('li')
let lineNum = document.createTextNode(i)
li.appendChild(lineNum)
EL_NUMBER_LINE.appendChild(li)
}
}
</script>
</head>
<body>
<div id="code-box">
<ul id="number-line"></ul>
<pre id="code"><code>@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
public static void main(String[] args) {
SpringApplication.run(VueApp.class); SpringApplication.run(VueApp.class);
}
}</code></pre>
</div>
</body>
</html>
highlight.js高亮代码(vue版)
效果
- 原文内容是通过WangEditor编辑保存的,可以参考:WangEdtior富文本编辑器
- 目录用的tocbot,具体使用可参考:tocbot生成文章目录
- 使用原生js手动添加了行号,修改了滚动条样式
- 实现代码高亮,注意实现代码高亮其实就是把code标签里的代码让highlight.js处理后,然后使用highlight.js提供的主题样式加花里胡哨的颜色。
代码
安装highlight.js
npm install highlight.js
vue组件中引入highlight.js 和 主题样式
import hljs from 'highlight.js';
import 'highlight.js/styles/atom-one-dark.css'
ArticleView.vue
<style lang="scss">
@import 'tocbot/src/scss/tocbot';
@import url('https://fonts.font.im/css?family=Roboto');
/* 整个滚动条 */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
/* 滚动条上的滚动滑块,参考: 滚动条样式修改->https://blog.csdn.net/coder_jxd/article/details/124213962 */
::-webkit-scrollbar-thumb {
background-color: #49b1f5;
/* 关键代码 */
background-image: -webkit-linear-gradient(45deg,
rgba(255, 255, 255, 0.4) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.4) 50%,
rgba(255, 255, 255, 0.4) 75%,
transparent 75%,
transparent);
border-radius: 32px;
}
/* 添加行号插件后,它默认把滚动条给覆盖了,所以将padding-left改成margin-left */
[class*=v-md-prism-] {
margin-left: 72px !important;
padding-left: 0 !important;
}
/* 滚动条样式,参考: */
/* 滚动条轨道 */
::-webkit-scrollbar-track {
background-color: #dbeffd;
border-radius: 32px;
}
.article {
width: 600px;
margin: 10px auto;
.article-content {
width: 725px;
padding: 15px;
// border: 1px solid red;
border-radius: 5px;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.16);
}
#toc-content {
position: fixed;
top: 20px;
right: 50px;
}
}
/* 行号相关样式 */
pre {
background-color: #282c34;
border-radius: 6px;
position: relative;
.line-numbers {
position: absolute;
color: #e0e0e0;
font-size: 16px;
margin: 16px 0;
padding-right: 10px;
width: 30px;
text-align: right;
font-family: 'Roboto', sans-serif;
border-right: 1px solid #c5c5c5;
}
}
code {
font-family: 'Roboto', sans-serif;
border-radius: 6px;
padding-left: 0 !important;
margin-left: 3em !important;
}
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
</style>
<template>
<div class="article">
<!-- <div style="height: 500px;"> </div> -->
<div class="article-content" id="article-content" v-html="htmlContent"></div>
<div id="toc-content"></div>
</div>
</template>
<script>
import { getArticle } from '@/api/articleApi'
// 引入highlight.js和主题样式
import hljs from 'highlight.js';
import 'highlight.js/styles/atom-one-dark.css'
console.log(hljs);
import tocbot from 'tocbot'
console.log('tocbot', tocbot);
export default {
name: 'Article',
data() {
return {
htmlContent: ''
}
},
created() {
getArticle(this.$route.params.articleId).then(data => {
this.htmlContent = data.htmlContent
this.$nextTick(() => {
// console.log('$nextTick...');
let articleContent = document.querySelector('#article-content')
let headingTag = ['h1', 'h2', 'h3']
let children = Array.from(articleContent.children)
for (let i = 0; i < children.length; i++) {
const e = children[i];
e.id = `h-${i}`
}
hljs.highlightAll()
let codes = document.querySelectorAll('code')
console.log(codes);
for (let i = 0; i < codes.length; i++) {
const codeBlock = codes[i];
// console.log(codeBlock.innerHTML);
let lineTotal = codeBlock.innerHTML.split('\n').length
let ul = document.createElement('ul')
ul.classList.add('line-numbers')
for (let i = 1; i <= lineTotal; i++) {
let li = document.createElement('li')
let lineNum = document.createTextNode(i)
li.appendChild(lineNum)
ul.appendChild(li)
}
codeBlock.parentNode.prepend(ul)
}
tocbot.init({
// Where to render the table of contents.
tocSelector: '#toc-content',
// Where to grab the headings to build the table of contents.
contentSelector: '#article-content',
// Which headings to grab inside of the contentSelector element.
headingSelector: 'h1, h2, h3, h4, h5, h6',
// For headings inside relative or absolute positioned containers within content.
hasInnerContainers: true,
});
})
})
},
mounted() {
// console.log('mounted');
},
components: {
}
}
</script>
Clipboard.js实现一键复制
思路:先把要复制的内容用textarea装起来,并用id标识它,然后这个textarea绝对定位,left放很远,top放很远。然后使用一个按钮,按钮的目标id指向这个标识,然后使用clipboard的复制功能即可,可以参考:markdown-it基本使用。
基础使用
JavaScript | 文本复制工具clipboard.js的使用详解(使用clipboard复制ajax请求的数据)
<!-- 该代码可直接创建HTML文件运行 -->
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>target-input</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<!-- 1. 定义一些标记 -->
<!-- 2. 设置按钮 -->
<!-- 示例1:复制input元素的value值 -->
<input id="foo" type="text" value="这是input元素的value值" />
<button class="btn" data-clipboard-action="copy" data-clipboard-target="#foo">点击复制</button>
<br/>
<hr/>
<!-- 示例2:剪切textarea元素的值 -->
<textarea id="bar">这里的文本可被复制或者剪切</textarea>
<button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">点击剪切文字</button>
<br/>
<hr/>
<!-- 示例3:复制div元素的值 -->
<div>这是div元素里的文字</div>
<button class="btn" data-clipboard-action="copy" data-clipboard-target="div">复制来自div的文字</button>
<br/>
<hr/>
<!-- 示例4:复制button自己设置的值 -->
<button class="btn" data-clipboard-text="这里的文字将被复制">复制自己的文字</button>
<!-- 3. 引入库文件 -->
<!-- <script src="../dist/clipboard.min.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js"></script>
<script>
//4. 实例化clipboard
var clipboard = new ClipboardJS('.btn');
//5. 复制成功的响应事件【按F12控制台可见】
clipboard.on('success', function (e) {
console.log(e);
//打印动作信息(copy或者cut)
console.info('Action:', e.action);
//打印复制的文本
console.info('Text:', e.text);
//打印trigger
console.info('Trigger:', e.trigger);
});
//6. 复制失败的响应事件
clipboard.on('error', function (e) {
console.log(e);
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
</script>
</body>
</html>
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)