insertHTML unwraps div while inserting when selection is inside a node

心不动则不痛 提交于 2021-01-27 19:00:30

问题


In a contenteditable element, when execCommand is called with command insertHTML, if selection is inside a node command unwraps the div tag around the inserted html segment.

Sample HTML Code block is as follows:

<div id="editable" contenteditable="true">
    <div>Some text</div>
    <div>Yet another</div>
    <div>and other</div>
</div>
<input id="insert" type="button" value="Insert Segment">

and let javascript handling insertion be as follows

$('#insert').on('mousedown', function (e) { //that is to save selection on blur
    e.preventDefault(); 
}).on('click', function () { // this inserts the sample html segment
    document.execCommand('insertHTML', false, 
    '<div class="new-segment">Text inside Segment</div>');
});

Live example at http://jsfiddle.net/TE4Y6/ Follow the scenario below:

  • place caret to the end of all content, press enter to create a new line then press "Insert Segment"

result: New div with gray background contains "Text Inside Segment" inserted

  • place caret to the inside any of first three lines, press "Insert Segment"

result: it inserts only the content of segment not surrounding div

expected: New div with gray background contains "Text Inside Segment" inserted

  • place caret to the end of any of first three lines, press "Insert Segment"

result: it inserts only the content of segment not surrounding div

expected: New div with gray background contains "Text Inside Segment" inserted

  • place caret to the end of any of first three lines, press enter to create a new line then press "Insert Segment"

result: New div with gray background contains "Text Inside Segment" inserted

I have tried to automatically insert <br> before inserted segment It fixes 3rd step though inserts redundant space.

Do you have any suggestions?


回答1:


You can try Range.insertNode. Proof of concept: http://jsfiddle.net/GYRLf/

var sel = window.getSelection();
if (sel.rangeCount) {
    var range = sel.getRangeAt(0);
    range.insertNode(yourDivElement);
}

A big disadvantage of this approach is that it breaks undo.


UPD. I think I found a workaround: http://jsfiddle.net/2LCtd/

document.execCommand('insertHTML', false,
    '<div class="new-segment">' +
        '<h6 class="killme">' + html + '</h6>' +
     '</div>'
);
$('.killme').contents().unwrap();

When you add a header inside the div WebKit stops merging the div with surroundings. And because the text content doesn't change when you later remove the header, the browser can undo correctly.




回答2:


It seems to be an issue with Chromium. You can follow the issue at https://code.google.com/p/chromium/issues/detail?id=122062



来源:https://stackoverflow.com/questions/16033737/inserthtml-unwraps-div-while-inserting-when-selection-is-inside-a-node

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!