Skip to main content

Bug Tracker

Side navigation

#11785 closed bug (patchwelcome)

Opened May 18, 2012 07:24PM UTC

Closed June 12, 2012 01:10PM UTC

Last modified November 24, 2012 03:32AM UTC

.findOne() method

Reported by: dmethvin Owned by:
Priority: undecided Milestone: None
Component: unfiled Version: 1.7.2
Keywords: Cc:
Blocked by: Blocking:
Description

There would certainly be a performance benefit to this on platforms that support querySelector() which is most of them these days.

http://forum.jquery.com/topic/why-there-is-no-jquery-findone-method-or-smth-similar

Also, perhaps we could automatically change $("anything:first") to use querySelector()?

Attachments (0)
Change History (7)

Changed May 18, 2012 07:32PM UTC by rwaldron comment:1

+1 to this

Changed May 19, 2012 11:07PM UTC by rkatic comment:2

_comment0: I think `findFirst()` is more appropriate then `findOne()` for several reasons: 1) It is more similar to the `.first()` method and the `:first` filter. 2) it removes any doubt in case of not simple selectors. Consider `".boo, .foo"`. We expect the `".foo"` element if it precedes the `".boo"` one, becouse it is how `querySelector()` works. \ \ So, I suggest three additions: \ 1. `jQuery.findFirst()`, that behaves like `jQuery.find("...")[0] || null`. \ 2. `jQuery.first()`, that returns `jQuery( jQuery.findFirst("...") )`. \ 3. `jQuery.fn.findFirst()`... \ \ Note how those additions would play nicely with the existent API. For example: \ \ * `$(".boo").first()` **or** `$.first(".boo")` \ * `$(".foo").find(".boo:first")` **or** `$(".foo").findFirst(".boo")` \ 1337470325942110
_comment1: I think `findFirst()` is more appropriate then `findOne()` for several reasons: 1) It is more similar to the `.first()` method and the `:first` filter. 2) it removes any doubt in case of not simple selectors. Consider `".boo, .foo"`. We expect the `".foo"` element if it precedes the `".boo"` one, becouse it is how `querySelector()` works. \ \ So, I suggest three additions: \ 1. `jQuery.findFirst()`, that behaves like `jQuery.find("...")[0] || null`. \ 2. `jQuery.first()`, that returns `jQuery( jQuery.findFirst("...") )`. **OPTIONAL** \ 3. `jQuery.fn.findFirst()`... \ \ Note how those additions would play nicely with the existent API. For example: \ \ * `$(".boo").first()` **or** `$.first(".boo")` **OPTIONAL** \ * `$(".foo").find(".boo:first")` **or** `$(".foo").findFirst(".boo")` \ 1337471489323991
_comment2: I think `findFirst()` is more appropriate then `findOne()` for several reasons: 1) It is more similar to the `.first()` method and the `:first` filter. 2) it removes any doubt in case of not simple selectors. Consider `".boo, .foo"`. We expect the `".foo"` element if it precedes the `".boo"` one, becouse it is how `querySelector()` works. \ \ So, I suggest three additions: \ 1. `jQuery.findFirst()`, that behaves like `jQuery.find("...")[0] || null`. \ 2. `jQuery.first()`, that returns `jQuery( jQuery.findFirst("...") )`. **OPTIONAL** \ 3. `jQuery.fn.findFirst()`... \ \ Note how those additions would play nicely with the existent API. For example: \ \ * `$(".boo").first()` **or** `$.first(".boo")` **OPTIONAL** \ * `$(".foo").find(".boo:first")` **or** `$(".foo").findFirst(".boo")` \ \ **EDIT:** Rethinking, I come with the conclusion that `jQuery.first()` would introduce confusion to the API, since `.first()` is for "filtering" and not for "searching"... so I marked it as optional.1337471775170140

I think findFirst() is more appropriate then findOne() for several reasons: 1) It is more similar to the .first() method and the :first filter. 2) it removes any doubt in case of not simple selectors. Consider ".boo, .foo". We expect the ".foo" element if it precedes the ".boo" one, becouse it is how querySelector() works.

So, I suggest ~~three~~ two additions:

1. jQuery.findFirst(), that behaves like jQuery.find("...")[0] || null

2. jQuery.fn.findFirst()...

3. ~~jQuery.first(), that returns jQuery( jQuery.findFirst("...") )~~

Note how those additions would play nicely with the existent API. For example:

  • $(".foo").find(".boo:first") **or** $(".foo").findFirst(".boo")
  • ~~$(".boo").first() **or** $.first(".boo")~~

**EDIT:** Rethinking, I come with the conclusion that jQuery.first() would introduce confusion to the API, since .first() is for "filtering" and not for "searching"...

Changed May 20, 2012 02:54AM UTC by rwaldron comment:3

After some consideration and re-reading the forum post, I dont think this makes sense. jQuery's API expects jQuery objects, querySelector is a node, not a list of nodes - so it wouldn't work with the current API anyway... Unless we shove it into a jQuery object, then we're back to good ol' jQuery(selector)

Changed May 23, 2012 10:58PM UTC by dmethvin comment:4

I did a quick jsperf to see if it seemed worth the effort. I thought for sure that it would be. Now I am not so sure, can anyone see something wrong here?

http://jsperf.com/findone-vs-findall

Once these are wrapped in the overhead of Sizzle I doubt they will be that much different.

Changed June 12, 2012 01:10PM UTC by dmethvin comment:5

resolution: → patchwelcome
status: newclosed

Per the jsperf I did, it doesn't seem worth adding this method since it's not faster. If someone wants to come up with a full implementation and perf tests proving otherwise we can reopen.

Changed November 24, 2012 03:01AM UTC by jquery@marc-andre.ca comment:6

Putting aside performance for a second, am I the only one that often will look for a single element on the page?

I typically either want to process any number of entries (0, 1 or more), or 1; in the later case, a findOne would be helpful if it raised an exception if none is found.

Changed November 24, 2012 03:32AM UTC by dmethvin comment:7

Not everything needs to be built into jQuery. That's why we have plugins.

jQuery.fn.findOne = function( selector ) {
   var result = this.find( selector );
   if ( this.length != 1 ) {
      jQuery.error( "Didn't find one " + selector );
   }
   return this;
};

http://jsfiddle.net/e4JdY/