I decided to implement the approach that I outlined in my comment on my other answer: traversing nodes in a selected range and deleting certain nodes (in this case, based on the tag name).
Here's the full demo. It will not work in IE <= 8 (which does not support DOM Range and Selection support), but it will be used in all other major browsers. One of the problems is that the choice is not always saved, but this is not too difficult to achieve.
http://jsfiddle.net/gF3sa/1/
This example includes modified range bypass code from elsewhere on 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");
source share