1. 程式人生 > >getSelection、range 物件屬性,方法理解,解釋

getSelection、range 物件屬性,方法理解,解釋

https://www.cnblogs.com/strangerqt/p/3745426.html


<p><b>法國國營鐵路公司(SNCF)20日承認,</b>新訂購的2000列火車因車體過寬,<strong>無法開進國內許多火車站的站臺,從而不得不花大筆資金改造站臺。</strong>法國國營鐵路公司發言人克里斯托夫·皮耶諾埃爾告訴法國新聞電臺:“我們發現問題晚了點。<b>我們承認這一失誤併為此承擔責任。”</b></p>以這段文字為例子。。

一個P標籤包含了文位元組點以及其他幾個標籤,標籤中包含了文位元組點。

selection 物件有一下幾個屬性:(以下都為chrome下單測的結果,firefox,IE另說)

  • anchorNode:anchorNode為selection物件的起點Node,假如選中的文字為“新訂購的2000列火”,那麼anchorNode就為“ 新訂購的2000列火車因車體過寬”, ”這個文位元組點。anchorNode還有幾個子屬性,我選出有用的有這麼幾個:length:這個節點的文字個數、nextSibling:這個文位元組點的下一個同級節點,這裡為 Strong標籤、previousSibling:這個文位元組點的前一個標籤,這裡是 B標籤、textContent:這個選中的文位元組點的全部文字,全部文字就是“ 新訂購的2000列火車因車體過寬, ”即便只選擇了“ 新訂購的2000列火 ”。以上只是選擇了單個的文字,還沒有跨標籤進行選擇,比如“  列火車因車體過寬,<strong>無法開進國內 ”這樣的選擇。也不會屬性對其造成影響。假如anchorNode起點為“  司(SNCF)20日承認,</b>新訂購的2000列火 ”這樣的呢?anchorNode起點就為 B 標籤裡面的textNode,有部分屬性就會產生變化。length:不變,都是textNode,nextSibling:變化了,B標籤裡面只有一個textnode,textnode的nextsibling就為null、previousSibling:和nextsibling 同理;textContent:不變;
  • anchorOffset:基於anchorNode也就是起點節點的偏移量,選中“  訂購的2000列火車因車體過 ”這段話,起點節點為“ 新訂購的2000列火車因車體過寬 “ 那麼偏移量就為1;
  • baseNode:和anchorNode 屬性一致。但是選擇的起點不同的話則完全不一樣。 假如選擇 ” 訂購的2000列火車因車體過 “ 這段話,anchorNode和baseNode的屬性完全一致。假如選擇起點為0,即anchorOffset為0的話屬性就完全不一樣了。比如”  新訂購的2000列火車因車體過寬, “這段話,baseNode的起點就是這個textNode的previousSibling: B標籤。其屬性length、nextsibling,previoussibling都為B標籤的文位元組點屬性 
  • baseOffset:和anchorOffset的一致,如果像”  新訂購的2000列火車因車體過寬, “這段話的話,那麼值就為previousSibling的textNode的length。
  • extentNode:selection選中文字的結束節點,假如選中的文字為“ 新訂購的2000列火 ”,那麼extentNode就為“ 新訂購的2000列火車因車體過寬 ”,這個屬性還有幾個子屬性,有用的幾個和anchorNode和baseNode基本一致,length:這個節點的文字個數、nextSibling:這個文位元組點的下一個同級節點,這裡為 Strong標籤、previousSibling:這個文位元組點的前一個標籤,這裡是 B標籤、textContent:這個選中的文位元組點的全部文字,全部文字就是“ 新訂購的2000列火車因車體過寬, ”即便只選擇了“ 新訂購的2000列火 ”。以上只是選擇了單個的文字,還沒有跨標籤進行選擇,比如“  列火車因車體過寬,<strong>無法開進國內 ”這樣的選擇的話,看最後選中的文字所處的地方,“  列火車因車體過寬,<strong>無法開進國內 ” 國內所處的標籤是 Strong標籤,那麼extentNode就為Strong標籤的 textNode,其length,nextSiblint,previousSibling,textContents都要做出相應的改變.
  • extentOffset:選中文字最後所處的標籤的偏移量。“  列火車因車體過寬,<strong>無法開進國 ” 這個內字在Strong標籤內所處的位置就是extentOffset的值。
  • focusNode:屬性和定於與extentNode完全一致
  • focusOffset:屬性和定義與extentOffset完全一致
  • getRangeAt:把選中的文字轉化為range物件,可以進行操作。接受一個引數,一般填寫為0,表示從selection物件的0開是進行轉化;

以上的屬性為chrome下console selection物件出來的與FF IE不一致,下面來說FF的selection物件屬性,方法;

FF的selection 方法基本和chrome的一樣,但是少了baseNode和extentNode以及extentOffset,baseOffset這4個屬性,所以綜上所述胃:起點節點用的屬性為anchorNode,結束節點為focusNode的屬性即可

IE下的的selection物件與上面又不相同為:

seletion物件屬性和方法完全不同於W3C的selection之屬性,方法;

                            RANGE物件

range物件也分為IE和W3C物件;range物件可以對選中的文字進行新增物件,刪除,變粗,改變字型等適合用於網頁富文字編輯等。在網上一搜一大片,我選幾個目前能用到的屬性來記錄下。

W3C range:可以由selection物件建立也可以由document來建立。兩者的區別為selection已經選好的range物件,通過selection.getRangeAt(0);來得到從selection 0開始的range物件;通過Document來建立就要稍微複雜一點,首先要確定range物件來自哪個元素,就拿上面的列子來講;range物件來自P標籤這個DOM物件;另外,range物件有4個基本屬性:

  • startContainer:要選中的range物件開始的父節點,比如range物件是“法國國營鐵路公司”   那麼startContainer就是這個段文字所在標籤B的文位元組點。這個物件是可以被制定為文位元組點或則一般節點。
  • startOffset:選中的range物件的起點,假如是文位元組點,註釋等,那麼這個值就是這個range物件第一個字所在該文位元組點的索引值;比如“國營鐵路公司” 這個range物件第一個字是“國”,所在的text節點是“  法國國營鐵路公司(SNCF)20日承認, ” 那麼國字在這段文字的第2個。所以startOffset的值就為2。。萬一我們選擇的startContainer為一般節點,那麼該值就為子節點的索引值;就拿上面列子來說,選擇range物件為“ 無法開進國內許多火車站的站臺,從而不得不花大筆資金改造站臺。 ”,startContainer為P標籤的話。那麼startOffset就為“ 1 ”;
  • endOffset:選擇規則和startOffset一致
  • endContainer:range結束時文字的父物件所在節點;比如” 臺:“我們發現問題晚了點。<b>我們承認這一 “  那麼endContainer就是B節點的文字節點;
  • commonAncestorContainer:endContainer和startContainer的共同父節點在這個Document最深的一個(最近的一個);比如“法國國營鐵路公司“ 這種range物件所在End和startContainer的共同祖先都是文字節點。如果是跨標籤的話,比如” 20日承認,</b>新訂購的 “ startContainer是B標籤的文字節點,endContainer是P標籤。那麼他們的共同祖先就是P標籤;

一般選擇:使用range.SelectNode(Dom)連同startContainer和endContainer一同選中;包含標籤;range.SelectNodeContents(Dom);選中除了start,endContainer之外的內容,只是內容,不包含標籤;

複雜選擇:可以指定選擇某段文字從哪開始從哪結束;有2個方法,為setStart,setEnd;方法分別接受2個引數,第一個引數為這個range物件的container,第2個引數為索引值;start和end2個方法的引數分別對應為setStart(startContainer,startOffset);setEnd(endContainer,endOffset);

以上就是range物件的基本屬性和選擇方式,分為selection選擇和自己輸入引數建立;下面就是實際操作range物件,讓其實現富文字編輯;

  • insertNode:插入節點,建立一個節點,比如span標籤,插入到這個range物件的開始處;用法:range.insertNode(span標籤);
  • surroundContent:環繞節點,建立一個節點,比如span標籤,把range物件新增進這個span標籤。用處:一般用來設定其CSS樣式等比如設定背景色;用法:range.surroundContents(span標籤);(注:這個方法只能用於startContaienr和endContainer都是文字節點並且range沒有跨標籤。比如” 臺:“我們發現問題晚了點。<b>我們承認這一 “  這種不行,要報錯,解決方法是用extractContents方法提出來,新增進span,使用insetAdjacentHTML新增;

extractContents:提取並刪除range物件,返回一個document.fragment物件;相當於我們的剪下功能;這方法和insertAdjacentHTML配合非常牛逼;例子:比如我們” 臺:“我們發現問題晚了點。<b>我們承認這一 “  這種range物件的話有一部分的B標籤在裡面,那麼使用這個方法的話,剪下後,B標籤會自動補全開始和閉合標籤,內容為剪下剩下的內容。比如剪下上面的range後,B標籤就變成了<b>失誤併為此承擔責任。”</b> range中含有B標籤部分的文字也會自動閉合成一個完整的B標籤例如:<b>我們承認這一</b>; 

要使用insetAdjacentElement的話,必須知道呼叫insetAdjacentElement的節點為哪個。比如要把剪切出來的內容原原本本添加個背景色後還原,那麼就必須知道確切的使用“insetAdjacentElement”的DOM節點。insetAdjacentElement可以新增在這個DOM節點的標籤面前,內容開始前,內容結束後,標籤結束後。分別為beforeBegin,beforeBegin,beforeEnd,afterEnd; 如何知道確切的呼叫這個方法的DOM節點呢?前面的selection物件的anchorNode和focusNode就派上用場了。我們分別得到這2個節點的父節點;總共有這麼幾種可能性:

1:假如起始節點的父節點不這個例子的根節點的話,那麼說明range物件的anchroeNode是一個子節點而非文字節點,那麼我們就把提取出來的range新增進span使用ahchorNode.insetAdjacentElement('afterEnd',span)來添到經過extractContents後自動閉合的起始節點的後面;

2:假如起始父節點為這個例子的根節點,但是結束父節點不是的話,那麼就是FocusNode.insetAdjacentElement('beforeBegin',span)來新增到這個節點的前面;

3:假如起始父節點和結束父節點為相同的話,那麼說明這個range的anchor和FocusNode都在子節點裡面;使用surroundContents即可。

4:起始父節點為例子的根節點,結束父節點不是,那麼就以結束父節點為起點,使用FocusNode.insetAdjacentElement('beforeBegin',span);

5:假如起始和結束父節點都是例子的話使用surroungContents即可。

但是有一點不同的是,在firefox下insetAdjacentElement不是一個有效的方法,firefox只支援insetAdjacentHTML。在chrome下HTML,TEXT,ELEMENT都支援。

目前在firefox下要使用怎麼辦呢?只支援insetAdjacentHTML的話我們就用span的innerHTML來拼接一個新的span就是了哇

如:FocusNode.insetAdjacentElement('beforeBegin',"<span style='background-color:red'>"+span.innerHTML+"</span>")   problem solved~~

                                                      IE下實現range給背景新增顏色等操作  

IE下的selection為document.selection;獲取selection選中的range物件為document.selection.createRange();

由於IE的selection物件沒有anchorNode等屬性,所以新增背景色等操作就用不到insetAdjacentElement這樣的函式,那麼是怎麼樣進行操作的呢?

IE特有的execCommad來執行的,這個方法非常的強大,可以把range物件替換為其他的文字,input,img標籤,還可以給range物件的文字進行樣式設定;

獲取range物件的方式和W3C一致,分別是通過selection 來獲取,還有就是通過建立range物件;

selection建立:document.selection.createRange();

range物件建立:IE可以用不同標籤來建立不同選擇區域的range物件。比如用body建立range物件,那麼range物件的選擇區域就是整個頁面了:獲取整個body的range:document.body.createTextRange();目前IE range物件支援由body,input,button,textarea建立的range物件

簡單的選擇range物件:range.findText(”查詢的文字“),返回一個bool值,true為找到值,false為沒找到;例如上面的例子”  公司(SNCF) “  range.findText('公司(SNCF)'); 返回true,就可以使用execCommad操作物件了;注意:使用這個方法時候要注意range物件是由哪個標籤建立的。比如Button建立的range物件要查詢由textarea建立的range物件在textarea中的值,肯定是找不到的;

複雜的選擇:IE range複雜的選擇是通過moveStart,moveEnd來前後移動range選區;

這2個方法接受2個引數,第一個是移動的型別; 有4個型別:

character:按照字元進行移動,最小單位

word:按照單詞進行移動;

sentence:按照句子進行移動;

textedit:直接移動到選區的結束位置,start傳入這個引數無效,只有end方法傳入才還效

第2個引數是數字,具體移動的個數,可以接受負值;start方法的數字是range開始起第幾個開始計算;end方法的傳入數字是這段range的結束位置起開始算,正數的話就是range的結束範圍就是range本身的長度。負數的話那麼就是range的長度減去負數值(絕對值);比如 一段完整的range文字,法國國營鐵路公司(SNCF)20日承認,  我們要擷取“鐵路公司” 話看下面的例子:

這裡用character來做例子;

range.moveStart('character',4);

range.moveEnd('character',-11);

那麼range的範圍就是建立這個range的元素的開始第4個到第8個之間的位置;

操作range物件

IE操作range物件全是通過execCommad來進行操作的

execCommad的引數有3個,

引數A,操作的型別比如設定range的css屬性,剪下,複製,把range的文字轉化成input、textarea標籤等,

引數B,為bool值,在引數A為替換元素,新增連結的情況下才有用,目的為是否彈出框來確定這個操作,true為彈出,false為不彈出;

引數C,為引數A的具體屬性,比如設定背景色的顏色,替換元素的ID屬性,替換超連結的URL等;

引數A的部分引數為:

 

  • 2D-Position 允許通過拖曳移動絕對定位的物件。 
  • AbsolutePosition 設定元素的 position 屬性為“absolute”(絕對)。 
  • BackColor 設定或獲取當前選中區的背景顏色。 
  • BlockDirLTR 目前尚未支援。 
  • BlockDirRTL 目前尚未支援。 
  • Bold 切換當前選中區的粗體顯示與否。 
  • BrowseMode 目前尚未支援。 
  • Copy 將當前選中區複製到剪貼簿。 
  • CreateBookmark 建立一個書籤錨或獲取當前選中區或插入點的書籤錨的名稱。 
  • CreateLink 在當前選中區上插入超級連結,或顯示一個對話方塊允許使用者指定要為當前選中區插入的超級連結的 URL。 
  • Cut 將當前選中區複製到剪貼簿並刪除之。 
  • Delete 刪除當前選中區。 
  • DirLTR 目前尚未支援。 
  • DirRTL 目前尚未支援。 
  • EditMode 目前尚未支援。 
  • FontName 設定或獲取當前選中區的字型。 
  • FontSize 設定或獲取當前選中區的字型大小。 
  • ForeColor 設定或獲取當前選中區的前景(文字)顏色。 
  • FormatBlock 設定當前塊格式化標籤。 
  • Indent 增加選中文字的縮排。 
  • InlineDirLTR 目前尚未支援。 
  • InlineDirRTL 目前尚未支援。 
  • InsertButton 用按鈕控制元件覆蓋當前選中區。 
  • InsertFieldset 用方框覆蓋當前選中區。 
  • InsertHorizontalRule 用水平線覆蓋當前選中區。 
  • InsertIFrame 用內嵌框架覆蓋當前選中區。 
  • InsertImage 用影象覆蓋當前選中區。 
  • InsertInputButton 用按鈕控制元件覆蓋當前選中區。 
  • InsertInputCheckbox 用複選框控制元件覆蓋當前選中區。 
  • InsertInputFileUpload 用檔案上載控制元件覆蓋當前選中區。 
  • InsertInputHidden 插入隱藏控制元件覆蓋當前選中區。 
  • InsertInputImage 用影象控制元件覆蓋當前選中區。 
  • InsertInputPassword 用密碼控制元件覆蓋當前選中區。 
  • InsertInputRadio 用單選鈕控制元件覆蓋當前選中區。 
  • InsertInputReset 用重置控制元件覆蓋當前選中區。 
  • InsertInputSubmit 用提交控制元件覆蓋當前選中區。 
  • InsertInputText 用文字控制元件覆蓋當前選中區。 
  • InsertMarquee 用空字幕覆蓋當前選中區。 
  • InsertOrderedList 切換當前選中區是編號列表還是常規格式化塊。 
  • InsertParagraph 用換行覆蓋當前選中區。 
  • InsertSelectDropdown 用下拉框控制元件覆蓋當前選中區。 
  • InsertSelectListbox 用列表框控制元件覆蓋當前選中區。 
  • InsertTextArea 用多行文字輸入控制元件覆蓋當前選中區。 
  • InsertUnorderedList 切換當前選中區是專案符號列表還是常規格式化塊。 
  • Italic 切換當前選中區斜體顯示與否。 
  • JustifyCenter 將當前選中區在所在格式化塊置中。 
  • JustifyFull 目前尚未支援。 
  • JustifyLeft 將當前選中區所在格式化塊左對齊。 
  • JustifyNone 目前尚未支援。 
  • JustifyRight 將當前選中區所在格式化塊右對齊。 
  • LiveResize 迫使 MSHTML 編輯器在縮放或移動過程中持續更新元素外觀,而不是隻在移動或縮放完成後更新。 
  • MultipleSelection 允許當用戶按住 Shift 或 Ctrl 鍵時一次選中多於一個站點可選元素。 
  • Open 目前尚未支援。 
  • Outdent 減少選中區所在格式化塊的縮排。 
  • OverWrite 切換文字狀態的插入和覆蓋。 
  • Paste 用剪貼簿內容覆蓋當前選中區。 
  • PlayImage 目前尚未支援。 
  • Print 開啟列印對話方塊以便使用者可以列印當前頁。 
  • Redo 目前尚未支援。 
  • Refresh 重新整理當前文件。 
  • RemoveFormat 從當前選中區中刪除格式化標籤。 
  • RemoveParaFormat 目前尚未支援。 
  • SaveAs 將當前 Web 頁面儲存為檔案。 
  • SelectAll 選中整個文件。 
  • SizeToControl 目前尚未支援。 
  • SizeToControlHeight 目前尚未支援。 
  • SizeToControlWidth 目前尚未支援。 
  • Stop 目前尚未支援。 
  • StopImage 目前尚未支援。 
  • StrikeThrough 目前尚未支援。 
  • Subscript 目前尚未支援。 
  • Superscript 目前尚未支援。 
  • UnBookmark 從當前選中區中刪除全部書籤。 
  • Underline 切換當前選中區的下劃線顯示與否。 
  • Undo 目前尚未支援。 
  • Unlink 從當前選中區中刪除全部超級連結。 
  • Unselect 清除當前選中區的選中狀態。

 

列如我們要設定背景色就為ragne.execCommad('BackColor','true','red');背景色為紅色,其他css屬性一直;

替換元素成TextBox並且把textbox的值設定為替換前的值:

var text=range.text;

range.execCommad('InsertInputText','false','tba');

document.getElementById('tba').value=text;