在保留所有子项和选择的同时删除节点

时间:2014-12-24 10:24:34

标签: javascript dom selection

所以,我试图在改变DOM的同时保持选择。我上半部分工作得很完美,当我添加它时会保持选择状态,但是当它移除它时效果不佳。根据选择的内容取决于它是否有效。

您可以在此处查看示例:http://jsfiddle.net/zanpm28d/

如果您选择“选择我”,您可以整天点击该按钮,它会进出,并保留选择。但是,如果您只选择“选择”或“不要选择我”,它将在向后退回时失去选择。

以下是相关的代码部分。

else{        
    // Get the first selection
    var range = sel.getRangeAt(0);
    // Get what was selected as a fragment
    var frag = range.cloneContents();

    // Create a new block element
    var block = document.createElement(blockType.toLowerCase());

    // Take all the children of the fragment, and place them into the block
    // This will also remove them from the fragment
    while(frag.firstChild != undefined && frag.firstChild != null){
        block.appendChild(frag.firstChild);
    }

    // Place the block back into the fragment
    frag.appendChild(block);

    // Now kill what was originally selected
    range.extractContents();

    // And put back in what we just built
    range.insertNode(frag);

    // Then reselect what we had.
    sel.removeAllRanges();
    if(block.childNodes.length > 0){
        var newRange = document.createRange();
        newRange.setStart(block.childNodes[0], 0);
        newRange.setEnd(block.childNodes[block.childNodes.length - 1], block.childNodes[block.childNodes.length - 1].length);
        sel.addRange(newRange);
    }
    return true;
}

如果你想知道为什么我这样做,IE。所有其他浏览器都保持正确的选择,但IE会出于任何原因不正确,并且如果我不“手动”更改选择,则会将块放入块中。

1 个答案:

答案 0 :(得分:1)

不是使用innerHTMLouterHTML,而是移动子节点,然后您可以定位新的选择范围以包含这些节点。这是您示例的更新版本:

http://jsfiddle.net/zanpm28d/1/

代码的关键部分:

// Insert all of elemStart's child nodes before elemStart        
var firstChild = elemStart.firstChild;
var lastChild = elemStart.lastChild;
var child;
while ( (child = elemStart.firstChild) ) {
    elemStart.parentNode.insertBefore(child, elemStart);
}

// Remove elemStart so that its children have now replaced it
elemStart.parentNode.removeChild(elemStart);

// Reselect the contents of elemStart
var newRange = document.createRange();
newRange.setStartBefore(firstChild);
newRange.setEndAfter(lastChild);
sel.removeAllRanges()
sel.addRange(newRange);