簡體   English   中英

修改選擇,選擇單詞,然后重新連接插入位置

[英]Modify selection, select word and then reattach the caret position

所以我想在javascript中創建一個所見即所得的編輯器。 我要做的是:當我沒有做出選擇並且只在一個單詞上放置插入符號時,我想選擇單詞,對其執行命令然后將插入符號移回其位置。

示例:在我執行代碼之前(插入符號應該在我的函數之后):

把這個詞改成b | old

后:

把這個詞加粗 |

jsFiddle示例: jsFiddle

我的代碼到目前為止:

    if (window.getSelection && (sel = window.getSelection()).modify) {
        doc.focus(); // the editor
        var range = sel.getRangeAt(0);
        var oldRange = document.createRange();
        oldRange.setStart(range.startContainer, range.startOffset);
        oldRange.setEnd(range.endContainer, range.endOffset);

        sel.collapseToStart();           

        sel.modify("move", "forward", "character");
        sel.modify("move", "backward", "word");
        sel.modify("extend", "forward", "word");

        document.execCommand(command, false, value);

        // Restore selection, Dosen't work as I expected
        sel.removeAllRanges();
        sel.addRange(oldRange);
}

問題是,在您運行document.execCommand ,它會重置范圍,您可以在oldRange上執行console.log並注釋掉document.execCommand行以進行確認。 保存舊范圍的唯一方法是序列化它,就像我在下面的例子中所做的那樣。 看一看

 changeStyle = function(command) { var sel; var doc = document.getElementById('editor'); if (window.getSelection && (sel = window.getSelection()).modify) { doc.focus(); var range = sel.getRangeAt(0); var oldRange = saveCaret(doc); sel.collapseToStart(); sel.modify("move", "forward", "character"); sel.modify("move", "backward", "word"); sel.modify("extend", "forward", "word"); document.execCommand(command, false, null); // Restore selection, well, it isn't restoring it restoreCaret(doc, oldRange) } } saveCaret = function(container) { var range = window.getSelection().getRangeAt(0); var preSelectionRange = range.cloneRange(); preSelectionRange.selectNodeContents(container); preSelectionRange.setEnd(range.startContainer, range.startOffset); var start = preSelectionRange.toString().length; return { start: start, end: start + range.toString().length }; }; restoreCaret = function(container, position) { var charIndex = 0, range = document.createRange(); range.setStart(container, 0); range.collapse(true); var nodeStack = [container], node, foundStart = false, stop = false; while (!stop && (node = nodeStack.pop())) { if (node.nodeType == 3) { var nextCharIndex = charIndex + node.length; if (!foundStart && position.start >= charIndex && position.start <= nextCharIndex) { range.setStart(node, position.start - charIndex); foundStart = true; } if (foundStart && position.end >= charIndex && position.end <= nextCharIndex) { range.setEnd(node, position.end - charIndex); stop = true; } charIndex = nextCharIndex; } else { var i = node.childNodes.length; while (i--) { nodeStack.push(node.childNodes[i]); } } } var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } 
 <button onclick="changeStyle('bold')"> Bold </button> <div contentEditable=true id="editor"> Try make a word bold without make a selection, the caret will either jump to the start of the word or the end. It should stay on its position. </div> 

對於任何可能在將來偶然發現此問題的人來說,實施並不是那么簡單 - 主要是由於難以跟蹤和操縱插入符號。 此外,跨瀏覽器行結束是任何嘗試實現中的問題的原因。

但是, jquery.caret在啟用插入信息和操作方面表現相當不錯,因此請考慮將其檢出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM