Reputation: 1948
Ok, I have the following string
I have a string that contains the following:
<span>A</span>BC<span id="blabla">D<span>EF</span></span>GH
I want to be able to use pure JavaScript to strip out any span tag that does not have an id so that the output looks like:
ABC<span id="blabla">DEF</span>GH
I have the following code which works fine but does not handle the nested span in the middle (the one that holds EF). I just need to know how can I use recursion to accomplish my goal.
function removeSpans2(s) {
var a = document.createElement('div');
a.innerHTML = s;
var node, next = a.firstChild;
while (node = next) {
next = next.nextSibling
if (node.tagName && node.tagName.toLowerCase() == 'span' && !node.id) {
a.replaceChild(document.createTextNode(node.textContent || node.innerText), node);
}
}
return a.innerHTML;
}
Upvotes: 0
Views: 445
Reputation: 4164
why don't you simply just use String.replace() if it is an html string like you seemed to indicate.
str.replace(/<span>([A-Za-z0-9]*)<\/span>/g, '$1');
You can tweak the values between the brackets to accommodate for what content you would find between your spans
EDIT edited above code to remove just the tags and not the content inside
Upvotes: 1
Reputation: 9907
Perfect time to pull out some recursion:
function removeSpans2(s) {
var a = document.createElement('div');
a.innerHTML = s;
var node, next = a.firstChild;
while (node = next) {
next = next.nextSibling
if (node.tagName && node.tagName.toLowerCase() == 'span' && !node.id) {
a.replaceChild(document.createTextNode(removeSpans2(node.textContent || node.innerText)), node);
} else if (node.innerText != undefined){
var node2 = node.cloneNode(true);
node2.innerText = removeSpans2(node2.innerText);
a.replaceChild(node2, node);
}
}
return a.innerHTML;
}
Upvotes: 1
Reputation: 147413
No recursion needed, figured out a simpler algorithm. This one handles all sorts of nested elements, you can have A elements inside the spans, or spans in side As, or spans in spans in spans... whatever.
function removeSpans3(s) {
var a = document.createElement('div');
a.innerHTML = s;
var span, spans = a.getElementsByTagName('span');
var frag, arr = [];
// Stabilise spans collection in array
for (var i=0, iLen=spans.length; i<iLen; i++) {
arr[i] = spans[i];
}
// Process spans
for (i=0; i<iLen; i++) {
span = arr[i];
// If no id, put content into a fragment
if (!span.id) {
// Some older IEs may not like createDocumentFragment
frag = document.createDocumentFragment();
while (span.firstChild) {
frag.appendChild(span.firstChild);
}
// Replace span with its content in the fragment
span.parentNode.replaceChild(frag, span);
}
}
return a.innerHTML;
}
Upvotes: 1
Reputation: 76
I think this will work, just add a recursion
function removeSpans2(s , el) {
var a = el || document.createElement('div');
a.innerHTML = s;
var node, next = a.firstChild;
while (node = next) {
next = next.nextSibling;
if( node.children && node.children.length ) {
arguments.callee(node.innerHTML , node);
}else if (node.tagName && node.tagName.toLowerCase() == 'span' && !node.id) {
a.replaceChild(document.createTextNode(node.textContent || node.innerText), node);
}
}
return a.innerHTML;
}
Upvotes: 1