0

Using pure JavaScript without any library like jQuery, how could I detect if a variable holds a DOM Class or ID?

For example if I pass into a function a value that could be...

var mySelector = ".class-name";

or

var mySelector = "#id-name";

Then based on if mySelector holds a Class or ID I would run

document.getElementsByClassName

or

document.getElementsById

What would be the best way to do this without the use of a library like jQuery or another library?

5 Answers 5

2

Take a look at document.querySelector or document.querySelectorAll, instead. Both of those can find elements by ID or class (as well as other selectors). querySelector will return 1 element, querySelectorAll will return all elements.

var mySelector = ".class-name", // "#id-name" will also work fine.
elements = document.querySelectorAll(mySelector);

Note that this doesn't work in IE < 8 (see http://caniuse.com/#search=querySelectorAll). A polyfill would be the best way to handle it to add IE7 support.

Sign up to request clarification or add additional context in comments.

8 Comments

While this is a great solution, it is probably worth noting that this doesn't work on IE < 8... But hopefully we don't worry about that any more (or at least not for much longer). :)
Also, browser native query selector implementations are far faster than JavaScript string manipulation.
@Steve, querySelectorAll has better browser support than getElementsByClassName. Clicky
@Steve Good point. I've updated my answer to point this out. If IE7 support is required, a polyfill would be the recommended approach.
True, but if two elements have the same id (which they shouldn't), querySelectorAll will return both
|
2

You can use this simple if/else statement to differentiate. This would also allow you to run other code based on whether it's a class or an ID you are referencing.

var mySelector = ".class-name";

if(mySelector.charAt(0) == ".")
{
    document.getElementsByClassName(mySelector.substring(1));
}
else if(mySelector.charAt(0) == "#")
{
    document.getElementsById(mySelector.substring(1));
}

7 Comments

Why not mySelector.charAt(0)?
@Ian, yes that would also work. Really just comes down personal preference.
True, but charAt is far faster (although probably unnoticeable), and semantically makes more sense. Still, personal preference is the factor
Note that getElementsByClassName doesn't work in IE8 and below. caniuse.com/#search=getElementsByClassName
@Ian Might as well change it to charAt. It does entail a few less characters of code.
|
1

The first way I think is check a first symbol of stroke. Something like:

var $ = function( string ) {
  var result;
  switch (string.substr(0,1)) {
    case '.': result = document.getElementsByClassName(string); break;
    case '#': result = document.getElementById(string); break;
    default: result = document.getElementsByTagName(string); break;
  }
  return result;
}
var mySelector = ".class-name";
console.log( $(mySelector) );

Comments

1

Just because you only want a selector and not the entire jQuery library, doesn't mean you have to roll your own own. jQuery uses the Sizzle selector engine, and you could just as easily use it yourself without the overhead of full jQuery:

http://sizzlejs.com/

Comments

0

I'm not an advanced user, but some time ago I created this little script:

https://gist.github.com/caiotarifa/cc7d486292f39157d763

var __;

__ = function(selector, filter) {
  'use strict';

  var response;

  function filtering(selectors, filter) {
    switch (filter) {
      case "first":
        return selectors[0];
        break;
      case "last":
        return selectors[selectors.length - 1];
        break;
      default:
        return selectors[filter];
        break;
    }
  }

  selector = selector.trim();
  if (typeof filter === "string") { filter = filter.trim(); }

  if (selector.indexOf(' ') < 0 && selector.indexOf('.', 1) < 0 && selector.indexOf('#', 1) < 0) {
    switch (selector.substr(0, 1)) {
      case '.':
        response = document.getElementsByClassName(selector.substr(1));
        if (response.length === 1) { filter = "first"; }
        if (typeof filter !== "undefined") { response = filtering(response, filter) }
        break;
      case '#':
        response = document.getElementById(selector.substr(1));
        break;
      default:
        response = document.getElementsByTagName(selector);
        if (response.length === 1) { filter = "first"; }
        if (typeof filter !== "undefined") { response = filtering(response, filter) }
        break;
    }
  } else {
    if (typeof filter !== "undefined") {
      switch (filter) {
        case "first":
          response = document.querySelector(selector);
          break;
        case "last":
          response = document.querySelectorAll(selector);
          response = response[response.length - 1];
          break;
        default:
          response = document.querySelectorAll(selector);
          response = response[filter];
          break;
      }
    } else {
      response = document.querySelectorAll(selector);
      if (response.length === 1) { response = response[0]; }
      else if (response.length < 1) { response = false; }
    }
  }

  return response;
};

It's simple to use it:

__("div")

Or passing some filter like:

__("div", "first")

I didn't make a benchmark test with it. I hope it can help you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.