A Short Selector without jQuery

  • (2 Pages)
  • +
  • 1
  • 2

23 Replies - 1313 Views - Last Post: 23 March 2014 - 09:09 PM

#1 felgall  Icon User is offline

  • D.I.C Regular

Reputation: 68
  • View blog
  • Posts: 365
  • Joined: 22-February 14

A Short Selector without jQuery

Posted 20 March 2014 - 02:00 PM

Just thought I'd share this code which I came up with as a result of a recent thread where someone was complaining about document.getElementById() being too long.

Basically this code is a far shorter replacement for jQuery 2.0 for when you just need to select elements in the HTML without needing any of the other Javascript functionality.

var $ = function (el,o) {
"use strict";
var d = (undefined===o) ? document : o;
return ('#'===el.slice(0,1) && /^[\S]*$/.test(el)) ? d.querySelector(el) : d.querySelectorAll(el);
}


Using the above code:

$('#myid') provides a static reference to the element with id="myid" (a shorter replacement for the alternative to document.getElementById that was being proposed in that other thread that already works for a larger % of browsers than that alternative does).
$('.myclass') provides a static nodelist of all the elements with class="myclass"
$('#id .myclass) provides a static nodelist of the elements with class="myclass" that are inside of the element with id="myid"
$('.myclass',elem) provides a static nodelist of the elements with class="myclass" that are inside of the element previously retrieved into the variable - elem.

Of course you can also leave off the # or . to reference tag names and use the other characters placed in CSS references to further define the particular nodes you are trying to access. So this code is not only shorter, it is far more flexible as well.

As with jQuery 2.0 this code does not work in older browsers so if you still need to support older browsers with this sort of functionality you might wantto stick with jQuery 1.11.

This post has been edited by laytonsdad: 20 March 2014 - 02:26 PM
Reason for edit:: Fixed code


Is This A Good Question/Topic? 0
  • +

Replies To: A Short Selector without jQuery

#2 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 4136
  • View blog
  • Posts: 13,051
  • Joined: 08-June 10

Re: A Short Selector without jQuery

Posted 20 March 2014 - 02:10 PM

wouldn’t /^\S*$/ suffice as RegExp?

or even el.trim() (assuming that if querySelector() is supported, trim() is as well).

although I think the Snippets section is up again …
Was This Post Helpful? 0
  • +
  • -

#3 ArtificialSoldier  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1828
  • View blog
  • Posts: 5,755
  • Joined: 15-January 14

Re: A Short Selector without jQuery

Posted 20 March 2014 - 02:21 PM

It looks like the forum re-interpreted the return line for you. Let's see if this works:

return ('#'===el.slice(0,1) && /^[\S]*$/.test(el)) ? d.querySelector(el) : d.querySelectorAll(el);


Added:
This has been changed in the original thread.

This post has been edited by laytonsdad: 20 March 2014 - 02:27 PM

Was This Post Helpful? 0
  • +
  • -

#4 laytonsdad  Icon User is offline

  • Let it rip!
  • member icon

Reputation: 466
  • View blog
  • Posts: 1,991
  • Joined: 30-April 10

Re: A Short Selector without jQuery

Posted 20 March 2014 - 02:24 PM

sizzle.js, which jQuery uses as its selector engine, is great also, and it is much smaller than jquery if you only need selections.

This post has been edited by laytonsdad: 09 September 2014 - 12:24 PM

Was This Post Helpful? 0
  • +
  • -

#5 felgall  Icon User is offline

  • D.I.C Regular

Reputation: 68
  • View blog
  • Posts: 365
  • Joined: 22-February 14

Re: A Short Selector without jQuery

Posted 20 March 2014 - 02:31 PM

View PostDormilich, on 21 March 2014 - 07:10 AM, said:

wouldn’t /^\S*$/ suffice as RegExp?

or even el.trim() (assuming that if querySelector() is supported, trim() is as well).

although I think the Snippets section is up again …



You're right the [] are unnecesarry (can't remember why I put them there in the first place.

Trim wouldn't detect if there is a blank in the middle of the string - which is what that test is actually for.
Was This Post Helpful? 0
  • +
  • -

#6 ge∅  Icon User is offline

  • D.I.C Lover

Reputation: 180
  • View blog
  • Posts: 1,126
  • Joined: 21-November 13

Re: A Short Selector without jQuery

Posted 20 March 2014 - 02:50 PM

I use such a function myself but the output is an array and I don't use querySelector and querySelectorAll which are too recent for my taste. I use it only on my intranet because I haven't optimised it yet and there is no error management but it has proven to be reliable.
Was This Post Helpful? 0
  • +
  • -

#7 felgall  Icon User is offline

  • D.I.C Regular

Reputation: 68
  • View blog
  • Posts: 365
  • Joined: 22-February 14

Re: A Short Selector without jQuery

Posted 20 March 2014 - 06:24 PM

A corrected version that either returns a single node (for an id) or a real array so that you can .forEach() the nodes instead of needing a loop. (also modified the regexp)

var $ = function (el,o) {
"use strict";
var d = (undefined===o) ? document : o;
return (/^#\w*$/.test(el)) ? d.querySelector(el) : [].slice.call(d.querySelectorAll(el));
}

This post has been edited by felgall: 20 March 2014 - 06:37 PM

Was This Post Helpful? 0
  • +
  • -

#8 ge∅  Icon User is offline

  • D.I.C Lover

Reputation: 180
  • View blog
  • Posts: 1,126
  • Joined: 21-November 13

Re: A Short Selector without jQuery

Posted 21 March 2014 - 02:12 AM

I think that such function should always return the same type of object. There is a reason why both querySelector and querySelectorAll exist.
Was This Post Helpful? 0
  • +
  • -

#9 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 4136
  • View blog
  • Posts: 13,051
  • Joined: 08-June 10

Re: A Short Selector without jQuery

Posted 21 March 2014 - 04:02 AM

@felgall your ID test is not compatible with HTML5 (it allows all characters but whitespace) and it should be + not * (otherwise a single octothorpe would pass the test) i.e /^#\S+$/

@ge∅ but querySelector() and querySelectorAll() don’t return the same object type either (Node vs. Nodelist resp. HTMLElement vs. HTMLCollection)

This post has been edited by Dormilich: 21 March 2014 - 04:04 AM

Was This Post Helpful? 0
  • +
  • -

#10 ge∅  Icon User is offline

  • D.I.C Lover

Reputation: 180
  • View blog
  • Posts: 1,126
  • Joined: 21-November 13

Re: A Short Selector without jQuery

Posted 21 March 2014 - 04:58 AM

That's what I was saying actually : when you use querySelectorAll, getElementsByTagName or getElementsByClassName, you expect a NodeList/HTMLCollection, they always return the same object type. And when you use querySelector or getElementById you expect a Node/HTMLElement and you always get that as well.

What if I expect a Node and the $() function returns a NodeList ? My code just breaks.
If I remember well, the Prototype library had a $() and a $$() function to distinguish the two object types.
Was This Post Helpful? 0
  • +
  • -

#11 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 4136
  • View blog
  • Posts: 13,051
  • Joined: 08-June 10

Re: A Short Selector without jQuery

Posted 21 March 2014 - 05:02 AM

felgall’s code doesn’t mix up those. you either get a Node/HTMLElement (for IDs) or an Array (everything else)
Was This Post Helpful? 0
  • +
  • -

#12 felgall  Icon User is offline

  • D.I.C Regular

Reputation: 68
  • View blog
  • Posts: 365
  • Joined: 22-February 14

Re: A Short Selector without jQuery

Posted 21 March 2014 - 01:07 PM

View PostDormilich, on 21 March 2014 - 09:02 PM, said:

@felgall your ID test is not compatible with HTML5 (it allows all characters but whitespace) and it should be + not * (otherwise a single octothorpe would pass the test) i.e /^#\S+$/


You are right it should be + rather than * but \S allows any character other than whitespace while \w only allows letters and numbers (as would be allowed in an id) - either would work assuming that the value entered was valid since the test is simply trying to distinguish a single id being supplied to return a single node and for anything else will return an array (easier to process than a nodelist as you can use forEach() instead of a loop).
Was This Post Helpful? 0
  • +
  • -

#13 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 4136
  • View blog
  • Posts: 13,051
  • Joined: 08-June 10

Re: A Short Selector without jQuery

Posted 21 March 2014 - 02:13 PM

View Postfelgall, on 21 March 2014 - 09:07 PM, said:

\w only allows letters and numbers (as would be allowed in an id)

valid ID characters have been changed in HTML5. the new definition is (roughly) "anything except a space character" e.g. "foo-bar" (as well as "アナタバカ") would be a valid ID, but not covered by \w+.
Was This Post Helpful? 0
  • +
  • -

#14 Blindman67  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 138
  • View blog
  • Posts: 615
  • Joined: 15-March 14

Re: A Short Selector without jQuery

Posted 22 March 2014 - 09:14 PM

Nice concept but unusable.

It has inconsistent return types.
Can return null or [] (empty array) if nothing is found. Should these two types not be the same, either both null or both empty arrays?

Can return a single element or one element in an array. Should the single element not be returned in a array to be consistent?

I would also ask why change the Nodelist to an Array. Would it not be better to keep it as a Nodelist.

It will also throw an error for invalid strings in el "name*" and there is no vetting to see if the argument are of the correct type. So a try catch should be in there

All in all it is just better to not use querySelector just use querySelectorAll and keep the return type as a nodeList rather than an array.

Once again (I know broken record here) you mask the fact that there could be more than one id of the same name in the document (Yes I know its not suppose to happen, that ids should be unique. But it does happen through nobodies fault, it could be a bug in your code, server code, third party code) How do you know if the element you get is the element you want?

So just use querySelectorAll or
// works on both Chrome and Firefox
if(document.querySelectorAll("#name").length > 2) {
   throw "W3C HTML Global Structure recommendation violation (7.5.2) id is not unique.";
} else {
   return document.querySelector("#name");
}


Was This Post Helpful? 0
  • +
  • -

#15 ge∅  Icon User is offline

  • D.I.C Lover

Reputation: 180
  • View blog
  • Posts: 1,126
  • Joined: 21-November 13

Re: A Short Selector without jQuery

Posted 23 March 2014 - 04:28 AM

Quote

Should the single element not be returned in a array to be consistent?

It's what I was thinking at first, but passing and id as parameter must be explicit enough. In my implementation, single elements are returned in an array. As a result, I never use it to select elements by their id (you feel stupid when you write things like $("#id")[0]).

Returning an array allows you to use Array.prototype methods (and to extend the Array prototype if you're into this kind of things)

Quote

if(document.querySelectorAll("#name").length > 2)

I don't use querySelectorAll, but according to my tests its length never exceeds 1 when you pass an id as parameter.

This post has been edited by ge∅: 23 March 2014 - 04:31 AM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2