You can use indexOf
to look for all occurrences of a string in the textContent
of the element and use appendChild
to add anchor elements.
function addLink(el, text){
let t = el.textContent;
el.textContent = '';
let idx, prev = 0;
while((idx = t.indexOf(text, prev)) !== -1){
el.append(t.slice(prev, idx));
const a = document.createElement('a');
a.href = '/' + text;
a.textContent = text;
el.appendChild(a);
prev = idx + text.length;
}
el.append(t.slice(prev));
}
addLink(document.querySelector('p'), 'ipsum');
<p>Lorem ipsum dolor sit amet</p>
You can split apart the text content by a ipsum
regular expression, then iterate over each match: for each segment which is not ipsum
, insert a text node containing the text for that segment. For ipsum
, insert a <span>
and assign to its textContent
.
const p = document.querySelector('p');
const pattern = new RegExp(/(.*?)(ipsum)/, 'gi');
const matches = p.textContent.split(pattern).filter(Boolean);
p.textContent = '';
for (const match of matches) {
if (match === 'ipsum') {
const a = p.appendChild(document.createElement('a'));
a.textContent = match;
a.href = '/ipsum';
} else {
p.appendChild(document.createTextNode(match));
}
}
<p>Lorem ipsum dolor sit amet</p>
I need to highlight text in an HTML document with JavaScript that will be part of a webextension. The use of .innerHTML
would cause a rejection in the review process. See innerHTML
Security considerations.
I need to highlight text as a link:
<p>Lorem ipsum dolor sit amet</p>
⬇
addLinkWithoutInnerHTML('ipsum');
⬇
<p>Lorem <a href="/ipsum">ipsum</a> dolor sit amet</p>
How can I pull this off without using .innerHTML
?
nothing. I haven’t written this function jet. It’s just an example
both anwers are good and they solve the initial problem. Thank you. I was just wondering line breaks (