【问题标题】:contenteditable div - divide a span tag - avoid nestingcontenteditable div - 划分一个 span 标签 - 避免嵌套
【发布时间】:2018-02-24 13:31:26
【问题描述】:

我正在开发一个使用 contenteditable 的打字工具。当用户输入一些文本时,我将其插入到 span 标签中并将其添加到主 div;结果是这样的:

<span style="color: black;">hello</span>

如果用户将插入符号放在单词“hello”中并开始输入不同的颜色,结果将是:

<span style="color: black;">he<span style="color: red;">new text</span>llo</span>

我真正想要实现的是:

<span style="color: black;">he</span>
<span style="color: red;">new text</span>
<span style="color: black;">llo</span>

我想避免嵌套 span 元素。 目前我使用这个过程来添加跨度标签:

var sel = window.getSelection();
var range = sel.getRangeAt(0);

var spanTag = "<span id='newSpan' style='color: " + currentColor + "'>00000</span>"; // &#8203;
var documentFragment = range.createContextualFragment(spanTag);

range.insertNode(documentFragment);

var dummySpan = document.getElementById("newSpan");

range.setStart(dummySpan, 1);
range.setEnd(dummySpan, 1);

sel.removeAllRanges();
sel.addRange(range);

$("#newSpan").removeAttr("id");
dummySpan.innerHTML = "";

我只是想知道我是否缺少一些可以帮助轻松实现此目标的 jquery 或 javascript 函数。

【问题讨论】:

  • 说真的。你的问题我不清楚。你到底想达到什么目标?
  • 当用户在一个 span 标签中输入内容时,我会添加另一个 span 标签,该标签嵌套在第一个标签中。我不希望这种情况发生,我只是希望所有的标签都分开而不是嵌套。
  • 我编辑了帖子,希望现在更清楚了。

标签: javascript jquery html nested contenteditable


【解决方案1】:

最后我用这个功能做到了。基本上我在插入符号位置将当前标签文本分成两半,创建两个单独的标签,每个标签都有一半的文本,在中间创建一个当前颜色的新标签并将插入符号放入其中。

function typeInKanji() {

    var sel = window.getSelection();
    var range = sel.getRangeAt(0);

    var currentNode = sel.anchorNode;   
    var elementNode = getSelectionElement();

    var caretPosition = getCaretCharacterOffsetWithin(elementNode);

    if (elementNode.tagName == "SPAN") { 

        if (elementNode.style.color == currentColor) {

            console.log("span of same color, do nothing and keep typing");

        } else {

            console.log("span of a different color, split it");

            var tagText = elementNode.innerText;

            console.log("text: " + tagText + " position: " + caretPosition);

            var firstHalf = tagText.substr(0, caretPosition);
            var secondHalf = tagText.replace(firstHalf, "");

            // remove the old element with all the text
            $(elementNode).remove();

            var firstTag = "<span style='color: " + elementNode.style.color + "'>" + firstHalf + "</span>"
            var secondTag = "<span style='color: " + elementNode.style.color + "'>" + secondHalf + "</span>"
            var middleTag = "<span id='middleTag' style='color: " + currentColor + "'>00</span>"

            var firstFrag = range.createContextualFragment(firstTag);
            var secondFrag = range.createContextualFragment(secondTag);
            var middleFrag = range.createContextualFragment(middleTag);

            range.insertNode(secondFrag);
            range.insertNode(middleFrag);
            range.insertNode(firstFrag);

            var getMiddleTag = document.getElementById("middleTag");

            console.log(getMiddleTag);

            range.setStart(getMiddleTag, 0);
            range.setEnd(getMiddleTag, 0);

            sel.removeAllRanges();
            sel.addRange(range);

            $("#middleTag").removeAttr("id");
            getMiddleTag.innerHTML = "";

        }


    } else {

        // if there is not SPAN tag create one
        insertTag("<span id='newSpan' style='color: " + currentColor + "'>00</span>");

        var dummySpan = document.getElementById("newSpan");

        range.setStart(dummySpan, 1);
        range.setEnd(dummySpan, 1);

        sel.removeAllRanges();
        sel.addRange(range);

        $("#newSpan").removeAttr("id");
        dummySpan.innerHTML = "";

    }

    typeKanjiNow = false;

}

这里是我使用的另外两个函数:

function getCaretCharacterOffsetWithin(element) {

    var caretOffset = 0;
    var doc = element.ownerDocument || element.document;
    var win = doc.defaultView || doc.parentWindow;
    var sel;

    if (typeof win.getSelection != "undefined") {

        sel = win.getSelection();

        if (sel.rangeCount > 0) {

            var range = win.getSelection().getRangeAt(0);
            var preCaretRange = range.cloneRange();
            preCaretRange.selectNodeContents(element);
            preCaretRange.setEnd(range.endContainer, range.endOffset);
            caretOffset = preCaretRange.toString().length;

        }

    } else if ( (sel = doc.selection) && sel.type != "Control") {

        var textRange = sel.createRange();
        var preCaretTextRange = doc.body.createTextRange();
        preCaretTextRange.moveToElementText(element);
        preCaretTextRange.setEndPoint("EndToEnd", textRange);
        caretOffset = preCaretTextRange.text.length;

    }

    return caretOffset;

}

function insertTag(tag) {

    var sel = window.getSelection();
    var range = sel.getRangeAt(0);

    var currentNode = sel.anchorNode;   

    var documentFragment = range.createContextualFragment(tag);
    range.insertNode(documentFragment);

}

【讨论】:

    猜你喜欢
    • 2011-04-03
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多