1
$('#div_search').keypress(function() {
    var search_term = $(this).val();
    $('.ticker_list').children('div').each(function() {
        var search_value = $(this).attr('search_term');
        if (search_value.indexOf(search_term) >= 0) {
            $(this).show();
        }
        else {
            $(this).hide();
        }
    });
});​

This is really slow, which makes sense since its running through 500 divs and searching each 'search_term' attribute to see if inputed search term is in the attr. Is there a better or faster way to do this? I am even interested for better search mechanisms.

I can modify the DOM, as needed as well.

EDIT Sorry I should have mentioned that say the search term is "hello today johnny", the term "hello", "today" and "johnny" would have to return true, this is why I was using indexOf in the script above.

NoviceCoding
  • 6,145
  • 2
  • 27
  • 33

4 Answers4

5

It's a simple CSS selector:

$(".ticker_list > div[search_term*="+search_term+"]")

You may need to escape search_term though, depending on what it may contain.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • It would be also a good idea to add single quotes around `search_term` – zerkms May 27 '12 at 21:05
  • This runs about the same code but in jQuery, how is this different? – Esailija May 27 '12 at 21:12
  • @gdoron that doesn't suddenly make the performance problem go away though... well it could.. I'm making a jsperf anyway :P – Esailija May 27 '12 at 21:18
  • I just put that `$` because it was in the question and I couldn't be bothered to type `document.querySelectorAll` instead. Normally I would though. This time I was in a rush. – Niet the Dark Absol May 27 '12 at 21:22
  • @Esailija. What about the jsperf? result please... :) – gdoron May 27 '12 at 21:50
  • @gdoron http://jsperf.com/queryselector-search-engine Note that I removed hide and show from loops because queryselector doesn't do that. (And it's not necessary even in the final solution) – Esailija May 27 '12 at 21:51
1
var search_term = this.value;
$('.ticker_list > div[search-term*="' search_term + '"]').show();

Notes:

  • You better use data-* attributes to store "meta-data" for DOM elements, not creating your own attributes.
  • Don't overuse jQuery! you can get input value with this.value instead of $(this).val().
  • If it's an expensive operation, you will get a performance boost moving from the keypress event to change or at least keyup event.
  • If you need to improve your code even more, cache $(this), it can speed up you code a bit.
Community
  • 1
  • 1
gdoron
  • 147,333
  • 58
  • 291
  • 367
  • @NoviceCoding. I saw your's update, I don't think your code working... are you sure it's searching for _hello\today\johnny_ can you produce a demo at http://jsFiddle.net? – gdoron May 27 '12 at 21:40
0

I'd assume this is faster ?

$('#div_search').on('keypress', function(){
       var search_term = this.value,
           elems = document.getElementsByClassName('ticker_list')[0].children;
       for (i=0; i<elems.length; i++) {
           var search_value = elems[i].getAttribute('search_term');
           elems[i].style.display = (search_value.indexOf(search_term) != -1?'block':'none');
       }
});​

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
0

I made a jsperf here

Jsfiddle http://jsfiddle.net/C9m2K/2/

Making some small optimizations such as not hiding or showing elements in a loop improved your speed a little, but still storing the search terms in javascript object was a lot faster.

You can build it like so:

var searchArray = $('.ticker_list').children('div').map( function( elem ){
    return {
        value: $(this).attr( "search_term" ),
        elem: this
    };
}).toArray();

You should also not toggle hide and show in the loop, if a search term only matches once, then you are calling hide 499 times when you could have just hidden the previously shown elements.

$('#div_search').keyup( function() {
    var previouslyShown = [],
        i, len = searchArray.length;

    return function(e) {
        var cur,
            searchTerm = $(this).val();

        $( previouslyShown ).hide();
        previouslyShown = [];
        for( i = 0; i < len; ++i ) {
            cur = searchArray[i];

            if( cur.value.indexOf( searchTerm ) >= 0 ) {
                $( cur.elem ).show();
                previouslyShown.push( cur.elem );
            }
        }

    };
}());
Esailija
  • 138,174
  • 23
  • 272
  • 326