I put together some code for a simple search bar with a predefined list of search terms to highlight words on the page that matches the search. Everything works fine, but after clicking on a search result to highlight the words on the page, the javascript completely stops working until the page is refreshed. Here’s a snippet of the code.
function ShowSearchResults() {
FindSearchResults();
resultListContainer.style.display = 'block';
setTimeout(() => {
resultListContainer.style.transitionDuration = '300ms'
resultListContainer.style.opacity = '1';
}, 1);
}
function HideSearchResults() {
resultListContainer.style.transitionDuration = '500ms'
resultListContainer.style.opacity = '0';
setTimeout(() => {
resultListContainer.style.display = 'block';
}, 500);
}
function FindSearchResults(){
let result = [];
let input = searchInput.value;
if (input.length > 0){
result = searchTerms.filter((keyword) => {
return keyword.toLowerCase().includes(input.toLowerCase());
});
}
else{
result = searchTerms
}
DisplaySearchResults(result);
}
function DisplaySearchResults(result) {
const content = result.map((list) => {
return "<li>" + list + "</li>";
});
resultList.innerHTML = "<ul>" + content.join('') + "</ul>";
document.querySelectorAll('.result-list li').forEach((item) => {
item.addEventListener('click', function () {
const searchText = item.textContent;
highlightMatches(searchText);
scrollToFirstMatch(searchText);
});
});
}
function highlightMatches(searchText) {
clearHighlights();
const regex = new RegExp(searchText, 'gi');
const highlightedText = bodyText.replace(regex, (match) => {
return `<span class="highlight-span">${match}</span>`;
});
document.body.innerHTML = highlightedText;
searchInput.focus();
}
function scrollToFirstMatch(searchText) {
const firstMatch = document.querySelector('.highlight-span');
if (firstMatch) {
firstMatch.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
}
function clearHighlights() {
document.body.innerHTML = document.body.innerHTML.replace(/<span class="highlight-span">(.*?)</span>/g, '$1');
}
Let me know if any furthur code is required!
2
Answers
Avoid modifying "document.body.innerHTML" completely.
The reason for this function is to ensure that the text, that was highlighted, returns back to its normal look without disturbing the rest of the DOM.
You are replacing the content of the
document
in your code. This means the elements after the replace are not the same as before. This also means any event-handlers attached to them are no longer working.To fix this, you need to run the code again which is able to attach the event-handlers. You already have this code. Move it to an extra function and call it twice.
You can update your code like this to fix the issue: