Приём отбора элементов на основе .siblings()
Здравствуйте уважаемые форумчане!
К примеру, есть вот такой зоопарк: <ul> <li class="slonik"></li> <li class="begemotik"></li> <li class="begemotik"></li> <li class="begemotik"></li> <li class="slonik"></li> <li class="slonik"></li> <li class="slonik"></li> <li class="begemotik"></li> <li class="begemotik"></li> </ul> Как при клике на одного из li class="begemotik" получить всех, самых ближайших соседей? Т.е. не всех бегемотиков в списке, а только тех кто рядом с тем, на кого кликнули. p.s. Для тех кому "пояснить задачу подробнее", "объяснить зачем это нужно" или "просто оберни бегемотов в тег" скажу лишь что текущую DOM структуру менять нельзя, и задача именно такая, и реализовать её нужно именно так. |
Цитата:
Цитата:
<ul> <li class="slonik">1</li> <li class="begemotik">2</li> <li class="begemotik">3</li> <li class="begemotik">4</li> <li class="slonik">5</li> <li class="slonik">6</li> <li class="slonik">7</li> <li class="begemotik">8</li> <li class="begemotik">9</li> </ul> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $('li.begemotik').click(function(){ $('li').css( "color", "black" ); $(this).next().css( "color", "red" ); $(this).prev().css( "color", "red" ); }); </script> Цитата:
<ul> <li class="slonik">1</li> <li class="begemotik">2</li> <li class="begemotik">3</li> <li class="begemotik">4</li> <li class="slonik">5</li> <li class="slonik">6</li> <li class="slonik">7</li> <li class="begemotik">8</li> <li class="begemotik">9</li> </ul> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $('li.begemotik').click(function(){ $('li').css( "color", "black" ); $(this).next('.begemotik').css( "color", "red" ); $(this).prev('.begemotik').css( "color", "red" ); }); </script> |
Методы next() и prev() выбирают одного следующего/предыдущего соседа, пожалуйста прочтите первый пост внимательно.
На вашем примере, должно работать так: клик на 2 - выбираются 3 и 4 клик на 3 - выбираются 2 и 4 клик на 9 - выбирается 8 |
самых ближайших соседей на основе .siblings()
<ul> <li class="slonik">1</li> <li class="begemotik">2</li> <li class="begemotik">3</li> <li class="begemotik">4</li> <li class="slonik">5</li> <li class="slonik">6</li> <li class="slonik">7</li> <li class="begemotik">8</li> <li class="begemotik">9</li> </ul> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $('li.begemotik').click(function(){ var i=$(this).index(); $('li').css( "color", "black" ); $(this).siblings().eq(i - 1).css( "color", "red" ); $(this).siblings().eq(i).css( "color", "red" ); }); </script> |
kvizor34,
Цитата:
Уточнять нельзя, но что такое самые ближайшие? Если, как работает siblings(), все дети родителя, то в чем вопрос? |
Цитата:
|
Цитата:
|
Решено, рекурсия
В итоге чтобы решить задачу, я написал две рекурсивных функции, одну для поиска себеподобных после, вторую до себя.
<ul> <li class="slonik"></li> <li class="begemotik"></li> <li class="begemotik"></li> <li class="begemotik"></li> <li class="slonik"></li> <li class="slonik"></li> <li class="slonik"></li> <li class="begemotik"></li> <li class="begemotik"></li> </ul> $('.begemotik').click(function(){ subrowsGroup = []; function findnext(row) { if(row.next().hasClass('begemotik')){ subrowsGroup.push(row.next()); findnext(row.next()); }else{ return false; } } function findprev(row) { if(row.prev().hasClass('begemotik')){ subrowsGroup.push(row.prev()); findprev(row.prev()); }else{ return false; } } findnext($(this)); findprev($(this)); console.log(subrowsGroup); }) Если у кого то появятся другие предложения, пишите, думаю эта тема может быть полезной. |
Кажется я понял (но не уверен :) ):
<ul> <li class="slonik">1</li> <li class="begemotik">2</li> <li class="begemotik">3</li> <li class="begemotik">4</li> <li class="slonik">5</li> <li class="slonik">6</li> <li class="slonik">7</li> <li class="begemotik">8</li> <li class="begemotik">9</li> </ul> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $('li').click(function(){ $('li').css( "color", "black" ); var $this = $(this); var cls = $this.attr('class'); $this.nextUntil(':not(.' + cls + ')').css( "color", "red" ); $this.prevUntil(':not(.' + cls + ')').css( "color", "red" ); }); </script> |
Аналогичный принцип - другая реализация
<ul> <li class="slonik">1</li> <li class="begemotik">2</li> <li class="begemotik">3</li> <li class="begemotik">4</li> <li class="slonik">5</li> <li class="slonik">6</li> <li class="slonik">7</li> <li class="begemotik">8</li> <li class="begemotik">9</li> </ul> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $('li.begemotik').click(function(){ $('li').css( "color", "black" ); var sb = $(this).prev('li.begemotik'); while (sb.index() >= 0){ sb.css( "color", "red" ); sb = sb.prev('li.begemotik'); } sb = $(this).next('li.begemotik'); while (sb.index() >= 0){ sb.css( "color", "red" ); sb = sb.next('li.begemotik'); } }); </script> |
kvizor34,
<!DOCTYPE HTML> <html> <head> <title>Untitled</title> <style type="text/css"> li{ width: 100px; height: 20px; border: 1px dashed Gray; padding: 5px; } .red{ background-color: Red; } </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $(function() { $("ul").on("click", "li", addCls); function addCls() { var el = $(this), cls = ":not(." + this.className +")"; el.nextUntil(cls).add(el.prevUntil(cls)).addClass("red") } }) </script> </head> <body> <ul> <li class="slonik"></li> <li class="begemotik"></li> <li class="begemotik"></li> <li class="begemotik"></li> <li class="slonik"></li> <li class="slonik"></li> <li class="slonik"></li> <li class="begemotik"></li> <li class="begemotik"></li> </ul> </body> </html> |
Aetae,
:) |
Цитата:
я про эти методы (next/prevUntil) вообще никогда не слышал) спасибо большое! :dance: |
<ul> <li class="slonik">1</li> <li class="begemotik">2</li> <li class="begemotik">3</li> <li class="begemotik">4</li> <li class="slonik">5</li> <li class="slonik">6</li> <li class="slonik">7</li> <li class="begemotik">8</li> <li class="begemotik">9</li> </ul> <script> var li = document.querySelectorAll('li'); li.forEach(el=>el.onclick=e=>{ var cls = el.className, th = el; while (el = el.previousElementSibling) { if (el.className !== cls) break; else el.style.color = 'red'; } while (th = th.nextElementSibling) { if (th.className !== cls) break; else th.style.color = 'red'; } }); </script> |
<ul> <li class="slonik">1</li> <li class="begemotik">2</li> <li class="begemotik">3</li> <li class="begemotik">4</li> <li class="slonik">5</li> <li class="slonik">6</li> <li class="slonik">7</li> <li class="begemotik">8</li> <li class="begemotik">9</li> </ul> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $('ul').on('click', 'li', function(){ $this = $(this); var cls = $this.attr('class'); if($this.data('select')=='yes'){ $this.css('color','').data('select', ''); $this.nextUntil(':not(.'+cls+')').css('color','').each(function(){$(this).data('select', '');}); $this.prevUntil(':not(.'+cls+')').css('color','').each(function(){$(this).data('select', '');}); } else { $this.data('select', 'yes'); $this.nextUntil(':not(.'+cls+')').css('color','red').each(function(){$(this).data('select', 'yes');}); $this.prevUntil(':not(.'+cls+')').css('color','red').each(function(){$(this).data('select', 'yes');}); } }); </script> Первое нажатие выделяет, второе - снимает выделение. |
Белый шум
.each(function(){$(this).data('select', 'yes');});== .data('select', 'yes') JQuery всегда работает с массивами. |
<ul> <li class="slonik">slonik 1</li> <li class="begemotik">begemotik 2</li> <li class="begemotik">begemotik 3</li> <li class="begemotik">begemotik 4</li> <li class="slonik">slonik 5</li> <li class="slonik">slonik 6</li> <li class="slonik">slonik 7</li> <li class="begemotik">begemotik 8</li> <li class="begemotik">begemotik 9</li> </ul> <script type="text/javascript"> document.querySelector('ul').addEventListener('click', this) handleEvent = (e) => { var sibling = e.target while (true) { if (!sibling.previousElementSibling || !sibling.previousElementSibling.classList.contains(e.target.className)) break sibling = sibling.previousElementSibling } while (sibling) { if (!sibling.classList.contains(e.target.className)) break else sibling.style.color = 'red' sibling = sibling.nextElementSibling } } </script> мои 5 копеек %) |
Цитата:
|
Часовой пояс GMT +3, время: 05:31. |