Thomas R Alexander

Manager, Developer, and professional problem solver

Search for and highlight text on a page with JQuery

Recently, I developed a webpage for an internal website and was asked to come up with an inline-search solution that would help people quickly discover whether a search term existed on a particular page.

My first thought…CONTROL + F…duhhh….but the more I thought about it, the more I realized that many people don’t even know that they can search for text on a webpage via their browser.

So I did some jQuerying.

There are three main parts to this…the web form that the user will use to search for text, the function to find the text under particular elements on a page, and lastly some functionality to highlight the matched terms on the page.

Edit: 05/16/2014:
Fixed a bug in subsequent searches

EDIT: 02/17/2014
There has been a lot of activity on this page and a lot of feedback from users. Thank you so much for reaching out to me and using my script! When I originally wrote this, I broke it down into individual functions so that it could be more easily understood, but I now think that it caused more confusion than anything. Therefore, I re-wrote the script and created a jsFiddle for you to use and play around with. Let me know if you have any other questions!

The HTML Form
By far the easiest part…. here is the HTML code for the form:


The jQuery  (Updated: 02/17/2014)

Next, we have to write the function that will actually go out and highlight the terms.

Step 1: Determine what elements to search within. Do you want to search the entire page? Is there a particular container that your text is in, for efficiencies sake?

The CSS

Next we need to  add some CSS to define what the highlighted class is:

Fiddle

I created a js fiddle that should help you understand the whole picture, debug, etc…
http://jsfiddle.net/z7fjW/485/

57 thoughts on “Search for and highlight text on a page with JQuery

  • Anonymous
    January 18, 2013 at 7:32 pm

    […] Search for and highlight text on a page with JQuery | Thomas R. Alexander […]

  • Andy Warren
    January 22, 2013 at 8:13 am

    Hi there, is there an easy way to search case insensitive, I’ve had a little look and can see for jquery 1.4.4 which I’m using it suggests I use the following:
    jQuery.expr[‘:’].Contains = function(a,i,m){
    return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
    };
    But I can’t work out how to put that into the contains statement in your code.

    Nice piece of code by the way it’s very useful

    Any help appreciated
    Andy.

    • teeohhem
      January 22, 2013 at 8:19 am

      Thanks for reaching out, Andy.

      It’s actually simpler than that. 🙂

      In the highlightTerms function, change the first line to:
      var searchTerm = $('#search-term').val().toLowerCase();

      and then the next line to:
      $("#yourSelector").filter(function() {
      return $(this).text().toLowerCase().indexOf(searchTerm) > -1;
      }).addClass('highlighted');

  • rafael
    January 22, 2013 at 2:29 pm

    Hi,

    Thanks for the great tutorial. Unfortunately the script only works in FireFox. Is there a way to make it compatible with other browsers?

    • rafael
      January 22, 2013 at 2:33 pm

      Correction: The jump to script doesn’t work in Chrome possibly IE

      • teeohhem
        February 17, 2013 at 10:15 pm

        In my testing, the script works in Chrome and IE. Perhaps there is another error in your setup? Let me know and I can help you debug! Thanks 🙂

  • Dian Nguyen
    February 16, 2013 at 12:08 pm

    how can highlight in more than one element in same time?

    • teeohhem
      February 17, 2013 at 10:13 pm

      It’s all about the selector that finds the text in the body. For instance: $(‘container:contains(searchTerm)’).addClass(‘highlighted’);

      If there are more than one elements returned by that selector, it will add the class “highlighted” to those elements.

  • Brian
    February 21, 2013 at 4:51 pm

    This is working nicely except for the scrollto function that will be sooo helpful once I get it sorted out. Are you still responding on this page?

    • teeohhem
      February 22, 2013 at 8:41 am

      Absolutely. I’d love to help out. The scrolling functionality will only work if a term has been found on the page. It uses its offset from the top of the page to calculate where to scroll to. If this functionality is not working, it is possible that you may need to convert that number to an integer. Try this:
      if (firstFoundTerm.length > 0) {
      $(‘html’).scrollTop(parseInt(firstFoundTerm.offset().top));
      }

      Which browser are you using? Perhaps there is an issue I do not know about. Thanks!

      • Brian
        February 22, 2013 at 10:21 am

        Thanks for following up.

        The code works brilliantly in FireFox, Idiot Explorer and Opera. Though it will highlight, it will not scroll to in Chrome and Safari. I tried your new snippet, but I noticed your $(‘html’) became $(‘html’). Anyway, I tried it both ways but no joy yet in Chrome/Safari.

        Since all I need for this page is a simple confirmation that the search term exists, a workaround for C&S problem might be to display a ‘Yes’ next to the search button inside a span tag with an id if found. But my jquery skills are childish so far and I don’t know how to manipulate your code to get it. This weird thing is all I’ve got:
        $(“body:contains(‘”+searchTerm+”‘)”).html($(“#YesM”).text(“Yes”)); and it isn’t showing the “Yes” anywhere on the page. Any ideas how to make that work? I’ll happily continue testing whatever ideas you come up with for Chorme and Safari if you’ll email them to me.

        • teeohhem
          February 22, 2013 at 1:50 pm

          Brian,
          No problem! Glad I could help. I’ve had a TON of activity on this page in the past year, great feedback, and insightful questions. This has prompted me to take a stab at re-writing it so that it’s a bit simpler to understand. Before, I had purposely written the code with mulitple functions to demonstrate the different parts of the code. Reflecting back, I now realize that the over simplification caused more confusion than good. Take a look at the new code in the blog post and play around with the jsFiddle link that I provided. This should help you in your quest to solve your issue. I tested this in Chrome, Safari, FireFox, IE 6-10, and Opera. Thanks!

          • Brian
            February 22, 2013 at 8:29 pm

            Once again, very nice code. Thanks for the update too.

            Now, as a professional, you know full well we journeymen developers and designers will find ways to use your stuff that hadn’t occurred to you. Can you accommodate this request? When I put your working page into an iframe and use it in another page, the scroll STILL works in 3 of the five, but in Chrome and Safari it won’t budge. It’s a lot to ask, so I’ll say ‘pretty please’ but, do you have any magic up your sleeve to make it work in an iframe in Chrome and Safari? (I promise to go away after this one) 🙂

          • teeohhem
            February 25, 2013 at 1:06 pm

            Thank you. First off, I’m going to give you the speil about using iframes. Avoid them at all costs 🙂 Secondly, the scroll is tied to the (window) object which can mean different things to various browsers when using iframes. You can change the (window) selector to target the iframe itself (if you’re trying to scroll within the iframe). Otherwise, if the text is outside of the iframe, the javascript also needs to live outside of the iframe so that it knows to use the main window and not the window created by the iframe. Best of luck!

  • My Homepage
    February 24, 2013 at 5:56 am

    … [Trackback]…

    […] Read More: teeohhem.com/2011/02/20/search-for-and-highlight-text-on-a-page-with-jquery/ […]…

  • Brian
    February 25, 2013 at 3:32 pm

    10-4. Over and out. Thanks brah.

  • mojtaba
    April 20, 2013 at 5:55 pm

    hi
    very good jq code
    how i can highlight two or more similar text on page?

    • teeohhem
      June 4, 2013 at 8:02 am

      You would need to build a Regular Expression that is a bit more lenient. For instance, if a user searches for catch, but you want it to match cat, your regex should be /cat[ch]/. If you wanted to match any combination of letters of the search term, your regular expression can be, /[search term]/ . This will return a search with all combinations of that expression, so you’ll have a lot of false negatives. Your answer is somewhere in between there 🙂

    • teeohhem
      June 4, 2013 at 9:31 am

      I actually updated my code to show you how to do that. See this blog post or play around with it at the jsfiddle link in the post.

  • Chris
    June 4, 2013 at 6:24 am

    Really useful script , thankyou. I am struggling with the case insensitive part , i have tried the code n the above comment but cant seem to get it to work …jquery 1.91

    • teeohhem
      June 4, 2013 at 9:33 am

      Great question. This actually inspired me to update my implementation to use Regular Expressions. See this blog post or play around with it at the jsfiddle link in the post. Let me know if you have questions!

      • Chris
        June 4, 2013 at 2:59 pm

        Hi there, thanks for the update. I am however getting crashes in the jfiddle, and I cant get it to work on my end. also when you click search a second time it doesn’t work. I’m using Google chrome if that is any help ?

        • teeohhem
          June 4, 2013 at 3:32 pm

          I am on Chrome as well and have not seen an issue. What is your search term? Which RegEx are you using?

          In my latest updates, I added an optional selector attribute that defines where the search/highlight should take place. The default selector, if not defined, is body. Keep in mind that if there are any HTML elements inside of the selector, the event bindings will be removed when the function executes (the code updates the html of the selector). This is why it does not work a second time. You can somewhat bypass this by trying to use the jQuery .live() function for the event handler of the button, which attaches the event to the document and not the element. Instead, I recommend wrapping your text in a div, assigning an id, and passing that selector to the function instead. Just be sure that your button and input elements live outside of the selector. Otherwise, you could change the jQuery selector (by adding .not() ) to exclude the input element.

  • Neville Franks
    September 16, 2013 at 5:42 pm

    This is fine for simple searching but fails for text that includes styles. ex. Searching from Tom won’t match: Tom

    • teeohhem
      October 18, 2013 at 8:35 am

      Correct. This is not trivial.

  • Jerry
    October 18, 2013 at 12:44 am

    Great tutorial. I’m a Chrome user as well and had the same problem as Chris but your recommendation helped me solve the issue.

    • teeohhem
      October 18, 2013 at 8:36 am

      Great! Thanks for sharing. 🙂

  • Bruno
    December 10, 2013 at 8:47 am

    Hi people!
    I tried commenting but gave up right mt

    My problem is that the code and modify my text, this by modifying the “href” of my images! Thus link them stops working!

    The following problem:
    http://pauma.com.br/fotos_alta/

    Notice that after the search, link and image stop working :/

    • teeohhem
      February 17, 2014 at 11:31 am

      I have updated the code to address the HTML malformation. Please see updated code and fiddle! 🙂

  • RegExp javascript match any word | Developers Questions - Msn4Free.com
    December 15, 2013 at 5:44 pm

    […] JSFiddle & Original Page […]

  • gabouh
    January 15, 2014 at 12:39 pm

    Hi, great tutorial it has been very useful. I would like to avoid the replacement of the searchTerm and just highlighted, how could i only remove the replacement and still be able to work ? Thanks in advance

    • teeohhem
      February 17, 2014 at 11:31 am

      I have updated the code to address the HTML malformation. Please see updated code and fiddle! 🙂

  • i have a issuewith jquery search, hightlight and jump to the highlighted codeCopyQuery CopyQuery | Question & Answer Tool for your Technical Queries,CopyQuery, ejjuit, query, copyquery, copyquery.com, android doubt, ios question, sql query, sqlite que
    January 15, 2014 at 2:35 pm

    […] using this code from this site: enter link description here and also have the running jsfiddle: enter link description here I notice that when you search in […]

  • Jake
    January 21, 2014 at 8:29 am

    Nice functionality. Any thoughts on how to implement this for content that contains html? Searching for ‘a’ will wreck havoc on hyperlinks 🙁

    • teeohhem
      February 17, 2014 at 11:31 am

      I have updated the code to address the HTML malformation. Please see updated code and fiddle! 🙂

  • Anusha
    February 17, 2014 at 7:18 am

    Hi,
    When i tried searching for text “p”, it matched the tags as well. How can we handle this.

    • teeohhem
      February 17, 2014 at 11:32 am

      I have updated the code to address the HTML malformation. Please see updated code and fiddle! 🙂

  • Chris
    February 18, 2014 at 11:44 pm

    THANK YOU SO MUCH <3

  • ES
    March 18, 2014 at 10:40 am

    In your latest fiddle, after searching for first term, button no longer works for subsequent searches. Also does not highlight all terms.

    • ES
      March 18, 2014 at 10:41 am

      Happens in Chrome Version 33.0.1750.154 m

    • teeohhem
      March 19, 2014 at 8:37 am

      The fiddle was linked incorrectly, I apologize. I updated the post and here is the link for your reference: http://jsfiddle.net/z7fjW/310/

  • ES
    March 19, 2014 at 10:13 am

    Thanks.

  • ES
    March 19, 2014 at 1:00 pm

    Found a slight bug. In your fiddle, if you search for Spa, it finds it in the word Space. But, if you then search for Space, it returns no results.

    You are not removing the entire highlight span, you are only removing the class. so the HTML becomes this when you search for Spa:
    Space and thus Space no longer is being found in the subsequent search.

    • ES
      March 19, 2014 at 1:01 pm

      Removed the HTML…hopefully this will show
      <span class=”highlighted”>Spa</span>

  • ES
    March 19, 2014 at 1:02 pm

    Oops..
    <span class=”highlighted”>Spa</span>ce

  • ES
    March 19, 2014 at 1:35 pm

    I modified the code to do the remove to this but the search still doesn’t find anything because of the span that you are creating in the doHighlight. I also placed it just after the first if, ‘if(searchTerm) {‘

    if(removePreviousHighlights) {
    var wrap = $(‘.’+highlightClass);
    $.each(wrap, function(index) {
    $(this).contents().unwrap();
    });
    }

    • teeohhem
      May 16, 2014 at 11:07 am

      Were you able to get your problem resolved? If so, please share!

    • teeohhem
      May 16, 2014 at 11:52 am

      I fixed the issue 🙂 See updated post or fiddle: http://jsfiddle.net/z7fjW/485/

  • JohnDoe
    May 2, 2014 at 5:58 am

    Great code!
    You should remove “abp” attribute from your script btw.

    • teeohhem
      May 16, 2014 at 11:05 am

      I didn’t see that in there. Where are you seeing that?

  • Zach Nicodemous
    May 2, 2014 at 11:55 am

    Great piece of jQuery, though in the newest version of the code you posted on JSFiddle, the “scrollto” functionality seems to be missing.

    Do you have any version of the code with this functionality restored or do you have any insights on how to restore it?

    Thanks

    • teeohhem
      May 16, 2014 at 11:05 am

      Yep!
      Just add this code before the return statement in searchAndHighlight():
      $(window).scrollTop($(‘.highlighted:first’).position().top);

  • Hemaraju
    June 26, 2014 at 6:24 am

    Thank you. Very helpful

  • clash of clans hack tool
    July 8, 2014 at 12:59 am

    I like the helpful information you provide in your articles.
    I’ll bookmark your blog and check again here frequently.
    I’m quite certain I will learn many new stuff right here!
    Good luck for the next!

  • jailbreak ios 7.1
    July 9, 2014 at 3:54 pm

    Hi there just wanted to give you a quick heads up. The words
    in your article seem to be running off the screen in Internet explorer.
    I’m not sure if this is a formatting issue or something to do with web browser compatibility but
    I thought I’d post to let you know. The design look great though!

    Hope you get the problem fixed soon. Many thanks

  • Gregory Smith
    November 14, 2014 at 2:30 am

    I love your blog

    I have read this article and enjoyed it

Leave a Reply

Your email address will not be published. Required fields are marked *.

*
*
You may use these <abbr title="HyperText Markup Language">HTML</abbr> tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">