Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I personally want a small selector function that covers the three common cases

  • getElementById
  • getElementsByClassName
  • getElementsByTagName

It should support contexts and should not support querySelectorAll since <opinionated> QSA is slow as hell and should be avoided </opinionated>

I have an implementation of such a function

function select(selector, context) {
    var c = selector.charAt(0),
        method;

    if (c === "#") {
        method = "getElementById";
        selector = selector.substring(1);
    } else if (c === ".") {
        method = "getElementsByClassName";
        selector = selector.substring(1);
    } else {
        method = "getElementsByTagName";
    }

    return (context || document)[method](selector);
}

And I have a benchmark.

As can be seen it's still a factor of 4 away from native support.

Can I hand optimise this further? And if so, how?

share|improve this question

3 Answers

I'm not sure why no one has suggested a switch ?

As i understand it a switch will be equal or faster than if statements EDIT:- except chrome ... huh!?

switch(c)
{
    case '#':
        ...
        break; // or return
    case '.':
        ...
        break; // or return
    default
        ...
        break; // or return
}

http://jsperf.com/select-vs-natives-vs-jquery/6

share|improve this answer

This is twice as slow as native (the original being 4x as slow)

function select (selector, context) {
    var c = selector.charAt(0), 
        method,
        context = context || document;

    if (c === '#') {
        selector = selector.substring(1);
        method = context.getElementById(selector);
    } 

    else if (c === '.') {
        selector = selector.substring(1);
        method = context.getElementsByClassName(selector);
    } 

    else {
        method = context.getElementsByTagName(selector);
    }

    return method
}
share|improve this answer
2  
benchmarks confirm your function is either the same or faster. – Raynos Dec 10 '11 at 16:43
anything else that could be done? – Thomas Blobaum Dec 10 '11 at 17:56
Fork chrome/firefox and hand optimise their C++ ? – Raynos Dec 10 '11 at 18:04

Well , you have to keep in mind that not all browsers implement getElementsByClassName, not even all of ( what you would call ) "proper browsers".

You should add a fallback for such a problem.

That said, you probably could get rid of at least one IF , if you use something like a { '.': 'getElementsByClassName', '#': 'getElementById' };. Just put said object into closure, otherwise you would be creating it each time anew.

share|improve this answer
1  
I know getElementsByClassName doesn't work in IE8, I have a shim for that. – Raynos Dec 10 '11 at 16:19
I implemented your suggestion as select2. It's actually slightly slower. – Raynos Dec 10 '11 at 16:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.