2016-02-09 149 views
1

我正在使用與contenteditable的div來創建文本編輯器。我覺得我在第一個障礙中失敗了。window.getSelection()返回意外值

<html> 
<head></head> 
<body> 
<input type="button" id="bold" value="B" /> 
<div id="wysiwyg" contenteditable="true" style="border:solid;width:500px;height:300px;"></div> 

<script> 
var bold = document.getElementById("bold"); 
var wysiwyg = document.getElementById("wysiwyg"); 

bold.addEventListener("click", function(){ 
    update("<b>", "</b>"); 
});  

function update(startTag, endTag){ 

//find the selected text 
var selected_text = ""; 
    if (window.getSelection) { 
     selected_text = window.getSelection(); 
    } else if (document.getSelection) { 
     selected_text = document.getSelection(); 
    } else if (document.selection) { 
     selected_text = document.selection.createRange().text; 
    } 

    //user could have selected in reverse, so we need to make sure the values are in correct order 
var startPos = selected_text.anchorOffset >= selected_text.focusOffset ? selected_text.focusOffset : selected_text.anchorOffset; 
var endPos = selected_text.focusOffset <= selected_text.anchorOffset ? selected_text.anchorOffset : selected_text.focusOffset; 

if (startPos == endPos) //There is no selection 
    return; 

var startText = wysiwyg.innerText.substr(0, startPos); 
var textToWrap = wysiwyg.innerText.substr(startPos, endPos- startPos); 
var endText = wysiwyg.innerText.substr(endPos); 
wysiwyg.innerHTML = startText + startTag + textToWrap + endTag + endText; 

} 

</script> 
</body> 
</html> 

如果要執行這個代碼,並鍵入3個字入格,選擇中間的單詞(高亮顯示鼠標),然後點擊屏幕上的B鍵(在HTML),你會注意該程序會根據需要執行,因爲它會使您突出顯示的單詞變爲粗體。

如果現在選擇您所鍵入的3的最後一個字,並儘量使其大膽,你會注意到的第一個詞變得大膽。

一看代碼,我看到的問題是selected_text.anchorOffset最初返回的是正確的值,但是在後續的請求中,它出錯了(或者至少提供了一個我不明白的值)。

這個JSFIDDLE將證明這個問題!

爲什麼window.getSelection返回incorect選定的文本的開始和結束位置?

回答

2

無需複雜化。如果您支持IE8及以上版本的瀏覽器,則可以使用execCommand函數。更新的代碼如下:

var bold = document.getElementById("bold"); 
var wysiwyg = document.getElementById("wysiwyg"); 

bold.addEventListener("click", function(){ 
    document.execCommand('bold'); 
}); 

要添加到答案,如果你還沒有弄清楚爲什麼你的代碼不工作。

首先,從MDN的定義focusOffset或anchorOffset(二者是相似的):

「Selection.focusOffset:本Selection.focusOffset只讀屬性返回選擇的焦點內的偏移的字符數Selection.focusNode。「

讓我們的文字的一個例子:「加粗文字」我們正在選擇「大膽」各一次。

第一次,它正確計算位置並使元素變爲粗體。所以新文本看起來像「Make text <b>bold</b>」。

第二次,它計算從<b>標籤的位置。所以,它的0-3和文本將是「<b>Make<b/> text bold」。

第三次,它計算從</b>標籤的位置。所以,其6-9和結果文本將是「Make t<b>ext </b>bold」。

第四次,指望從</b>標籤的位置。所以,它再次0-3。所以,0-3和6-9模式會一再重複。

+1

我恨這個答案,因爲我使用的textarea和一個div進行預覽已經創建了一個完整的編輯器...然後我雖然我很聰明,使用'contenteditable'有一個div ...而功能已經內置。多麼棘手的3天工作!無論如何,答案是完美的,我的編輯器現在可以更高效地工作,而無需顯示源代碼!謝謝 – MyDaftQuestions