Skip to content

Instantly share code, notes, and snippets.

@manstie
Last active May 30, 2024 02:07
Show Gist options
  • Save manstie/019562a90292246ac7d710c82497026b to your computer and use it in GitHub Desktop.
Save manstie/019562a90292246ac7d710c82497026b to your computer and use it in GitHub Desktop.
Manual search highlighting
search(elements: HTMLElement[], value: string) {
value = value.toLowerCase();
for (const el of elements) {
el
.querySelectorAll('mark')
.forEach((highlight) => {
highlight.outerHTML = highlight.textContent || '';
});
// make text nodes homogeneous again on firefox
el.normalize();
if (value) {
if (this.highlightTextNodes(el, value)) {
el.classList.remove('d-none');
} else {
el.classList.add('d-none');
}
} else {
el.classList.remove('d-none');
}
}
}
highlightTextNodes(node: Node, value: string) {
let highlighted = false;
if (
node.nodeType === 3 &&
node.textContent?.toLowerCase().includes(value)
) {
// TEXT NODE
const originalText = node.textContent;
const split = originalText.toLowerCase().split(value);
let textIndex = 0;
if (split[0]) {
const before = document.createTextNode(
originalText.slice(
textIndex,
(textIndex += split[0].length)
)
);
node.parentNode?.insertBefore(before, node);
}
for (let i = 1; i < split.length; i++) {
const highlightNode = document.createElement('mark');
highlightNode.textContent = originalText.slice(
textIndex,
(textIndex += value.length)
);
node.parentNode?.insertBefore(highlightNode, node);
if (split[i]) {
const text = document.createTextNode(
originalText.slice(
textIndex,
(textIndex += split[i].length)
)
);
node.parentNode?.insertBefore(text, node);
}
}
node.parentNode?.removeChild(node);
highlighted = true;
} else {
node.childNodes.forEach((child) => {
highlighted =
this.highlightTextNodes(child, value) || highlighted;
});
}
return highlighted;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment