Reputation: 115
I need a function that finds text (child text nodes) inside some (for this example the div) elements and wraps the text in a paragraph.
Text1
<div>
<div>
Text2
<div>Text3</div>
</div>
<div>Text4</div>
<p>Text5</p>
</div>
<div>Text6</div>
<div>
Text7
<p>Text8</p>
Text9
</div>
tried did it like this:
const fn = (doc) => {
const coll = [...doc.childNodes];
coll.forEach(el => {
if (el.tagName === 'DIV' && el.childElementCount === 0) {
el.innerHTML = `<p>${el.innerHTML}</p>`;
}
if (el.childElementCount > 0) {
el.childNodes.forEach(item => {
if (item.nodeType === 3 && item.textContent.trim()) {
const content = item.textContent.trim();
item.innerHTML = `<p>${content}</p>`;
console.log('2: ', item.innerHTML);
}
});
fn(el);
}
});
}
but it works wrong - in if condition (el.childElementCount > 0) in console log, I got all needed nodes in p tags. but not in result. item.innerHTML = `<p>${content}</p>`;
not apply it to document :(.
Can anyone help to fix it?
result i need:
Text1
<div>
<div>
<p>Text2</p>
<div><p>Text3</p></div>
</div>
<div><p>Text4</p></div>
<p>Text5</p>
</div>
<div><p>Text6</p></div>
<div>
<p>Text7</p>
<p>Text8</p>
<p>Text9</p>
</div>
Upvotes: 2
Views: 1094
Reputation: 20039
You can use replaceWith()
to replace the text node with the paragraph element
function filterTextNode(node) {
var textNodes = [];
for (node = node.firstChild; node; node = node.nextSibling) {
if (node.nodeType == 3 && node.textContent.trim()) textNodes.push(node);
else textNodes = textNodes.concat(filterTextNode(node));
}
return textNodes;
}
function wrapTextNode(text) {
var p = document.createElement('p');
p.innerHTML = text.textContent;
text.replaceWith(p);
}
const fn = (doc) => {
var textNodes = filterTextNode(doc);
textNodes.forEach(text => {
if (text.parentNode.tagName != 'P') {
wrapTextNode(text);
}
});
}
fn(document.body)
p {
color: red;
}
Text1
<div>
<div>
Text2
<div>Text3</div>
</div>
<div>Text4</div>
<p>Text5</p>
</div>
<div>Text6</div>
<div>
Text7
<p>Text8</p>
Text9
</div>
References
Upvotes: 5
Reputation: 11
var elements = document.getElementsByTagName('div');
for(var i=0;i<elements.length;i++){
if(elements[i]===0){
console.log(elements[i].textContent);
}
else{
var y=elements[i].innerHTML
console.log(y)
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>testing result</title>
</head>
<body>
<div>Text1</div>
<div>
<div>Text2</div>
<p>Text3</p>
</div>
<div>Text4</div>
</body>
</body>
</html>
i tryed this but i cant get last two div(4 and 2) like this output in the console <div>text4</div>
and <div>text2</div>
i hope this my help and i dont know how to print last two div innerHTML
Upvotes: 1
Reputation: 628
By considering the childElementCount
of the div
we can get your desired result. Rewrite your function like below.
const fn = (document) => {
let elements = document.getElementsByTagName('div');
elements = Array.prototype.slice.call(elements);
elements.forEach(el => {
if (el.innerHTML && el.childElementCount === 0) {
el.innerHTML = `<p>${el.innerHTML}</p>`;
}
});
}
Upvotes: 2