I need to merge direct html siblings into just one in page code including text nodes.
<div>some text
<b>some text</b> som
e text <b>text</b><b> more text</b> some te
xt</div>
This is actualy output after editing the code using rangy and jQuery and i need to clear it after the editing so it will look like this:
<div>some text <b>some text</b> some text <b>text more text</b> some text</div>
I would like to use jQuery to do this. I am aware of functions unwrap() and wrapAll() but i cant combine them effectively. Thanks for any clue or help!
You need to iterate over child nodes one by one; comparing nodes with previous one and combine if necessary. It can be as complicated as you want; but here is a start:
$("div").each(function (i) {
$(this).find("*").each(function () {
var that = this.previousSibling;
if (that && that.nodeType === Node.ELEMENT_NODE && that.tagName === this.tagName) {
var node = document.createElement(this.tagName);
while (that.firstChild) {
node.appendChild(that.firstChild);
}
while (this.firstChild) {
node.appendChild(this.firstChild);
}
this.parentNode.insertBefore(node, this.nextSibling);
that.parentNode.removeChild(that);
this.parentNode.removeChild(this);
}
});
});
Demo here
If i understood your question correctly, you wanted to combine elements that are next to each other of the same type.
var $div = $("#mydiv");
console.log($div.html());
$div.contents().each(function(){
if (this.nodeType != 1) return;
while (this.nextSibling && this.nextSibling.tagName == this.tagName) {
this.innerHTML = (this.innerHTML + this.nextSibling.innerHTML);
this.parentNode.removeChild(this.nextSibling);
}
});
console.log($div.html());
http://jsfiddle.net/X8LYu/2/
If you also wanted to remove the new-line characters, it would change to this:
var $div = $("div");
console.log($div.html());
$div.contents().each(function(){
if (this.nodeType == 3) {
this.nodeValue = this.nodeValue.replace(/\n/g,"");
return;
}
if (this.nodeType != 1) return;
while (this.nextSibling && this.nextSibling.tagName == this.tagName) {
this.innerHTML = (this.innerHTML + this.nextSibling.innerHTML).replace(/\n/g,"");
this.parentNode.removeChild(this.nextSibling);
}
});
console.log($div.html());
http://jsfiddle.net/X8LYu/3/
I don't write code in this way very often, so there might be better ways of handling this.
$('div').html(function(_, oldHTML) {
return oldHTML.replace(/\n/g, '');
}).children().filter(function () {
return this.nextSibling
&& this.nextSibling.nodeName === this.nodeName;
}).text(function (_, oldText) {
return oldText + this.parentNode.removeChild(this.nextSibling).textContent;
});
http://jsfiddle.net/tVZJV/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With