有些頁面上的數據用戶常常須要全選而後進行復制的工做,用戶通常須要兩步操做,第一步是選中文本,用戶能夠經過三次點擊或着點擊後拖動鼠標來進行選中,第二步則是點擊右鍵選擇複製,或者利用鍵盤快捷鍵。爲了提升用戶體驗,咱們想要讓用戶點擊相關文字時候,自動全選而且完成複製操做。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實現鼠標點擊自動選中點擊元素內的文字