There is a newer post with a better method to perform a full-text search in JavaScript.
Some time ago, I needed to create a full-text search in JavaScript in a project that I was working on. The requirement was to search the text directly in the DOM modifying it and highlighting the relevant results.
The majority of the scripts on the internet, explain how to search a text inside a string, but many of them focused on verifying if the text is present or not, using for it the indexOf or the search methods of the String object.
Using the indexOf method
var myString = "This is a test";
var word = "test";
var index = myString.indexOf(word);
if(index >= 0) {
console.log("the word is contained within the string and its index position is " + index);
} else {
console.log("the word doesn‘t exist in the string");
}
Using the search method
var myString = "This is a test";
var expression = /test/;
var index = myString.search(expression);
if(index >= 0) {
console.log("the word is contained within the string and its index position is " + index);
} else {
console.log("the word doesn‘t exist in the string");
}
But what we needed, was to search directly in the DOM and highlight all the occurrences, so I kept searching. Another script that I found was limited to do the next using jQuery:
HTML of the jQuery method
<div id="paragraph">
<p>
This is a test using jQuery
</p>
</div>
jQuery method
var word = "test";
$("#paragraph p").each(function () {
$(this).html( "<span>" + $(this).html().split(" ").join("</span> <span>") + "</span>" );
});
$("#paragraph span:contains('" + word + "')").css("color", "#F00");
Basically, this method takes all the words contained inside <p> tags and wraps them by a <span> tag. After this, to search for a word, it searches for a span tag that contains the word and adds a class to it to highlight it.
Despite the simplicity of this method, it had a pitfall and it was that the content in which we wanted to search could contain other tags as <img> and this would add spans around all the images parameters. On top of that, this script supposes that we want to search a single word, if one tries to search a sentence it will not work, because there is no span with more than one word inside.
So, I decided to write a custom script to solve this, using something discouraged but very useful in specific cases like this one: regular expressions. This function was the result of that:
Full-text search in JavaScrit final function
function searchInText (word, html) {
//---Remove spans
html = html.replace(/<span class="finded">(.*?)<\/span>/g, "$1");
//---Build the regular expression to search for the word
var reg = new RegExp(word.replace(/[\[\]\(\)\{\}\.\-\?\*\+]/, "\\$&"), "gi");
var htmlreg = /<\/?(?:a|b|br|em|font|img|p|span|strong)[^>]*?\/?>/g;
//---Add the spans to the array
var htmlarray;
var len = 0;
var sum = 0;
var pad = 28 + word.length;
while ((array = reg.exec(html)) != null) {
htmlarray = htmlreg.exec(html);
//---Verify if the search match with an html tag
if (htmlarray != null && htmlarray.index < array.index && htmlarray.index + htmlarray[0].length > array.index + word.length) {
reg.lastIndex = htmlarray.index + htmlarray[0].length;
continue;
}
len = array.index + word.length;
html = html.slice(0, array.index) + "<span class='finded'>" + html.slice(array.index, len) + "</span>" + html.slice(len, html.length);
reg.lastIndex += pad;
if (htmlarray != null) htmlreg.lastIndex = reg.lastIndex;
sum++;
}
return { total: sum, html: html };
}
Function Parameters
word | String to search |
html | HTML code in which the string will be searched |
Return value
The function returns an object with two properties:
total | Number of occurrences found |
html | Html code containing the matches wrapped in a span with the class finded |
Full text search in JavaScript demo
Download the files
Download the demo files
It is possible to insert code fragments between <pre></pre> tags and HTML or XML code between <xmp></xmp> tags.