有些页面上的数据用户常常须要全选而后进行复制的工做,用户通常须要两步操做,第一步是选中文本,用户能够经过三次点击或着点击后拖动鼠标来进行选中,第二步则是点击右键选择复制,或者利用键盘快捷键。为了提升用户体验,咱们想要让用户点击相关文字时候,自动全选而且完成复制操做。javascript
CSS属性 user-select 控制用户可否选中文本css
auto | text | none | contain | allhtml
contain 在不少浏览器中例如Chrome中时不支持的,在这里咱们用 user-selet: all 就可以实现文本全选的功能。vue
优点: 能够很是灵活,并且十分简单,一个语句就可完成功能。java
不足: 做为优化需求的时候,须要修改原有代码。也就是若是要在原来的已经写好的页面中加入此功能,须要找到每个具体的位置,而后添加对应的className或者增长css的行间样式。node
selection 表明了当前激活选中区,即高亮文本块,和/或文档中用户可执行某些操做的其它元素。正则表达式
export default () => {
// 监听鼠标的click事件
document.addEventListener('click', (e: Event) => {
// 获取到鼠标点击的dom元素
const span = e.target;
// 获取dom元素中的的innerText的值
const value = (span as HTMLElement).innerText;
// 遍历全部配置的正则表达式
for (const reg of Object.values(regObject)) {
if (reg.test(value)) {
// 验证经过了正则的值是不是span元素或者是div元素,由于不想在输入框也有此功能
if ((span as HTMLElement).localName === ('span' || 'div')) {
// 获取一个Selection对象
const selection = window.getSelection();
// 先清空一下以选择的内容
selection?.removeAllRanges();
// 建立一个range对象
const range = document.createRange();
// 让range对象包含一个node的内容
range.selectNodeContents(span as HTMLElement);
// 向selection中添加一个区域(range)
selection?.addRange(range);
}
}
}
});
};
复制代码
技术方案实现的思路:api
/^[A-Z]{3}-[A-Z](-[0-9]{1,2})+$/
, 此正则表达式用到的符号的意思为:^ 表示(脱字符)匹配开头,在多行匹配中匹配行开头
[A-Z] 等价于全部大写字母
{m} 等价于{m,m},表示出现m次
[0-9] 等价于全部数字
{1,2} 等价于前面的内容出现一到两次
+等价于{1,},表示出现至少一次
$(美圆符号)匹配结尾,在多行匹配中匹配行结尾浏览器
优点: 能够在App.vue入口文件一次添加,不须要修改原有代码markdown
不足: 所须要高亮的数据须要有必定的结构特色,好比数据须要有必定的规则。还有就是全局添加click的监听事件,会增长一点性能消耗
文本全选实现方案总结
两种方案都有优缺点,须要结合具体的场景,需求来选取合适的方案,本文也只是提供一种思路的参考。
实现自动将内容复制到剪贴板中有三种方法:
Document.execCommand()
是操做剪贴板的传统方法,各类浏览器都支持。
它支持复制、剪切和粘贴这三个操做。
document.execCommand('copy')(复制)
document.execCommand('cut')(剪切)
document.execCommand('paste')(粘贴)
Document.execCommand() 方法的缺点是只能复制高亮文本的内容,不能够自定义信息放入剪贴板中, 并且这种方式只支持同步操做。可是对于咱们这个需求,这种方式已经足够了。
Clipboard 对象的全部操做都是异步的,返回 Promise 对象,不会形成页面卡顿。
const clipboardObj = navigator.clipboard;
并且,它能够将任意内容(好比图片)放入剪贴板。拥有如下4个方法:
Clipboard.readText() 方法用于复制剪贴板里面的文本数据。
Clipboard.read() 方法用于复制剪贴板里面的数据,能够是文本数据,也能够是二进制数据
Clipboard.writeText()方法用于将文本内容写入剪贴板
Clipboard.write()方法用于将任意数据写入剪贴板,能够是文本数据,也能够是二进制数据
这样的操做更加灵活,高效。可是缺点是 Chrome 浏览器规定,只有 HTTPS 协议的页面才能使用这个 API, 而咱们这个项目不是这种协议的,因此没法使用此 API。
此方法须要首先利用2.1中的document.execCommand('copy')
方法触发一个复制操做,而后利用监听copy进行处理。
document.addEventListener('copy', async (e) => {
e.preventDefault();
try {
let clipText = ''
...
// 将自定义的内容放入剪贴板中
e.clipboardData.setData('text/plain', clipText)
} catch (err) {
console.log(err);
}
});
复制代码
此需求并非这种方法的应用场景,此方法的应用场景以下:
当你但愿自定义放入一些内容在剪贴板中,可是你的项目又并非 HTTPS 的协议,就只有使用这种方法了。但须要注意一点, 因为 2.1 Document.execCommand()方法 是只支持同步的,因此若是在异步操做里面调用是没有用的,那么若是你想放入剪贴板中的内容是须要异步请求的,再请求以后想要直接调用复制操做的话就会失效。举代码例子:
async getData () {
try {
await this.getClipboardData();
// 这里的复制操做触发是无效的
document.execCommand("Copy")
}
}
复制代码
因此交互需变成,先保存异步回来的数据,等数据回来之后,再经过一个按钮或其余方式,同步出发复制操做。
自动触发复制的实现方案总结
三种方式都有其适合的应用场景,但第三种 copy 事件的方式会污染真正的复制操做,仍是不太建议使用,只能算是一种兜底的方案。
剪贴板操做 Clipboard API 教程
MDN: user-select
MDN: Selection
MDN: Document.createRange()
JS正则表达式完整教程
javascript实现鼠标点击自动选中点击元素内的文字