contenteditable 元素中的 selectionStart 和 selectionEnd

Posted

技术标签:

【中文标题】contenteditable 元素中的 selectionStart 和 selectionEnd【英文标题】:selectionStart and selectionEnd in contenteditable element 【发布时间】:2013-10-17 19:06:18 【问题描述】:

我一直在努力使 textarea 的 selectionStartselectionEnd 属性与 contenteditable div 元素一起使用。我在 google 和 SO 上查看了很多相关文章,但无济于事。我有类似于以下内容的内容,非常适用于 textarea。但我希望这个可以与 contenteditable div 一起使用。

function replaceVal(node, val, step)
    //...
    var cursorLoc =  node.selectionStart;
    node.value = node.value.substring(0, node.selectionStart - step) + value +
    node.value.substring(node.selectionEnd, node.value.length);
    node.scrollTop = scrollTop;
    node.selectionStart = cursorLoc + value.length - step;
    node.selectionEnd = cursorLoc + value.length - step;
  //...

如何修改它以使其与 contenteditable div 元素而不是 textarea 一起使用?

【问题讨论】:

获取:***.com/questions/13949059/…。设置:***.com/a/16100733/96100 @TimDown 我检查了链接,它们确实很有帮助。但是我仍然在将每个按下的键值正确附加到 contentEditable 时遇到问题。我已将 node.value 替换为 node.childNodes[0].nodeValue 并且每个字符都附加在 div 中。但是,当我按 Enter 并开始输入时,字符会附加到前面的字符上,而忽略 Enter 键(将替换为 )。如何让 contentEditable 理解 html 标签,如 和

@semytech 你解决过 HTML 标签的问题吗? 我遇到了类似的问题,我找到了从选择中创建 TextRange 的解决方案。在这种情况下,您可以修改范围边界并重新选择内容。请访问此问题:http://***.com/questions/24958043/create-textselection-from-selection-in-ie11 【参考方案1】:

试试这个,它返回选择的文本,不管它是否是 contentEditable 。

function GetSelectedText() 

            if (document.getSelection)     // all browsers, except IE before version 9
                var sel = document.getSelection();
                    // sel is a string in Firefox and Opera, 
                    // and a selectionRange object in Google Chrome, Safari and IE from version 9
                    // the alert method displays the result of the toString method of the passed object
                alert(sel);
             
            else 
                if (document.selection)    // Internet Explorer before version 9
                    var textRange = document.selection.createRange();
                    alert(textRange.text);
                
            
        
<div>Test Example Microsoft T-shirt box</div>
<button onClick="GetSelectedText()">Get text</button>

我在 jsfiddler 中做了这个例子,看到 enter link description here

【讨论】:

【参考方案2】:

使用getSelection()方法中的Selection对象获取baseOffsetextentOffset的contentEditable元素

var sel = document.getSelection();
node.value = node.value.slice(0, sel.baseOffset - step) + value + node.value.slice(sel.extentOffset);

【讨论】:

【参考方案3】:

这个答案使用了非标准的Selection#modify,但至少,我建议你使用“insertText”命令:

function replaceVal(val, step) 
  var selection = window.getSelection();
  for (var i = 0; i < step; i += 1) 
    selection.modify('extend', 'backward', 'character');
  
  document.execCommand('insertText', false, val);
<label for="editable">Editable:</label>
<div contenteditable="true" id="editable">Test test test</div>
<label for="step">Step:</label>
<input type="number" id="step" name="step" min="0" step="1" value="0" />
<button onClick="replaceVal('insertion', Number(document.getElementById('step').value))">Get text</button>

【讨论】:

以上是关于contenteditable 元素中的 selectionStart 和 selectionEnd的主要内容,如果未能解决你的问题,请参考以下文章

contenteditable:使用行/列修饰符时检测元素变化

contenteditable div 中的 HTML5 可拖动元素 - 第一次放置后停止工作 - 为啥?

contenteditable属性

Vue.js 删除渲染函数中的 contenteditable 属性

当父元素是 contentEditable 时,是不是可以防止子元素被删除?

contenteditable元素的placeholder输入提示语设置