Rangy和IE8-在段落末尾的元素后面放置插入符号

Rangy and IE8 - positioning caret after element at end of paragraph

本文关键字:符号 插入 元素 IE8- 段落末 Rangy      更新时间:2024-04-22

我使用Rangy在富文本编辑器中执行多项操作(designmode="on")。其中一个功能是粘贴格式化的内容,这些内容可以表示用户之前创建的某些预定义字符。所有文本内容都包含在段落元素中。用户可以从以下内容开始:

<p>The following is a special character: |</p>

其中管道(|)是插入符号的位置。然后,他们选择通过编辑器上的按钮粘贴其中一个"特殊"字符,最终显示为:

<p>The following is a special character: <span class="read-only" contenteditable="false">SPECIAL</span>|</p>

该操作在内部粘贴过程中使用Rangy在幕后维护插入符号(SelectionSaveRestoreModule)的位置,这可能是在编辑器中对文本进行后粘贴处理,否则可能会混淆光标的位置。

但是,在IE8中,插入符号不能放在<span>之后,因为似乎存在使其成为无效位置的错误。因此,光标出现在<span>元素之前,甚至不可能使用键盘光标控件将光标移动到跨度之后。事实上,它甚至可以防止光标移动到下面的任何段落。

最近几天,我尝试了几种技术,包括在<span>后面放置额外的字符,并取得了一些成功。然而,当这些额外的字符出现时,显然会给用户带来困惑,而且并不理想。使用零宽度空间在视觉上更好,但在粘贴操作后试图整理它们会导致问题。

我需要一种"整洁"的方法来支持用户对特殊字符的要求,我可以自由地接受我可能以错误的方式处理这一问题。

我有一个解决方案,到目前为止,它似乎在我的测试中起作用,但当我看到它时,它仍然让我觉得一定有更好的方法(更不用说恐惧感了)。

这段代码试图在段落末尾的任何只读跨度后面放置一个零宽度的空格。它通过检查这些元素之后的节点来确定其中是否真的有文本来实现这一点。同时,它删除了以前检查中文本中可能仍然存在的任何零宽度空格,这些空格现在不再需要。

var ZWS = ''ufeff';
jQuery(_doc.body).find('p').each(function () {
    var lastContentEditable = undefined;
    // Look through the root contents of each paragraph to remove no-longer require zws fixes
    jQuery(this).contents().each(function () {
         if (this.nodeType === 3) {
            if (this.nodeValue.indexOf(ZWS) != -1) {
                // Text node containing a ZWS - remove for now
                this.nodeValue = this.nodeValue.replace(new RegExp(ZWS, 'g'), '');
            }
            // Does this node now contain text?
            if (this.nodeValue.length > 0 && lastContentEditable) {
                // Found text after a read-only node, ergo we do not need to modify that read-only node at the end
                lastContentEditable = undefined;
            }
        } else if (this.nodeType === 1 && this.getAttribute('contenteditable') === "false") {
            // Indicate that this is currently the last read-only node
            lastContentEditable = this;
        }
    });
    if (lastContentEditable) {
        // It appears that there is a read-only element at the end of the paragraph.
        // Add the IE8 fix zws after it.
        var node = document.createTextNode(ZWS);
        jQuery(lastContentEditable).after(node);
    }
});