簡體   English   中英

需要按兩次 Enter 鍵才能添加范圍

[英]Enter key needs to be pressed twice for range to be added

我剛剛學會了如何使用selectionrange ,並建立了一個更好的方法來在 contenteditable div 中按下 Enter 鍵。 當按下回車鍵時, event.preventDefault()被調用,程序會在 contenteditable 通常會添加一個 div 的地方插入<br> 但是,我需要按兩次 Enter 才能發生任何事情。 另一個奇怪的事實:當該行上沒有文本時,這不會發生。 我是selectionrange的新手,我確定這是一個新手錯誤。 這是代碼:

 function keyExamine(e) {
    var doc = document.getElementById('cmd');
    e.keyCode = e.keyCode || e.which;
    if (e.keyCode == 13) {
        if (e.ctrlKey) {
            alert(doc.innerHTML);
        } else {
            e.preventDefault();
            initiateCommand(doc.innerHTML);
            var dv = doc.ownerDocument.defaultView;
            var sel = dv.getSelection();
            var range = sel.getRangeAt(0);
            var enterNode = document.createElement('br');
            range.insertNode(enterNode);
            range.setStartAfter(enterNode);
            range.setEndAfter(enterNode); 
            sel.removeAllRanges();
            sel.addRange(range);
            document.getElementById('maxback').innerText = doc.innerText.replace(/(\r\n\t|\n|\r\t)/gm,"").length;
        }
    } else if (e.keyCode == 38) {
        e.preventDefault();
    } else if (e.keyCode == 37 || e.keyCode == 8 || e.keyCode == 46) {
        var ml = Number(document.getElementById('maxback').innerText);
        if (getCaretPosition(doc) <= ml) {
            e.preventDefault();
        }
    } else {
        var ml = Number(document.getElementById('maxback').innerText);
        if (getCaretPosition(doc) < ml) {
            e.preventDefault();
        }
    }
}

function getCaretPosition(element) {
    var caretOffset = 0;
    var doc = element.ownerDocument || element.document;
    var win = doc.defaultView || doc.parentWindow;
    var sel;
    if (typeof win.getSelection != "undefined") {
        sel = win.getSelection();
        if (sel.rangeCount > 0) {
            var range = win.getSelection().getRangeAt(0);
            var preCaretRange = range.cloneRange();
            preCaretRange.selectNodeContents(element);
            preCaretRange.setEnd(range.endContainer, range.endOffset);
            caretOffset = preCaretRange.toString().length;
        }
    } else if ( (sel = doc.selection) && sel.type != "Control") {
        var textRange = sel.createRange();
        var preCaretTextRange = doc.body.createTextRange();
        preCaretTextRange.moveToElementText(element);
        preCaretTextRange.setEndPoint("EndToEnd", textRange);
        caretOffset = preCaretTextRange.text.length;
    }
    return caretOffset;
}

我有以下 HTML:

<p id='maxback' style='display: none'>0</p>
<p contenteditable="true" onkeydown="keyExamine(event)" id="cmd"></p>

有一種方法可以解決所有問題,同時避免許多陷阱。 您可以插入一個包含換行符的文本節點,然后將所有選擇折疊到它的末尾。

這種方法既獨立於平台又獨立於瀏覽器,一直工作到 IE9(理論上)。

主要缺點? 它依賴於未定義的行為,故意將折疊索引設置為超出節點長度。 碰巧所有瀏覽器都在插入節點后正確設置了選擇,即使在第一次按下 Enter 時也是如此。

function handleKey(event) {
  const editor = document.getElementById('cmd')
  if (event.key === 'Enter') {
    const node = document.createTextNode('\n')
    const range = window.getSelection().getRangeAt(0)
    range.insertNode(node)
    
    const selection = document.getSelection()
    if (selection) {
      selection.collapse(node, 2)
    }
    
    event.preventDefault()
  }
}

期待瀏覽器供應商在使用索引1調用折疊時將此作為默認行為。 希望有一天這會發生。

暫無
暫無

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

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