Skip to main content

Bug Tracker

Side navigation

#7571 closed bug (invalid)

Opened November 19, 2010 01:03PM UTC

Closed November 19, 2010 01:36PM UTC

Last modified November 19, 2010 03:23PM UTC

closest() with a cascading selector is inconsistent

Reported by: anonymous Owned by:
Priority: undecided Milestone: 1.5
Component: unfiled Version: 1.4.4
Keywords: Cc:
Blocked by: Blocking:

Sometimes .closest() returns inconsistent results on a cascading selector. I don't think this is new to 1.4.4, I think it has happened since at least 1.4.2, perhaps earlier.

// test case:

var x = $(
  '<ul id="l1">' +
      '<li class="cl1">l1.1' +
      '<li class="cl2">l1.2<ul id="l2">' +
          '<li class="cl3">l2.1' +
      '</ul>' +

var t0 = $('li.cl3', x);                    // t0.length = 1
var t1 = $(t0).closest('ul');               // t1.length = 1
var t2 = $(t0).closest('ul li.cl1');        // t2.length = 0 ... why?
var t3 = $(t0).closest('ul li.cl2');        // t3.length = 1
var t4 = $(t0).closest('ul li.cl3');        // t4.length = 1
Attachments (0)
Change History (4)

Changed November 19, 2010 01:26PM UTC by anonymous comment:1

Changed November 19, 2010 01:36PM UTC by jitter comment:2

resolution: → invalid
status: newclosed

Thanks for taking the time to contribute to the jQuery project by writing a bug ticket and providing a testcase!

I think there is a misunderstanding on the behavior of closest() please check the closest() API docs again. For an element to match closest(...) it must be an ancestor of the element in the jQuery object. li.cl1 is not an ancestor of li.cl3. test case as a proof.

The next time please make sure you really found a bug. If you aren't sure you can always first try the jQuery Forum as the jQuery bug tracker is not for support requests.

Changed November 19, 2010 02:19PM UTC by anonymous comment:3

I didn't really expect that closest would return the last element of a cascading selector match, but I can see how that might be useful also. I was trying to use the selector to qualify a direct ancestor, not select a secondary element out of the ancestry tree. I wanted something that worked like .closest() but allowed me to filter out ancestors that didn't meet the filter, and stopped on the first match that did meet the filter. My attempted usage was actually $(obj).closest('div img[src*="some_indicator"]') rather than a simple list element in my example. I was expecting it to return the first direct div ancestor that had an img somewhere in it's child hierarchy that had a specific pattern in its image path.

Perhaps .closest() could take a filter function similar to .filter() or .not() so that this type of functionality could be added without having to duplicate the basic function of .closest() or invalidate the way .closest() works now?

Changed November 19, 2010 03:23PM UTC by jitter comment:4

Please use the jQuery Forum for further support requests.

P.S.: Courtesy: you can use t0.closest('ul:has(li.cl1) to achieve what you want.´