以這段文字為例子。。
<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;
轉自https://www.cnblogs.com/strangerqt/p/3745426.html