Reputation: 13
I have written the following JS for my chrome project which allows you to bold random letters in a word or sentence.
The problem is that whenever there is a hyperlink
in a paragraph the code only bolds random letters up until that point and the rest of the text is unaffected.
let all = document.querySelectorAll("*");
all.forEach(a => a.childNodes.forEach(b => makeRandomBold(b)));
function makeRandomBold(node) {
if (node.nodeType !== 3) {
return;
}
let text = node.textContent;
node.textContent = "";
text.split('').forEach(s => {
if (s !== " " && Math.random() > .49) {
let strong = document.createElement("strong");
strong.textContent = s;
node.parentNode.insertBefore(strong, node);
} else {
node.parentNode.insertBefore(document.createTextNode(s), node);
}
I have tried to change from the universal selector tag, to individually selecting HTML elements such as p
a
span
. Which did not work.
Might finding random intervals and putting them in a single strong tag work? What might be causing this?
Upvotes: 1
Views: 68
Reputation: 1838
Here you have one way to do it. I added comments to the code:
// The selector * will pull everything: html, head, style, script, body, etc.
// Let's indicate that we only want elements inside the body that aren't scripts,
// styles, img, or any element that wont hold a string.
let allElements = document.querySelectorAll("body > *:not(style):not(script):not(img)");
// Now, lets iterate:
allElements.forEach(elem => {
traverseDOMToBold(elem);
});
// We want to visit all the futher children first,
// then we can change the content
function traverseDOMToBold(elem){
if (elem.hasChildNodes()){
[...elem.children].forEach(child => {
traverseDOMToBold(child);
});
}
boldInnerHTML(elem);
}
// I like to try to create function that have a Single Responsability if possible.
function boldInnerHTML(elem){
if (elem.innerHTML.length > 0){
let currentString = elem.innerHTML;
let newString = `<strong>${currentString}</strong>`;
elem.innerHTML = currentString.replace(currentString, newString)
}
}
<h1>Title</h1>
<p>Paragraph</p>
<div>Div</div>
<span id="parent">
Parent Span
<span id="child">
Child Span
</span>
</span>
<div>
1.
<div>
2.
<div>
3.
</div>
</div>
</div>
<ul>
<li>A.</li>
<li>B.</li>
<li>
<ul>C
<li>C1.</li>
<li>C2.</li>
<li>C3.</li>
</ul>
</li>
</ul>
Upvotes: 1