我决定实施我在对其他答案的评论中概述的方法:遍历所选范围内的节点并删除特定节点(在这种情况下,基于标签名称)。
这是完整的演示。它不适用于 IE <= 8(缺少 DOM Range 和 Selection 支持),但适用于当前其他主要浏览器。一个问题是选择并不总是被保留,但这并不难实现。
http://jsfiddle.net/gF3sa/1/
此示例包括来自SO 其他地方的修改范围遍历代码。
function nextNode(node) {
if (node.hasChildNodes()) {
return node.firstChild;
} else {
while (node && !node.nextSibling) {
node = node.parentNode;
}
if (!node) {
return null;
}
return node.nextSibling;
}
}
function getRangeSelectedNodes(range, includePartiallySelectedContainers) {
var node = range.startContainer;
var endNode = range.endContainer;
var rangeNodes = [];
// Special case for a range that is contained within a single node
if (node == endNode) {
rangeNodes = [node];
} else {
// Iterate nodes until we hit the end container
while (node && node != endNode) {
rangeNodes.push( node = nextNode(node) );
}
// Add partially selected nodes at the start of the range
node = range.startContainer;
while (node && node != range.commonAncestorContainer) {
rangeNodes.unshift(node);
node = node.parentNode;
}
}
// Add ancestors of the range container, if required
if (includePartiallySelectedContainers) {
node = range.commonAncestorContainer;
while (node) {
rangeNodes.push(node);
node = node.parentNode;
}
}
return rangeNodes;
}
function getSelectedNodes() {
var nodes = [];
if (window.getSelection) {
var sel = window.getSelection();
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
nodes.push.apply(nodes, getRangeSelectedNodes(sel.getRangeAt(i), true));
}
}
return nodes;
}
function replaceWithOwnChildren(el) {
var parent = el.parentNode;
while (el.hasChildNodes()) {
parent.insertBefore(el.firstChild, el);
}
parent.removeChild(el);
}
function removeSelectedElements(tagNames) {
var tagNamesArray = tagNames.toLowerCase().split(",");
getSelectedNodes().forEach(function(node) {
if (node.nodeType == 1 &&
tagNamesArray.indexOf(node.tagName.toLowerCase()) > -1) {
// Remove the node and replace it with its children
replaceWithOwnChildren(node);
}
});
}
removeSelectedElements("h1,h2,h3,h4,h5,h6");