Bug Tracker

Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#7571 closed bug (invalid)

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

Change History (4)

comment:2 Changed 10 years ago by jitter

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.

comment:3 Changed 10 years ago by anonymous

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?

comment:4 Changed 10 years ago by jitter

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.´

Note: See TracTickets for help on using tickets.