处理内容可编辑div中的插入位置

时间:2015-04-25 00:17:36

标签: javascript jquery angularjs caret

我在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方法中的数字周围应用span标记时,光标将转到内容可编辑div的开头。当我按下回车键时,它也不能进入下一行。

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

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

2 个答案:

答案 0 :(得分:1)

我遇到了与您前一段时间相同的问题,为了了解rangeselection的工作原理,我建议您查看MDN文档Selection和{{3} }

检测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操作并将插入符号重新定位到其初始值。

您可以在这个要点Range

上查看它们

答案 1 :(得分:0)

以下是来自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合作将来会带来更多麻烦,我建议尽力找到替代方案。另外,请务必注意我提供的链接中有限的浏览器支持警告。