最近需要給HTML5的WebAPP在頁面上實現(xiàn)一個復(fù)制功能:用戶點擊長按文本會全選文字并彈出系統(tǒng)“復(fù)制”菜單,用戶可以點擊“復(fù)制”進(jìn)行復(fù)制操作,然后粘貼到AppStore搜索對應(yīng)的應(yīng)用。之所以不是采用鏈接形式直接跳轉(zhuǎn)到AppStore對應(yīng)應(yīng)用是為了通過用戶的主動輸入關(guān)鍵詞搜索給推廣的企業(yè)App增加權(quán)重。所以這一個“復(fù)制”功能對用戶的體驗至關(guān)重要。
嘗試了一些做法,在安卓/iOS平臺上的兼容性都不是很好。在微信瀏覽器內(nèi)是很容易實現(xiàn)長按文本激發(fā)系統(tǒng)菜單,高亮全選文本內(nèi)容的。但是在其他瀏覽器的表現(xiàn)就不是很一致了。包括模擬focus input,JavaScript Selection, 使用a標(biāo)簽嘗試激活系統(tǒng)菜單。這些方法都存在兼容的缺陷。
1)雖然使用帶有href屬性的a標(biāo)簽在uc瀏覽器和百度瀏覽器上長按文本會出現(xiàn)“自由復(fù)制”/“選擇文本”菜單,選擇該菜單后會出現(xiàn)“全選/復(fù)制”的菜單,但是在一些安卓手機(jī)的系統(tǒng)瀏覽器和iPhone中卻被視為純鏈接,只彈出“復(fù)制鏈接”,沒有“復(fù)制文本”菜單。況且即使只考慮少部分瀏覽器可行,這樣也給用戶操作多了一步,增加了復(fù)雜度。所以該方案不可取。
2)借助selection和range的方法需要考慮到不同瀏覽器的兼容性,代碼如下:
function selectText(element) { var doc = document, text = docgetElementById(element), range, selection; if (docbodycreateTextRange) { range = documentbodycreateTextRange(); rangemoveToElementText(text); rangeselect(); } else if (windowgetSelection) { selection = windowgetSelection(); range = documentcreateRange(); rangeselectNodeContents(text); selectionremoveAllRanges(); selectionaddRange(range); /*if(selectionsetBaseAndExtent){ selectionsetBaseAndExtent(text, 0, text, 1); }*/ }else{ alert("none"); } }
遺憾的是在iphone Safari上依然無法通過點擊或長按高亮選中所有文本(既然也支持window.getSelection,為何在Safari瀏覽器addRange操作后文本不能默認(rèn)選中,知道原因的請留言指教)。因此,該方式存在缺陷。主動選中文本區(qū)域的方法后面后附上。
3)iPhone用戶可能知道,長按某一文本選區(qū)內(nèi)文字周圍的空白區(qū)域,Safari會自動將該選區(qū)內(nèi)的文本高亮全選(目標(biāo)文本需要放在獨立的div塊級容器內(nèi))。根據(jù)這一特性,用CSS margin修飾一下,利用這個特點,正好可以解決上述第二種方法在ios設(shè)備的不兼容。經(jīng)過測試,無論安卓和ios平臺,一般手機(jī)自帶的系統(tǒng)瀏覽器都是可以兼容的。至于uc瀏覽器、百度瀏覽器等其他廠家的移動端產(chǎn)品,由于有不同的機(jī)制,只能使用這些瀏覽器菜單提供的“自由復(fù)制”功能。
所以,我綜合了第二種和第三種方式,使用jQuery mobile中的taphold事件來模擬longtap操作激發(fā)手機(jī)系統(tǒng)的復(fù)制菜單,這樣基本上可以做到在所有移動設(shè)備瀏覽器上都能實現(xiàn)長按文本區(qū)域來高亮選中所有文本內(nèi)容。再提一句,taphold的兼容bug這里就不詳細(xì)附解決方法了,如果你的項目要求精益求精,你可以自行搜索解決方案。
下面列出我的解決方案。具體代碼如下:
HTML代碼:
<div class=" para requirement"> <div class="tips tips-t"> 1、必須首次下載才生效<br/> 2、不能從排行榜下載哦 </div> <div class="cparea"> <div class="kwd" id="kwd"><span>三國艷義手機(jī)優(yōu)化大師</span></div> </div> <div class="cparea"> <span class="kdes"><b>★</b>長按虛線框,拷貝關(guān)鍵詞</span> </div> <a href="https://itunesapplecom/cn/" data-role="button" class="downlink">去AppStore搜索下載</a> </div>
JavaScript代碼:
<script type="text/javascript"> $("#kwd")bind("taphold", function(){ //不支持iPhone/iTouch/iPad Safari var doc = document, text = docgetElementById("kwd"), range, selection; if (docbodycreateTextRange) { range = documentbodycreateTextRange(); rangemoveToElementText(text); rangeselect(); } else if (windowgetSelection) { selection = windowgetSelection(); range = documentcreateRange(); rangeselectNodeContents(text); selectionremoveAllRanges(); selectionaddRange(range); }else{ alert("瀏覽器不支持長按復(fù)制功能"); } }); </script>
關(guān)鍵的CSS代碼:
cparea{ text-align: center; font-family: Microsoft Yahei; margin: -2em 0 0; } kwd{ display: inline-block; color: #272727; background-color: #fff; font-size: 1875em; font-size: 1875em; padding: 75em 1em; border: 1px dashed #e60012; -webkit-user-select:element; margin: 2em; } kwd span{ display: block; border: 1px solid #fff; } kdes{ display: inline-block; color: #212121; font-size: 875em; padding-top: 0; } kdes b{ color: #ed5353; font-size: 25em; padding-right: 1em; }
說明:這里的margin:2em正是為了實現(xiàn)Safari瀏覽器上的長按全選功能,為了尊重還原設(shè)計稿效果,父容器.cparea又使用了負(fù)邊距來抵消這個2em的外邊距。最終,不僅視覺上和設(shè)計圖保持了一致,也實現(xiàn)了長按全選激發(fā)系統(tǒng)菜單。
最后再補(bǔ)充一下支持Safari下的完整方法:
$("#kwd").bind("taphold", function(){ var doc = document, text = docgetElementById("kwd"), range, selection; if (docbodycreateTextRange) { //IE range = documentbodycreateTextRange(); rangemoveToElementText(text); rangeselect(); } else if (windowgetSelection) { //FF CH SF selection = windowgetSelection(); range = documentcreateRange(); rangeselectNodeContents(text); selectionremoveAllRanges(); selectionaddRange(range); //測試 consolelog(texttextContent); textinnerText && consolelog(textinnerText); //FireFox不支持innerText consolelog(texttextContentlength); textinnerText && consolelog(textinnerTextlength); //在Chrome下長度比IE/FF下多1 consolelog(textfirstChildtextContentlength); textinnerText && consolelog(textfirstChildinnerTextlength); consolelog(textfirstChildinnerHTMLlength); //注意IE9-不支持textContent makeSelection(0, textfirstChildtextContentlength, 0, textfirstChild); /* if(selectionsetBaseAndExtent){ selectionselectAllChildren(text); selectionsetBaseAndExtent(text, 0, text, 4); } */ }else{ alert("瀏覽器不支持長按復(fù)制功能"); } }); function makeSelection(start, end, child, parent) { var range = documentcreateRange(); //consolelog(parentchildNodes[child]); rangesetStart(parentchildNodes[child], start); rangesetEnd(parentchildNodes[child], end); var sel = windowgetSelection(); selremoveAllRanges(); seladdRange(range); }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。
新聞熱點
疑難解答