IE6,IE7,IE8下使用Javascript記錄游標選中範圍(已補全)_javascript技巧

來源:互聯網
上載者:User
剛和同事討論了一個很有趣的問題,有個idea,需要記錄使用者在頁面選中的內容,在ff和ie9下有w3c的dom2級事件createRange,這裡不再累贅。主要問題是在IE6,7,8隻能通過createTextRange選中熱區。假如我們知道使用者選擇開始元素和位移量,以及結束元素以及位移量,那麼我們可以用下面的例子把使用者選擇的內容用js給標記起來
複製代碼 代碼如下:

<head>
<script>
function mark() {
var b= document.getElementById ("b");
var b1= document.getElementById ("b1");
var b2= document.getElementById ("b2");
var a1 = document.body.createTextRange();
a1.moveToElementText(b);
a1.moveStart('character',17);
var a2 = document.body.createTextRange();
a2.moveToElementText(b1);
a2.moveEnd('character',-2);
a1.setEndPoint ("EndToEnd",a2);
a1.select();
}</script>
</head>
<body>
<div id="b">The <b>contents</b> of the <i>source</i> element.</div>
<div id="b1">The <b>contents</b> of the <i>source</i> element.</div>
<div id="b2">The <b>contents</b> of the <i>source</i> element.</div>
<button onclick="mark();">Mark</button>
</body>

ok,從上面的代碼,我們可以知道,在IE6,7,8下,需要關聯多個元素的選擇時候,我們需要建立兩個textRange,一個是開始節點,以及位移量,還有一個結束節點,以及位移量,兩個textRange用a1.setEndPoint關聯

參考文檔:http://help.dottoro.com/ljgbbkjf.php

http://msdn.microsoft.com/en-us/library/ms535872%28VS.85%29.aspx

上面是我們知道開始結束位置的情況下,那我們如何知道使用者自己選中的熱區的開始,結束節點和位移量呢?

很可惜查了半天,MSDN只有以下幾個屬性可以利用,

textRange.parentElement返回選中熱區的父親節點,可以協助我們確定,一個大概的範圍

boundingLeft,offsetLeft,可以知道熱區的左位移距離

boundingTop,offsetTop,可以知道熱區的上位移距離

text,選中的常值內容,htmlText選中的html內容

可以沒有直接的index…,和開始節點。。。之類

好吧,如果我們要通過位置來算的話,我們可以通過每行的line-height,計算高度,如果是一個節點的話,要計算節點的height,padding,marging,

如果是計算左位移的話,要計算font-size,margin,padding,letter-space,這樣我們通過css的計算,可以得到大致的位置,

然後我們結合text,和htmlText去比對附近的元素的常值內容,可以得到索引的座標

這樣 基本上我們可以確定開始/結束節點,以及位移量了,

不過這樣做的成本也是比較高的,不知道大家還有沒有好的辦法,或者hacker的方法^_^

==================================================================================

剛才又看了下htmlText方法,有個驚奇的發現,還是上面的例子,htmlText返回如下

 

<DIV id=src>he <I>source</I> element.</DIV>
<DIV id=src1>The <B>contents</B> of the <I>source</I> element</DIV>

可以看到開始節點的tagName,還有選中的內容,可以通過去掉開頭結尾的html tag,然後用正則判斷取到這段html代碼在之前的parent.innerHTML的位置,這樣位移量也就取到了,ok,不需要通過判斷offset的方式,我們就可以取到開始,結束節點,以及位移量了

這樣在IE6,7,8下,可以記錄使用者任意選中的內容的開始、結束節點,以及位移量了^_^

 =============================================================

只是這樣做,還有一個唯一的缺點就是對於單個字元,或者重複出現的單詞,還是得通過css的offsetLeft 這樣的屬性 ,通過判斷距離,還確定是否是選中的那個,不知道大家有沒好的建議

===============================================================

然後今天早上,今天靈光一現,互發奇想,解決不需要通過offsetTop,left判斷單個node內部,重複字元的位移量問題

代碼如下

複製代碼 代碼如下:

<head>
<script>
function mark() {
var selection=document.selection.createRange();
if(selection.text.length==0){
return;
}
var textLength=event.srcElement.innerText.length;
var oldSelectionParent=selection.parentElement();
do{
selection.moveEnd("character",1);
}while(selection.parentElement()==oldSelectionParent);
selection.moveEnd("character",-1);
alert(textLength - selection.text.length);
}
function load(){
document.body.onmouseup=mark;
//document.body.onmousedown=mark;
}
</script>
</head>
<body onload="load()">
<div> 飛 a a a a 飛飛飛飛飛a飛 a a a </div>
</body>

原理就是利用在一個節點內部,不斷位移1個字元,到底部或者頂部,計算位移量的方法,因為對於單個元素內的熱區,他的parentElement()返回就是他自己,如果跨多個節點,之後,返回的parentNode就是他自己的父節點了,可以通過這個變化,判斷,是否移動到該節點文本的盡頭。^_^這樣就可以計算位移量了




ok,總結,通過htmlText的屬性可以解決多節點選中熱區的定位問題,對於單節點內部重複字元,可以通過文中最後一部分代碼解決,這樣在IE下,記錄游標選中位置,和複現的方法就完美了^_^


============================================

去kissy群問了下,原來承玉已經做過全相容的取位置的代碼,連結如下
http://www.jb51.net/article/28120.htm

代碼:http://lite-ext.googlecode.com/svn/trunk/lite-ext/playground/range/ie.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.