需求:用户点击指定的地方就可以复制内容到剪切板
前置知识
document.execCommand()方法
先看看这个方法在 MDN 上是怎么定义的:
which allows one to run commands to manipulate the contents of the editable region.
意思就是可以允许运行命令来操作可编辑区域的内容,注意,是可编辑区域。
方法返回一个 Boolean 值,表示操作是否成功。
这个方法在之前的兼容性其实是不太好的,但是好在现在已经基本兼容所有主流浏览器了,在移动端也可以使用。
使用方法
需求:从输入框复制内容
现在页面上有一个 <input> 标签,我们想要复制其中的内容,我们可以这样做:
<input id="demoInput" value="hello world">
<buttonid="btn">点我复制</button>
const btn = document.querySelector('#btn');
btn.addEventListener('click', () => {
const input = document.querySelector('#demoInput')
// 选择要复制的表单元素的内容
input.select()
if (document.execCommand('copy')) {
document.execCommand('copy');
console.log('复制成功')
// 让表单元素失去焦点
input.blur()
}
})
需求:复制非input的文本内容
有的时候页面上并没有 <input> 标签,我们可能需要从一个 <div> 中复制内容,或者直接复制变量。
还记得在 execCommand() 方法的定义中提到,它只能操作可编辑区域,也就是意味着除了 <input>、 <textarea> 这样的输入域以外,是无法使用这个方法的。
这时候我们只能采取“曲线救国”的方法。
<button id="btn">点我复制</button>
<div id="div">我是div盒子里面的内容,出现我代表复制成功了</div>
const btn = document.querySelector('#btn');
btn.addEventListener('click', () => {
const input = document.createElement('input')
const div = document.querySelector('#div')
document.body.appendChild(input)
input.setAttribute(
'value',
div.innerText
)
input.select()
if (document.execCommand('copy')) {
document.execCommand('copy')
console.log('复制成功')
}
document.body.removeChild(input)
})
算是曲线救国成功了吧。在使用这个方法时,遇到了几个坑。
在Chrome下调试的时候,这个方法时完美运行的。然后到了移动端调试的时候,坑就出来了,集中体现了ios的调试上
- 1.点击复制时屏幕下方会出现白屏抖动,仔细看是拉起键盘又瞬间收起
知道了抖动是由于什么产生的就比较好解决了。既然是拉起键盘,那就是聚焦到了输入域,那只要让输入域不可输入就好了,在代码中添加 input.setAttribute('readonly','readonly');使这个 <input>是只读的,就不会拉起键盘了。 - 2.无法复制
这个问题是由于 input.select() 在ios下并没有选中全部内容,我们需要使用另一个兼容IOS的方法来选中内容,这个方法就是 input.setSelectionRange(0,input.value.length);。
完整代码如下:
const btn = document.querySelector('#btn');
btn.addEventListener('click', () => {
const input = document.createElement(
'input'
)
const div = document.querySelector('#div')
input.setAttribute('readonly', 'readonly')
input.setAttribute(
'value',
div.innerText
)
document.body.appendChild(input)
input.setSelectionRange(0, 9999)
if (document.execCommand('copy')) {
document.execCommand('copy')
console.log('复制成功')
}
document.body.removeChild(input)
})