前言
移動端專案開發中,經常遇到需要複製文字的場景,今天我們們就來聊一下,移動端複製文字的那些事~
效果預覽
背景分析
業務需求很簡單,將指定的文字(例如: 關鍵字、文案描述等)複製到手機的剪貼簿上,方便使用者直接進行貼上
解決方案
相關API
- document.execCommand
該方法允許執行命令來操縱可編輯內容區域的元素,其中執行 copy 命令,可以將當前選中的內容拷貝到剪貼簿中。相容性如下所示:
- setSelectionRange
該方法用於設定 input 或 textarea 元素中當前選中文字的起始和結束位置,接受兩個引數:被選中的第一個字元的位置索引、被選中的最後一個字元的下一個位置索引。相容性如下所示:
- select
該方法和 setSelectionRange 類似,唯一區別是 select 是全選,而 setSelectionRange 是手動指定選中範圍
實現思路
- DOM
在某一個 DOM 元素中新增一個容器 DOM ,然後在容器 DOM 中追加 input 標籤,並重置 input 的預設樣式,同時將容器 DOM 的寬度位置為 1 ,透明度設定為 0
.input_wrap {
position: absolute;
top: 0;
left: 0;
width: 1px;
opacity: 0;
overflow: hidden;
user-select: none;
}
.input_wrap input {
width: 1px;
resize: none;
border: none;
outline: none;
user-select: none;
color: transparent;
background: transparent;
}
<div class="input_wrap">
<input id="input" type="text" readonly="true">
</div>
- JS邏輯
首先獲取我們事先隱藏好的 input 元素,接著將 input 的 value 設定為待複製的文字,然後將焦點聚集在 input 上,再使用 setSelectionRange 方法選中待複製的文字,最後使用document.execCommand('copy')執行復制命令,即可將相關文字複製到客戶端的剪貼簿中
const input = document.getElementById('input');
input.value = '待複製的文字內容';
// 聚焦
input.focus();
// 選擇需要複製的文字
if (input.setSelectionRange) {
input.setSelectionRange(0, input.value.length);
} else {
input.select();
}
try {
const result = document.execCommand('copy');
console.error(result ? '內容已複製' : '複製失敗,請重試~');
} catch (e) {
console.error('複製失敗,請重試~');
}
體驗優化
儘管我們已經實現了複製的能力,但是複製之後頁面上會出現輸入鍵盤,為了更好的使用者體驗,我們需要想辦法遮蔽鍵盤
- blur
我們為了選中待複製的文案,手動呼叫了 input 的 focus 方法進行聚焦,為了遮蔽鍵盤,我們可以在複製結束後手動呼叫 input.blur() ,讓鍵盤自動隱藏
- activeElement
儘管我們手動呼叫了 blur 釋放焦點,但是部分機型上仍然會彈出輸入鍵盤,這裡想到的解決方案是使用 document.activeElement.blur() 來進行二次遮蔽,最終實踐效果還不錯,基本所有機型都不會彈出輸入鍵盤,或者彈出鍵盤後立馬回彈消失
小結
移動端實現複製能力,主要還是依賴HTML文件暴露的API來實現,最後花費時間最多的還是在進行體驗優化上