2014-12-24 39 views
0

所以,我试图在改变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会因为某种原因而不正确,并且如果我不更改“手动”选项,则会将块放入块中。

+0

'而(!frag.firstChild =未定义&& frag.firstChild = NULL)'可以'而(frag.firstChild)'。 [* firstChild *](http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-169727388)将返回一个Node(truthy)或* null *(falsey)。要将片段的所有孩子放入块中,不需要循环。使用'block.appendChild(frag)'。参见[* Interface DocumentFragment *](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-B63ED1A3)。 – RobG

+0

谢谢,更整洁。关于手头问题的任何想法? – David

回答

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); 
相关问题