Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery function similar to closest that will return elements outside of the parent chain

Is there any jQuery function similar to closest() that will return elements outside of the parent chain, traversing sideways? For example, I want to call a function foo() on the div source that would return the div target. I know I could navigate using parent() and siblings(), but I need something generic that would go as many levels as needed, up, sideways and down?

var allsources = $('.source');

allsources.click(function()){
  $(this).closest('.target').hide();
});

<div class="row">
  <div>
     <div class="target" ></div>
  </div>
  <div>
    <div>
      <div class="source"></div>
    </div>
  </div>
</div>

<div class="row">
  <div>
     <div class="target" ></div>
  </div>
  <div>
    <div>
      <div class="source"></div>
    </div>
  </div>
</div>

EDIT:

My definition of closest: you have an element source. Try to find it down. If find more than one, return one that is less node hoops down/next/prev. If not found, go one level up, and try to find again. Repeat until no parent.

like image 470
tie Avatar asked Dec 12 '22 20:12

tie


2 Answers

If, by closest, you mean "travel up as little as possible, then anywhere downwards", then you can do

$("#source")
  .closest(":has(.target)")
  .find(".target:first")  //make sure we only select one element in case of a tie

In your case, it would be better to specify the common parent directly:

$(this)
  .closest(".row")
  .find(".target")        //there's no tie here, no need to arbitrate
like image 175
John Dvorak Avatar answered May 18 '23 01:05

John Dvorak


This is a tricky one. As has been commented, how do you define closest in this context? Assuming you can decide on some rules; for example:

Traverse up: 3pt
Traverse down: 2pts
Move sideways: 1pts

And then consider the item with the lowest points to be "closest" then it would be easy enough to author a plugin, named something such as closestAll, which would do the recursive traversal of the whole dom tree to determine the closest item.

However, looking at your recent edit, one (of many!) right solutions to the problem stated is:

var allsources = $('.source');

allsources.click(function(){
  $(this).parents('.row').find('.target').hide();
});

Live example: http://jsfiddle.net/zCvJM/ (Source A only hides Target A, Same for B)

like image 20
Jamiec Avatar answered May 18 '23 01:05

Jamiec