## 前言
今天來談談一個小小的需求:
產品:說給我這個添加一個復制功能,點一下把內容給我復制到粘貼板上。
我:好嘞
我:說上就上,5分鐘搞定,部署上去看一下,美滋滋,又是一天
5分鐘過去了...
測試:測試通過,可以了
產品:復制提示成功了,但是沒有在粘貼板上呢!!!
我和測試:蒙蔽了,咋會呢
產品:我的是蘋果電腦
我和測試:靠,產品這么豪嗎?都沒想BUG,一心想著,自己那破電腦...
我:沒辦法了,只能看一下什么問題了...
我:又是5分鐘過去了,發現:input自帶的select()方法在蘋果端無法進行選擇,問題找出了,那就干吧。
...
### 先看看我5分鐘CV出來的代碼
``` js
// 點擊復制到剪貼板函數
copyToClipboard(content) {
? ? ? if (window.clipboardData) {
? ? ? ? window.clipboardData.setData('text', content)
? ? ? } else {
? ? ? ? (function(content) {
? ? ? ? ? document.oncopy = function(e) {
? ? ? ? ? ? e.clipboardData.setData('text', content)
? ? ? ? ? ? e.preventDefault()
? ? ? ? ? ? document.oncopy = null
? ? ? ? ? }
? ? ? ? })(content)
? ? ? ? document.execCommand('Copy')
}
```
* 注:ios下不能執行document.execCommand('copy')
在ios設備下`alert(document.execCommand('copy'))`一直返回`false`
查閱相關資料發現ios下input不支持`input.select();`
* 其他兼容問題:
input 輸入框不能`hidden`或者`display: none`; 如果需要隱藏輸入框可以使用定位脫離文檔流,然后移除屏幕
### 解決input自帶的select()方法在蘋果端無法進行選擇
直接上完整代碼,看著就比較簡單了
``` js
copyText(text) {
? ? ? const textString = text.toString() // 數字沒有 .length 不能執行selectText 需要轉化成字符串
? ? ? let input = document.querySelector('#copy-input')
? ? ? if (!input) {
? ? ? ? input = document.createElement('input')
? ? ? ? input.id = 'copy-input'
? ? ? ? input.readOnly = 'readOnly' // 防止ios聚焦觸發鍵盤事件
? ? ? ? input.style.position = 'absolute'
? ? ? ? input.style.left = '-2000px'
? ? ? ? input.style.zIndex = '-2000'
? ? ? ? document.body.appendChild(input)
? ? ? }
? ? ? input.value = textString
? ? ? // ios必須先選中文字且不支持 input.select();
? ? ? this.selectText(input, 0, textString.length)
? ? ? if (document.execCommand('copy')) {
? ? ? ? document.execCommand('copy')
? ? ? ? this.$message.success('復制成功!')
? ? ? } else {
? ? ? ? this.$message.success('復制失敗!')
? ? ? }
? ? ? input.blur()
}
```
### input自帶的select()方法在蘋果端無法進行選擇,所以需要自己去寫一個類似的方法
``` js
// 選擇文本。createTextRange(setSelectionRange)是input方法
selectText(textbox, startIndex, stopIndex) {
? ? ? if (textbox.createTextRange) {
? ? ? ? // ie
? ? ? ? const range = textbox.createTextRange()
? ? ? ? range.collapse(true)
? ? ? ? range.moveStart('character', startIndex) // 起始光標
? ? ? ? range.moveEnd('character', stopIndex - startIndex) // 結束光標
? ? ? ? range.select() // 不兼容蘋果
? ? ? } else {
? ? ? ? // firefox/chrome
? ? ? ? textbox.setSelectionRange(startIndex, stopIndex)
? ? ? ? textbox.focus()
? ? ? }
}
```
## 兼容性補充:
必須手動觸發 點擊事件或者其他事件,不能直接使用js調用!!!
copyText('h5實現一鍵復制到粘貼板 兼容ios')
* 移動端:
安卓手機:微信(chrome)和幾個手機瀏覽器都可以用;
蘋果手機:微信里面和sarafi瀏覽器里也都可以;
* PC:
sarafi版本必須在10.2以上,其他瀏覽器可以。
## 總結
1.坑都是一步步填過來的,不要把沒做過作為理由,犯了就改,這就是經驗了,雖然表面上不是什么大問題,但是小心總是好的;
2.做事情需要考慮全面,不要讓“所謂得小事”而不放在心上,小事如果多了,性質就不一樣了
3.做事謹慎、謹慎、謹慎,重要得事情要說三次。
- 首頁
- 2021年
- 基礎知識
- 同源策略
- 跨域
- css
- less
- scss
- reset
- 超出文本顯示省略號
- 默認滾動條
- 清除浮動
- line-height與vertical-align
- box-sizing
- 動畫
- 布局
- JavaScript
- 設計模式
- 深淺拷貝
- 排序
- canvas
- 防抖節流
- 獲取屏幕/可視區域寬高
- 正則
- 重繪重排
- rem換算
- 手寫算法
- apply、call和bind原理與實現
- this的理解-普通函數、箭頭函數
- node
- nodejs
- express
- koa
- egg
- 基于nodeJS的全棧項目
- 小程序
- 常見問題
- ec-canvas之橫豎屏切換重繪
- 公眾號后臺基本配置
- 小程序發布協議更新
- 小程序引入iconfont字體
- Uni-app
- 環境搭建
- 項目搭建
- 數據庫
- MySQL數據庫安裝
- 數據庫圖形化界面常用命令行
- cmd命令行操作數據庫
- Redis安裝
- APP
- 控制縮放meta
- GIT
- 常用命令
- vsCode
- 常用插件
- Ajax
- axios-services
- 文章
- 如何讓代碼更加優雅
- 虛擬滾動
- 網站收藏
- 防抖節流之定時器清除問題
- 號稱破解全網會員的腳本
- 資料筆記
- 資料筆記2
- 公司面試題
- 服務器相關
- 前端自動化部署-jenkins
- nginx.conf配置
- https添加證書
- shell基本命令
- 微型ssh-deploy前端部署插件
- webpack
- 深入理解loader
- 深入理解plugin
- webpack注意事項
- vite和webpack區別
- React
- react+antd搭建
- Vue
- vue-cli
- vue.config.js
- 面板分割左右拖動
- vvmily-admin-template
- v-if與v-for那個優先級高?
- 下載excel
- 導入excel
- Echart-China-Map
- vue-xlsx(解析excel)
- 給elementUI的el-table添加骨架
- cdn引入配置
- Vue2.x之defineProperty應用
- 徹底弄懂diff算法的key作用
- 復制模板內容
- 表格操作按鈕太多
- element常用組件二次封裝
- Vue3.x
- Vue3快速上手(第一天)
- Vue3.x快速上手(第二天)
- Vue3.x快速上手(第三天)
- vue3+element-plus搭建項目
- vue3
- 腳手架
- vvmily-cli
- TS
- ts筆記
- common
- Date
- utils
- axios封裝
- 2022年
- HTML
- CSS基礎
- JavaScript 基礎
- 前端框架Vue
- 計算機網絡
- 瀏覽器相關
- 性能優化
- js手寫代碼
- 前端安全
- 前端算法
- 前端構建與編譯
- 操作系統
- Node.js
- 一些開放問題、智力題