I’m making an attempt to pick out and modify textual content on my webpage which aren’t distinctive after which modify them. As an illustration suppose I’ve a number of HTML components which might be siblings of each other and so they comprise the identical textual content. If I attempt to choose the textual content in considered one of them utilizing Regex after which modify it i.e. (wrap it in span tags, exchange it with totally different textual content, delete it, and so on.), Regex will solely present the primary match that it had discovered which can or will not be the textual content I chosen.
I did some analysis into utilizing the Treewalker API for this however the examples I noticed weren’t very useful. Please assist recommend the very best resolution that can handle conditions the place the identical chosen textual content exists in a number of HTML components.
Is that this much like what you had in thoughts?
It may do with a little bit of a cleanup/refactoring
const getDuplicates = operate()
// a map of present textual content content material
// e.g. 'Another content material': true
const exists =
const isNewLine = operate (node)
return /^[nr]+s*/.take a look at(node.textContent)
return doc.createNodeIterator(
doc.physique,
NodeFilter.SHOW_TEXT,
(node) =>
// ignore new line textual content nodes e.g. 'n '
if (isNewLine(node)) return NodeFilter.FILTER_SKIP
// if node with identical textual content content material already exists
// return duplicate
if (exists[node.textContent])
return NodeFilter.FILTER_ACCEPT
// first look then retailer in exists
exists[node.textContent] = true
return NodeFilter.FILTER_SKIP
,
false
);
// get the iterator
const duplicatesIterator = getDuplicates()
let currentNode
let duplicateNodes = []
// iterate and retailer in an array
whereas (currentNode = duplicatesIterator.nextNode())
duplicateNodes.push(currentNode)
// creates a span round a textual content ingredient
const createSpan = operate(textContent)
const span = doc.createElement('span')
span.className="duplicate"
span.textContent = textContent
return span
// loop by means of duplicates and wrap a span
duplicateNodes.forEach(
(node) => node.replaceWith(createSpan(node.textContent))
)
Whereas i’m positive rpg’s code works nice…
Why are you doing this with Javascript? Looks like we’re lacking a bit of the scenario/drawback assertion right here…
If it’s your webpage… go into the HTML in your HTML-editor of selection, discover the duplicates and… do no matter you have been going to do with them?
1 Like
That may be far too straightforward!
Glad I did this model too then
const walkTheDom = operate (node, callback)
callback(node)
node = node.firstChild
whereas (node)
walkTheDom(node, callback)
node = node.nextSibling
const isValidTextNode = operate (node)
const isNewLine = /^[nr]+s*/
return (node.nodeType === 3 && !isNewLine.take a look at(node.textContent))
const getDuplicates = operate (root = doc.physique)
const exists =
const duplicates = []
walkTheDom(root, (node) =>
if (!isValidTextNode(node)) return
// if node with identical textual content content material already exists
// return duplicate
if (exists[node.textContent]) duplicates.push(node)
// first look then retailer in exists
exists[node.textContent] = true
)
return duplicates
// creates a span round a textual content ingredient
const createSpan = operate(textContent)
const span = doc.createElement('span')
span.className="duplicate"
span.textContent = textContent
return span
// loop by means of duplicates and wrap a span
getDuplicates(doc.physique).forEach(
(node) => node.replaceWith(createSpan(node.textContent))
)
Hello all, Thanks on your replies particularly you rpg_digital. The explanation for creating this performance is for presentation functions. Suppose I would like to have the ability to spotlight some information on my web page on the fly whereas giving a presentation to a gaggle of individuals in a video convention, if I can spotlight or improve the dimensions of any piece of information (particularly dynamically loaded information) that’s deemed essential to the group it might be very helpful as it may well draw the attentions of all assembly attendees to these highlighted information.
physique.innerHTML = physique.innerHTML.replaceAll(new RegExp(window.getSelection().toString(),"ig"),"<span class="emphasize">$0</span>")
?
Except your chosen textual content is more likely to match a classname or HTML part…