How to wrap part of a text in a node with JavaScript
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Wrapping only part of a text node is a common DOM task when you need to highlight a substring, attach a tooltip, or turn one word into a link without rebuilding the entire element. The tricky part is that text inside the DOM is not automatically split into convenient chunks, so you need to create that structure yourself.
Why Partial Wrapping Is Different From Replacing innerHTML
The fastest-looking approach is often element.innerHTML = ..., but that is usually the wrong tool. Replacing HTML as a string destroys existing child nodes, removes event listeners attached below that element, and forces you to manually escape text.
If you only want to wrap a substring inside existing text, work with real text nodes instead. That preserves the rest of the DOM and makes the change more predictable.
For example, imagine this HTML:
You want to wrap the word only in a span so it can be styled.
A Simple and Reliable Approach With splitText
If you already know the target text node and the character offsets, splitText is the cleanest solution. It breaks one text node into smaller text nodes, which lets you insert a wrapper element around the middle part.
Why this works:
- '
splitText(start)separates the leading text from the target and everything after it.' - A second
splitText(target.length)isolates the exact substring. - You replace just that isolated node with a real element.
This pattern is good when the content is mostly plain text and the element contains one direct text node.
Using Range for More Complex DOM Content
If the target text is mixed with other inline nodes, Range is often safer. A range can select a slice of a text node and wrap it without rebuilding surrounding markup.
Range.surroundContents is concise, but it has one important limitation: the selected range must be structurally valid. If the selection crosses incompatible node boundaries, the browser throws an error. When you are not sure the selection is contained neatly in one text node, split the text first or process smaller nodes individually.
Finding the Correct Text Node
Real pages often contain multiple nested text nodes. In that case, firstChild is not enough. You may need to scan text nodes with a TreeWalker.
This is a better foundation when the element contains nested formatting or dynamic content.
When You Need All Matches, Not Just One
A common next step is wrapping every occurrence of a word. That is still easier with DOM traversal than with string-based HTML replacement. Process text nodes one by one, and always restart carefully after each split, because splitting changes node boundaries.
For large documents, avoid rescanning the entire subtree after every replacement. Instead, collect candidate text nodes first, then transform them in order.
Common Pitfalls
- Replacing
innerHTMLjust to wrap one substring, which removes existing listeners and can introduce escaping bugs. - Assuming
element.firstChildis always the text node you want. - Using
Range.surroundContentsacross mixed nodes and getting runtime exceptions. - Forgetting that
splitTextmutates the original node structure. - Searching raw text without deciding whether you want the first match, all matches, or only whole-word matches.
Summary
- Use DOM node operations instead of rewriting HTML strings.
- '
splitTextis the simplest option when you know the exact text node and offsets.' - '
Rangeis concise, but only works when the selection is structurally valid.' - Use
TreeWalkerwhen the text may be nested inside several child nodes. - Decide early whether your wrapper logic targets one match or every match in the subtree.
Related reading
- How to write a Promise wrapper around Web Workers API?
- How to yum install Node.js on Amazon Linux
- How would I get webpack or an other JS bundler to bundle files remotely hosted?
- HTML file input control with capture and accept attributes works wrong?
- HTML Table rendering algorithms, recommended reading?
- HTML text input allow only numeric input
- HTML.ActionLink method
- Html.fromHtml deprecated in Android N
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.