1. 程式人生 > >移動端html5頁面長按實現高亮全選文字內容的相容解決方案

移動端html5頁面長按實現高亮全選文字內容的相容解決方案

最近需要給html5的WebAPP在頁面上實現一個複製功能:使用者點選長按文字會全選文字並彈出系統“複製”選單,使用者可以點選“複製”進行復制操作,然後貼上到AppStore搜尋對應的應用。之所以不是採用連結形式直接跳轉到AppStore對應應用是為了通過使用者的主動輸入關鍵詞搜尋給推廣的企業App增加權重。所以這一個“複製”功能對使用者的體驗至關重要。

嘗試了一些做法,在安卓/iOS平臺上的相容性都不是很好。在微信瀏覽器內是很容易實現長按文字激發系統選單,高亮全選文字內容的。但是在其他瀏覽器的表現就不是很一致了。包括模擬focus input,JavaScript Selection, 使用a標籤嘗試啟用系統選單。這些方法都存在相容的缺陷。

1)雖然使用帶有href屬性的a標籤在uc瀏覽器和百度瀏覽器上長按文字會出現“自由複製”/“選擇文字”選單,選擇該選單後會出現“全選/複製”的選單,但是在一些安卓手機的系統瀏覽器和iPhone中卻被視為純連結,只彈出“複製連結”,沒有“複製文字”選單。況且即使只考慮少部分瀏覽器可行,這樣也給使用者操作多了一步,增加了複雜度。所以該方案不可取。

2)藉助selection和range的方法需要考慮到不同瀏覽器的相容性,程式碼如下:
function selectText(element) {
  var doc = document,
      text = doc.getElementById(element),
      range,
      selection;

  if (doc.body.createTextRange) {
      range = document.body.createTextRange();
      range.moveToElementText(text);
      range.select();
  } else if (window.getSelection) {
      selection = window.getSelection();        
      range = document.createRange();
      range.selectNodeContents(text);
      selection.removeAllRanges();
      selection.addRange(range);
      /*if(selection.setBaseAndExtent){
          selection.setBaseAndExtent(text, 0, text, 1);
      }*/
  }else{
      alert("none");
  }
}


遺憾的是在iphone Safari上依然無法通過點選或長按高亮選中所有文字(既然也支援window.getSelection,為何在Safari瀏覽器addRange操作後文本不能預設選中,知道原因的請留言指教)。因此,該方式存在缺陷。主動選中文字區域的方法後面後附上。

3)iPhone使用者可能知道,長按某一文字選區內文字周圍的空白區域,Safari會自動將該選區內的文字高亮全選(目標文字需要放在獨立的div塊級容器內)。根據這一特性,用CSS margin修飾一下,利用這個特點,正好可以解決上述第二種方法在ios裝置的不相容。經過測試,無論安卓和ios平臺,一般手機自帶的系統瀏覽器都是可以相容的。至於uc瀏覽器、百度瀏覽器等其他廠家的移動端產品,由於有不同的機制,只能使用這些瀏覽器選單提供的“自由複製”功能。

所以,我綜合了第二種和第三種方式,使用jquery mobile中的taphold事件來模擬longtap操作激發手機系統的複製選單,這樣基本上可以做到在所有移動裝置瀏覽器上都能實現長按文字區域來高亮選中所有文字內容。再提一句,taphold的相容bug這裡就不詳細附解決方法了,如果你的專案要求精益求精,你可以自行搜尋解決方案。

下面列出我的解決方案。具體程式碼如下:

HTML程式碼:

			<div class=" para requirement">
				<div class="tips tips-t">
					1、必須首次下載才生效<br/>
					2、不能從排行榜下載哦
				</div>
				<div class="cparea">
					<div class="kwd" id="kwd"><span>三國豔義手機優化大師</span></div>					
				</div>
				<div class="cparea">
					<span class="kdes"><b>★</b>長按虛線框,拷貝關鍵詞</span>
				</div>
				<a href="https://itunes.apple.com/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 = doc.getElementById("kwd"),
	    	range, 
	    	selection;
	    if (doc.body.createTextRange) {
	        range = document.body.createTextRange();
	        range.moveToElementText(text);
	        range.select();
	    } else if (window.getSelection) {
	        selection = window.getSelection();        
	        range = document.createRange();
	        range.selectNodeContents(text);
	        selection.removeAllRanges();
	        selection.addRange(range); 
	    }else{
	    	alert("瀏覽器不支援長按複製功能");
	    }		
	});

	</script>

關鍵的CSS程式碼:

.cparea{
	text-align: center;
	font-family: Microsoft Yahei;
	margin: -2em 0 0;
}
.kwd{
	display: inline-block;
	color: #272727;
	background-color: #fff;
	font-size: 1.1875em;
	font-size: 1.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: 1.25em;
	padding-right: .1em;
}

說明:這裡的margin:2em正是為了實現Safari瀏覽器上的長按全選功能,為了尊重還原設計稿效果,父容器.cparea又使用了負邊距來抵消這個2em的外邊距。最終,不僅視覺上和設計圖保持了一致,也實現了長按全選激發系統選單。


最後再補充一下支援Safari下的完整方法:

	$("#kwd").bind("taphold", function(){
	    var doc = document, 
	    	text = doc.getElementById("kwd"),
	    	range, 
	    	selection;
	    if (doc.body.createTextRange) {	//IE
	        range = document.body.createTextRange();
	        range.moveToElementText(text);
	        range.select();

	    } else if (window.getSelection) {	//FF CH SF
	        selection = window.getSelection();        
	        range = document.createRange();
	        range.selectNodeContents(text);
	        selection.removeAllRanges();
	        selection.addRange(range);

	        //測試
	        console.log(text.textContent);
	        text.innerText && console.log(text.innerText);	//FireFox不支援innerText
	        console.log(text.textContent.length);
	        text.innerText && console.log(text.innerText.length);	//在Chrome下長度比IE/FF下多1
	        console.log(text.firstChild.textContent.length);
	        text.innerText && console.log(text.firstChild.innerText.length);
	        console.log(text.firstChild.innerHTML.length);

	        //注意IE9-不支援textContent
	        makeSelection(0, text.firstChild.textContent.length, 0, text.firstChild);
        	/*
			if(selection.setBaseAndExtent){
	        	selection.selectAllChildren(text);
	        	selection.setBaseAndExtent(text, 0, text, 4);
	        }
	        */
	    }else{
	    	alert("瀏覽器不支援長按複製功能");
	    }
	
	});
	function makeSelection(start, end, child, parent) {
		var range = document.createRange();
		//console.log(parent.childNodes[child]);
		range.setStart(parent.childNodes[child], start);
		range.setEnd(parent.childNodes[child], end);

		var sel = window.getSelection();
		sel.removeAllRanges();
		sel.addRange(range); 
	}


轉載請註明來自於CSDN freshlover的空間。