admin管理员组文章数量:1401672
With the exception of using Undo, I don't think there's a way to remove h1 and h2 tags in content editable. The expected behavior is clicking the H1 button again should toggle it off, but it does not. There's also a "remove formatting" button, but it only works on items that are bold, italic, etc. Is there a way to do this through javascript?
Edit: Result must remove the opening and closing H1 tag, and not replace it with anything else.
Please see the simplified test case here: /
<div id="editor" contenteditable="true">
<h1>This is a heading one</h1>
How can I remove the header styling if I want to?
</div>
With the exception of using Undo, I don't think there's a way to remove h1 and h2 tags in content editable. The expected behavior is clicking the H1 button again should toggle it off, but it does not. There's also a "remove formatting" button, but it only works on items that are bold, italic, etc. Is there a way to do this through javascript?
Edit: Result must remove the opening and closing H1 tag, and not replace it with anything else.
Please see the simplified test case here: http://jsfiddle/kthornbloom/GSnbb/1/
<div id="editor" contenteditable="true">
<h1>This is a heading one</h1>
How can I remove the header styling if I want to?
</div>
Share
Improve this question
edited Aug 27, 2013 at 19:12
kthornbloom
asked Aug 20, 2013 at 14:02
kthornbloomkthornbloom
3,7403 gold badges32 silver badges47 bronze badges
2
- jsfiddle link is broken – Stepan Suvorov Commented Nov 19, 2014 at 14:34
- Sorry, I cleared out some old fiddles recently. The one in the accepted answer is still active though. – kthornbloom Commented Nov 19, 2014 at 14:51
3 Answers
Reset to default 5 +50I decided to implement the approach I outlined in my ment to my other answer: traversing nodes within the selected range and removing particular nodes (in this case, based on tag name).
Here's the full demo. It won't work in IE <= 8 (which lacks DOM Range and Selection support) but will in everything other major current browser. One problem is that the selection isn't always preserved, but that isn't too hard to achieve.
http://jsfiddle/gF3sa/1/
This example includes modified range traversal 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.monAncestorContainer) {
rangeNodes.unshift(node);
node = node.parentNode;
}
}
// Add ancestors of the range container, if required
if (includePartiallySelectedContainers) {
node = range.monAncestorContainer;
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");
This may not exactly meet your needs, but you could do it by using the FormatBlock
mand and passing in "div" or "pre" as the final parameter:
document.execCommand('formatBlock', false, 'p');
Demo: http://jsfiddle/GSnbb/2/ [jsFiddle has been deleted]
EDIT: Yes, this doesn't answer the question as it is now. However, it pre-dates the edit to the question about not replacing the <h1>
element and was a reasonable answer to the original question.
It is feasible with javascript, logic is the following:
- get the selected text and its position (cf. Get the Highlighted/Selected text and javascript - Getting selected text position)
remove all the
<h1>
and</h1>
from the selected texts = s.replace(/<h1>/g, ''); s = s.replace(/<\/h1>/g,'');
Insert the corrected text in place of the original one
I have drafted a solution based on your JSFiddle, but it requires some tweaking.
works: removing <h1>
and </h1>
from selected text on Gecko and webKit based browsers
not developed: IE support - cf. links in the jsfiddle, should not be difficult
broken:
- replacement of inplete selections (containing only one of
<h1>
and</h1>
) - easy to fix - removal of
<h1>
when it is right at the beginning of the selected text - you will need to play around a bit more with selections and ranges to sort that out.
P.S. Have you considered using an existing text editor plugin instead of creating it by yourself ?
本文标签: javascriptHow to remove H1 formatting within ContentEditable (wysiwyg)Stack Overflow
版权声明:本文标题:javascript - How to remove H1 formatting within ContentEditable (wysiwyg) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744245667a2596999.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论