需求
代码
在moven-editor给代码块增加复制按钮的代码如下:
addCopyBtn(){
this.$nextTick(()=>{
const content = document.getElementsByClassName('v-show-content')[0]
const precodes = content.getElementsByTagName('pre')
// precodes 是个类数组 ,转换一下
const arr = Array.from(precodes)
arr.forEach((element,index)=>{
const btn = document.createElement('div');
btn.innerHTML = '复制';
btn.setAttribute("class",'code-copy' );
btn.addEventListener('click', function(e) {
const code = e.target.parentElement.children[0]; // code 标签
const codeText = code.innerText
// 复制函数
shareURL('code-copy', codeText ,false)
})
element.appendChild(btn)
});
})
},
分別在mounted
和接口返回中执行addCopyBtn
mounted:{
this.addCopyBtn()
},
methods:{
getServiceList().then((res) => {
// .....
this.addCopyBtn()
})
}
结果如下:
mounted
虽然是在视图加载完成后执行,但是 mounted
不会承诺所有的子组件也都一起被挂载,所以在此阶段,dom 结构还没加载完,我们的addCopyBtn
就执行了。所以要放到$nextTick
里面执行。
但我们现在的需求是在moven-editor 的内容里面增加复制按钮,而我们的显示内容是通过接口调用返回的,所以要在接口返回中调用addCopyBtn
方法。
其他代码
1、按钮的样式(SaSS)
pre {
background: #F8F8F8;
border-radius: 2px;
margin-bottom: 17px;
padding: 10px;
overflow: auto;
position: relative;
.code-copy{
position: absolute;
top: 10px;
right: 10px;
padding: 0 10px;
background: #FFFFFF;
border: 1px solid #5592E5;
border-radius: 2px;
font-size: 14px;
color: #5592E5;
cursor: pointer;
&:hover{
background-color: #ecf5ff;
}
}
}
2、复制函数
import Clipboard from 'clipboard'
import { Message } from 'element-ui'
// className 是点击的元素的class,url是复制的内容
export default function shareURL(className, url) {
let clipboard = new Clipboard('.' + className, {
text: function () {
return url
}
})
clipboard.on('success', e => {
Message({
message: '复制成功, CLTR+V 粘贴',
showClose: true,
type: 'success'
})
// 其他处理代码
{...}
// 释放内存
clipboard.destroy()
})
clipboard.on('error', e => {
Message({
message: '复制失败,需手动复制链接',
showClose: true,
type: 'error'
})
clipboard.destroy()
})
// 其他处理的代码不能写在外面,会导致复制失败
}
新问题修复
发现一个问题,当pre中的代码很长时,会出现滚动条,当挪动滚动条时,复制按钮的位置也发生改变,主要是pre元素的relative也发生了改变。解决方法就是将code外面包一层div设置scroll。
addCopyBtn(){
this.$nextTick(()=>{
const content = document.getElementsByClassName('v-show-content')[0]
const precodes = content.getElementsByTagName('pre')
const arr = Array.from(precodes)
arr.forEach((element,index)=>{
const btn = document.createElement('div')
btn.innerHTML = '复制'
btn.setAttribute("class",'code-copy' )
// 将code 塞到div中
const code = element.children[0]
const codeDiv = document.createElement('div')
codeDiv.setAttribute("class",'code-div' )
codeDiv.appendChild(code)
element.appendChild(codeDiv)
// -- 修改結束
btn.addEventListener('click', function(e) {
const code = e.target.parentElement.children[0] // code 标签
const codeText = code.innerText
shareURL('code-copy', codeText ,false)
})
element.appendChild(btn)
});
})
}
.code-div{
width: 100%;
overflow: auto;
padding: 10px;
}