Приём отбора элементов на основе .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, время: 09:36. |