【问题标题】:Handle caret position in content editable div处理内容可编辑 div 中的插入符号位置
【发布时间】:2015-04-25 00:17:36
【问题描述】:

我在 HTML 中有这个内容可编辑的 div

<div contenteditable="true" id="TextOnlyPage"></div>

这是我的 jquery 代码

var rxp = new RegExp("(([0-9]+\.?[0-9]+)|([0-9]+))", "gm");
$('#TextOnlyPage').keyup(function(e){
    if(e.keyCode == 13){
        e.preventDefault();
        $('#TextOnlyPage').children().each(function() {
            if ( $(this).is("div") ) {
                $(this).contents().unwrap();
            }});
        $('#TextOnlyPage').append("<br/>");
    }
        $('#TextOnlyPage').children().contents().unwrap();
        var $this = $(this);
        var content = $this.html();
        $this.html(content.replace(rxp, "<span class='highlight'>$1</span>"));});

问题是插入符号的位置,因为当它在 string.replace 方法中围绕数字应用跨度标签时,光标会转到可编辑内容 div 的开头。当我按下回车键时,它也不能进入下一行。

我知道我可以通过 rangeselection 对象处理它,但找不到有用的资源来了解这些对象的工作原理。

请为我提供此问题的解决方案,如果使用 angularjs 解决方案会更好,或者为我提供一个资源,我可以通过工作示例了解范围和选择对象。

【问题讨论】:

  • 我假设您的意思是大于 [&gt;] 和小于 [&lt;] 的字符,因为在这篇文章的任何地方都没有插入符号 [^]?
  • @ethorn10 插入点位置,OP指的是插入点在文本框中的位置。
  • @ethorn10 对不起,我没有得到你..!

标签: javascript jquery angularjs caret


【解决方案1】:

我遇到了和你前段时间一样的问题,为了了解 rangeselection 的工作原理,我建议你查看 MDN 文档 SelectionRange

检测contentEditable div 变化的一种可靠方法是事件input。我在侦听 keyUp 并阻止某些 keyCode 的默认行为时发现的一个问题是它们数量众多,很难涵盖所有用例。

我更喜欢做的是让正常事件被处理,保存插入位置,获取文本值并替换需要突出显示的部分,然后将插入位置设置回来。

这是一个简单的例子

var contentEditable = document.querySelector('div[contenteditable]');
contentEditable.addEventListener('input', onInput);

var onInput = function(e) {

    // this function will be called after the current call-stack
    // is finished, at that time the user input will be inserted
    // in the content editable
    setTimeout(function() {

        // save the caret position

        var text = contentEditable.innerText;
        // perform all your replacement on `text`
        contentEditable.innerHTML = text;

        // set the caret position back
    }, 0);
}

我还编写了两个方便的方法getCaretOffsetWithinsetCaretPositionWithin 来帮助您在想要执行一些DOM 操作并在处理后将插入符号重新定位为其初始值时操作插入符号。

您可以在这个 gist contenteditable-utils.js 上查看它们

【讨论】:

  • 谢谢你的代码,伙计。为我节省了很多时间。
【解决方案2】:

以下是来自 MDN 的一些资源:SelectionRange

我创建了这个JSFiddle to demonstrate re-positioning the caret

它不适用于所有情况(例如,在输入时,使用 shift + 箭头选择范围......)但它应该已经给你一些想法。

这是来自 MDN 的关于创建选择的示例:

/* Select all STRONG elements in an HTML document */

var strongs = document.getElementsByTagName("strong");
var s = window.getSelection();

if(s.rangeCount > 0) s.removeAllRanges();

for(var i = 0; i < strongs.length; i++) {
    var range = document.createRange();
    range.selectNode(strongs[i]);
    s.addRange(range);
}

顺便说一句,与contentEditable 合作将来会带来更多麻烦,我建议您尽最大努力寻找替代方案。另外,请务必注意我提供的链接中的有限浏览器支持警告。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-24
    • 2011-10-07
    • 2011-04-27
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 2013-04-24
    相关资源
    最近更新 更多