Select the closest element by class at the same (or not) level

How to choose the element closest with a certain class that matters or maybe not at the same level as the element with the ability to click?

For example, let says this is the output:

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div> <div> <p class="change-on-click">A</p> <p class="click">Click on this will change A</p> </div> </div> <div> <div> <p class="change-on-click">B</p> <div> <p class="click">Click on this will change B</p> </div> </div> </div> <div> <div> <p class="change-on-click">C</p> <div> <div> <p class="click">Click on this will change C</p> </div> </div> </div> </div> <div> <div> <div> <div> <p class="click">Click on this will change D</p> </div> <p class="change-on-click">D</p> </div> </div> </div> <div> <div> <div> <div> <p class="click">Click on this will change E</p> </div> </div> </div> <p class="change-on-click">E</p> </div> 

I want when I p.click on p.click to find the closest p.change-on-click element.


Just like that, but unfortunately I can’t change the HTML.

 $('.click').on('click', function(){ $(this).closest('.parent').find('.change-on-click').css('color', 'red'); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div class="parent"> <div> <p class="change-on-click">A</p> <p class="click">Click on this will change A</p> </div> </div> <div class="parent"> <div> <p class="change-on-click">B</p> <div> <p class="click">Click on this will change B</p> </div> </div> </div> <div class="parent"> <div> <p class="change-on-click">C</p> <div> <div> <p class="click">Click on this will change C</p> </div> </div> </div> </div> <div class="parent"> <div> <div> <div> <p class="click">Click on this will change D</p> </div> <p class="change-on-click">D</p> </div> </div> </div> <div class="parent"> <div> <div> <div> <p class="click">Click on this will change E</p> </div> </div> </div> <p class="change-on-click">E</p> </div> 

Here is the scenario with the second situation

+5
source share
4 answers

This will require a special approach because the jQuery API does not support this type of search. Basically, just iterate through the parent nodes until you find the click-on-change element.

 $('.click').click(function(){ var node = this; while(node != document.body){ var target = $(node).find('.change-on-click') if( target.length == 0 ){ node = node.parentNode; }else{ target.css('color','red'); return; } } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div> <div> <p class="change-on-click">A</p> <p class="click">Click on this will change A</p> </div> </div> <div> <div> <p class="change-on-click">B</p> <div> <p class="click">Click on this will change B</p> </div> </div> </div> <div> <div> <p class="change-on-click">C</p> <div> <div> <p class="click">Click on this will change C</p> </div> </div> </div> </div> 
+3
source

You can do it as follows:

 $('p.click').each(function(i){ $(this).on("click", function(){$('.change-on-click').eq(i).css('color', 'red');}); }); 

http://jsfiddle.net/4ofajqxa/1/

+2
source

Is this what you are looking for? (Find the target element through the while loop)

 $('.click').on('click', function() { var coc = $(this); while( !coc.prev().is( '.change-on-click' ) ) { coc = coc.parent(); } coc.prev().css('color','red'); }); 

 $('.click').on('click', function() { var coc = $(this); while( !coc.prev().is( '.change-on-click' ) ) { coc = coc.parent(); } coc.prev().css('color','red'); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div> <div> <p class="change-on-click">A</p> <p class="click">Click on this will change A</p> </div> </div> <div> <div> <p class="change-on-click">B</p> <div> <p class="click">Click on this will change B</p> </div> </div> </div> <div> <div> <p class="change-on-click">C</p> <div> <div> <p class="click">Click on this will change C</p> </div> </div> </div> </div> 

OR (Using jQuery Plugin)

 $('p.click').on('click', function(){ $(this).changeOnClick(); }); $.fn.changeOnClick = function() { return this.each(function() { var near = $(this); while( !near.prev().is('.change-on-click') ) { near = near.parent(); } near.prev().css('color','red'); }); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div> <div> <p class="change-on-click">A</p> <p class="click">Click on this will change A</p> </div> </div> <div> <div> <p class="change-on-click">B</p> <div> <p class="click">Click on this will change B</p> </div> </div> </div> <div> <div> <p class="change-on-click">C</p> <div> <div> <p class="click">Click on this will change C</p> </div> </div> </div> </div> 

UPDATE

The next version should work for cases when the target element is before or after the element with a click:

 $('.click').on('click', function() { var coc = $(this); while( !coc.prev().is( '.change-on-click' ) && !coc.next().is( '.change-on-click' ) ) { coc = coc.parent(); } coc.prev().add( coc.next() ).filter( '.change-on-click' ).css('color','red'); }); 

Demo

+1
source

You can do this with jQuery without additional features, etc.

 $('.click').on('click', function(){ $('.change-on-click', $(this).parents('div')).css('color', 'red'); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div> <div> <p class="change-on-click">A</p> <p class="click">Click on this will change A</p> </div> </div> <div> <div> <p class="change-on-click">B</p> <div> <p class="click">Click on this will change B</p> </div> </div> </div> <div> <div> <p class="change-on-click">C</p> <div> <div> <p class="click">Click on this will change C</p> </div> </div> </div> </div> <div> <div> <div> <div> <p class="click">Click on this will change D</p> </div> <p class="change-on-click">D</p> </div> </div> </div> <div> <div> <div> <div> <p class="click">Click on this will change E</p> </div> </div> </div> <p class="change-on-click">E</p> </div> 
0
source

Source: https://habr.com/ru/post/1208610/


All Articles