一、如何在可編輯區域div的光標處通過點擊事件來添加文本內容
下面的例子是可編輯div的區域添加文本內容和判斷光標位置的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
焦點位置:<input id="i1">選中文本:<input id="i2">
<div id="d1" contenteditable="true" style="width:200px;height:100px;border:1px solid black">1234567890abcdef
</div>
<button id="add">添加文字</button>
</body>
<script type="text/javascript">
add.onclick=function () {
var obj= d1;
var range, node;
if(!obj.hasfocus) {
obj.focus();
}
if (window.getSelection && window.getSelection().getRangeAt) {
range = window.getSelection().getRangeAt(0);
range.collapse(false);
node = range.createContextualFragment('10000ss');
var c = node.lastChild;
range.insertNode(node);
if(c){
range.setEndAfter(c);
range.setStartAfter(c)
}
var j = window.getSelection();
j.removeAllRanges(); range = window.getSelection().getRangeAt(0);
j.addRange(range);
} else if (document.selection && document.selection.createRange) {
document.selection.createRange().pasteHTML(text);
}
}
document.onselectionchange = function (e) {
// ie11
//判斷是否支持document.selection屬性
if (document.selection) {
var pos = 0;
var range = document.selection.createRange();
var srcele = range.parentElement();
//新建一個range,焦點在開頭
var copy = document.body.createTextRange();
copy.moveToElementText(srcele);
//判斷copy的焦點起始部分是否在range的焦點起始部分的后面
for (pos = 0; copy.compareEndPoints("StartToStart", range) < 0; pos++) {
//copy的焦點向后移動一個字符
copy.moveStart("character", 1);
}
document.getElementById('i1').value = pos;
document.getElementById('i2').value = range.htmlText;
}
// chrome uc
if (window.getSelection) {
//獲取Selection對象
var se = window.getSelection();
//獲取起始位置,這個是字符的序號位置,而不是坐標
var start = se.anchorOffset;
//獲取結束位置
var end = se.focusOffset;
//獲取起始的dom元素
var startEl = se.anchorNode.parentElement;
//獲取結束的dom元素
var endEl = se.focusNode.parentElement;
//獲取起始dom元素的文本內容
var startText = startEl.innerText;
var txt = '';
if (startEl == endEl) {
txt = startText.substring(start, end);
}
document.getElementById('i1').value = start;
document.getElementById('i2').value = txt;
}
}
</script>
</html>
range.startOffset;相對於上個元素
獲取整個元素偏移量的方法(復制的情況需要自己來計算)
var range = window.getSelection().getRangeAt(0);
var offset = 0;
var str = '';
var container = range.endContainer;
console.log(container)
var i=0;
while(container.previousSibling){
// console.log(container.previousSibling.textContent.trim());
// console.log(container.previousSibling.textContent.trim().length);
str += container.previousSibling.textContent.trim();
offset += container.previousSibling.textContent.trim().length;
container = container.previousSibling;
i++;
// console.log(offset,container.previousSibling.textContent.trim().length)
}
selection是對當前激活選中區(即高亮文本)進行操作。
在非IE瀏覽器(Firefox、Safari、Chrome、Opera)下可以使用window.getSelection()獲得selection對象,本文講述的是標准的selection操作方法。文中絕大部分內容來自 https://developer.mozilla.org/en/DOM/Selection
術語
以下幾個名詞是英文文檔中的幾個名詞。
- anchor
- 選中區域的“起點”。
- focus
- 選中區域的“結束點”。
- range
- 是一種fragment(HTML片斷),它包含了節點或文本節點的一部分。一般情況下,同一時刻頁面中只可能有一個range,也有可能是多個range(使用Ctrl健進行多選,不過有的瀏覽器不允許,例如Chrome)。可以從selection中獲得range對象,也可以使用document.createRange()方法獲得。
屬性
- anchorNode
- 返回包含“起點”的節點。
- anchorOffset
- “起點”在anchorNode中的偏移量。
- focusNode
- 返回包含“結束點”的節點。
- focusOffset
- “結束點”在focusNode中的偏移量。
- isCollapsed
- “起點”和“結束點”是否重合。
- rangeCount
- 返回selection中包含的range對象的數目,一般存在一個range,Ctrl健配合使用可以有多個。
方法
- getRangeAt(index)
-
從當前selection對象中獲得一個range對象。
index:參考rangeCount屬性。
返回:根據下標index返回相應的range對象。 - collapse(parentNode, offset)
-
將開始點和結束點合並到指定節點(parentNode)的相應(offset)位置。
parentNode:焦點(插入符)將會在此節點內。
offset: 取值范圍應當是[0, 1, 2, 3, parentNode.childNodes.length]。
- 0:定位到第一個子節點前。
- 1:第二個子節點前。
- ……
- childNodes.length-1:最后一個子節點前。
- childNodes.length:最后一個子節點后。
- extend(parentNode, offset)
-
將“結束點”移動到指定節點(parentNode)的指定位置(offset)。
“起點”不會移動,新的selection是從“起點”到“結束點”的區域,與方向無關(新的“結束點”可以在原“起點”的前面)。
parentNode:焦點將會在此節點內。
Offset:1,parentNode的最后;0,parentNode的最前。 - modify(alter, direction, granularity)
-
改變焦點的位置,或擴展|縮小selection的大小
alter:改變的方式。”move”,用於移動焦點;”extend”,用於改變selection。
direction:移動的方向。可選值forward | backword或left | right
granularity:移動的單位或尺寸。可選值,character", "word", "sentence", "line", "paragraph", "lineboundary", "sentenceboundary", "paragraphboundary", or "documentboundary"。
Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1才會支持此函數, 官方文檔: https://developer.mozilla.org/en/DOM/Selection/modify - collapseToStart()
- 將“結束點”移動到,selction的“起點”,多個range時也是如此。
- collapseToEnd()
- 將“起點”移動到,selction的“結束點”,多個range時也是如此。
- selectAllChildren(parentNode)
- 將parentNode的所有后代節點(parentNode除外)變為selection,頁面中原來的selection將被拋棄。
- addRange(range)
-
將range添加到selection當中,所以一個selection中可以有多個range。
注意Chrome不允許同時存在多個range,它的處理方式和Firefox有些不同。 - removeRange(range)
-
從當前selection移除range對象,返回值undefined。
Chrome目前沒有改函數,即便是在Firefox中如果用自己創建(document.createRange())的range作為參數也會報錯。
如果用oSelction.getRangeAt()取到的,則不會報錯。 - removeAllRanges()
- 移除selection中所有的range對象,執行后anchorNode、focusNode被設置為null,不存在任何被選中的內容。
- toString()
- 返回selection的純文本,不包含標簽。
- containsNode(aNode, aPartlyContained)
-
判斷一個節點是否是selction的一部分。
aNode:要驗證的節點。
aPartlyContained:true,只要aNode有一部分屬於selection就返回true;false,aNode必須全部屬於selection時才返回true。
