4

我需要获取节点的文本(或整个内部 html),在contenteditable设置为的元素中的当前插入符号(文本光标)位置截断true。我试过使用 range.setStart() 等,但我无法做出正面和反面......

编辑:为了澄清起见,在某些事件中,我希望脚本从当前具有焦点的节点的开头提取文本到插入符号的位置(如果可编辑字段具有焦点,则当前闪烁的垂直线位于该位置)并将其存储在变量中. 类似于用户按下 ctrl+shift+home 和 ctrl+c 时会发生的操作

示例:给定 html:

<span contenteditable=true>Hello, world<br> Good bye, World</span>

假设插入符号在“Good”和“bye”之间,我想检索

"Hello, world<br> Good"

4

4 回答 4

7

我建议采用以下方法:

  • 创建一个包含您想要的内容的范围
  • 调用范围的cloneContents()方法来获取一个DocumentFragment表示范围内容的
  • 创建一个<div>or<body>元素并将片段附加到它
  • 获取元素的innerHTML

示例:http: //jsfiddle.net/sUSYG/

代码:

function getHtmlPrecedingSelectionIn(container) {
    var html = "";
    if (window.getSelection && document.createRange) {
        var sel = window.getSelection();
        if (sel.rangeCount > 0) {
            var selRange = sel.getRangeAt(0);
            var range = document.createRange();
            range.selectNodeContents(container);
            range.setEnd(selRange.startContainer, selRange.startOffset);

            var frag = range.cloneContents();
            var el = document.createElement("body");
            el.appendChild(frag);
            html = el.innerHTML;
        }
    }
    return html;
}

注意事项:

  • 这在 IE <= 8 中不起作用,尽管它并不难做到(通过使用其不同的选择/范围 API 进行编码或使用诸如 Rangy 之类的库)
  • 生成的 HTML 不保证是可编辑范围的原始 HTML 的子字符串。
于 2013-05-23T14:28:26.830 回答
6

您可以使用RangyjQuery相当轻松地做到这一点。

这是一个jsFiddle演示这种方法。评论解释了正在发生的事情。

$("contenteditable-element").click(function () {
    // Get the current selection with Rangy
    var sel = rangy.getSelection()
    // Insert a temporary caret element at the caret position 
    // (which is inside the contenteditable element)
    if (sel.rangeCount) sel.getRangeAt(0).insertNode($("<caret />")[0]);
    // Read the html inside the contenteditable element
    var innerHTML = $("contenteditable-element").html();
    // Clean up, get rid of the caret element
    $("caret").remove();
    // Only keep the text before the first occurrence of the caret element
    innerHTML = innerHTML.substr(0, innerHTML.indexOf('<caret>'));
});
于 2013-05-22T14:11:37.043 回答
0

Have a look at this answer: https://stackoverflow.com/a/16575647/1532004 I think think he is doing something similar. Perhapes he's shooting over the moon, but he got a working solution :)

于 2013-05-22T10:11:26.363 回答
0

也许这会将您推向正确的方向: 获取范围相对于其父容器的开始和结束偏移量

我建立了一个小提琴,它显示了与您的示例一起使用的功能:http: //jsfiddle.net/Kn8qr/2/

function getCaret(element) {
var caretOffset = 0;
if (typeof window.getSelection != "undefined") {
    var range = window.getSelection().getRangeAt(0);
    var preCaretRange = range.cloneRange();
    preCaretRange.selectNodeContents(element);
    preCaretRange.setEnd(range.endContainer, range.endOffset);
    caretOffset = preCaretRange.toString().length;
} else if (typeof document.selection != "undefined" && document.selection.type != "Control") {
    var textRange = document.selection.createRange();
    var preCaretTextRange = document.body.createTextRange();
    preCaretTextRange.moveToElementText(element);
    preCaretTextRange.setEndPoint("EndToEnd", textRange);
    caretOffset = preCaretTextRange.text.length;
}
var elCont=element.innerHTML;

var truncCont=elCont.substr(0,caretOffset);

alert(truncCont);
}

这要归功于该函数的作者,我刚刚对其进行了编辑。

于 2013-05-22T09:43:23.790 回答