Как найти последний ли в списке и скрыть элемент - PullRequest
0 голосов
/ 03 ноября 2019

Я испытываю затруднения, пытаясь отобразить элемент, когда последний элемент в списке. По сути, у меня есть список, который скрывает и показывает кнопку, ища класс <li class="single-data-item has-multi-items">.

Моя проблема, когда он ищет последний li в <li class="single-data-item has-multi-items">

<li class="single-data-item has-multi-items">
  <ul class="pagnation-2">
    <li>3a</li>
    <li>3b</li>
    <li>3c</li>
  </ul>
</li>

JS код:

if($item.is(':last-child')) {
    $('#multi-next-multi-item').css('display', 'none');
    $('#multi-single-next').css('display', 'block');
}

Проблема в том, чтобы найтипоследние кнопки li и hide / unhide. Он добавляет еще один элемент в список, а затем скрывает / показывает кнопки. Вы можете увидеть это ниже после 3C и добавления другой пули, а затем возобновления нормального.

$('#multi-single-next').click(function() {
    let $item;

    if(!$('ul.pagnation li.single-data-item.active').length) {
        $item = $('ul.pagnation li.single-data-item').first();
    }
    else {
        $prev = $('ul.pagnation li.single-data-item.active');
        $item = $prev.next();

        if(!$prev.next().length) {
            $prev.removeClass('active');
            $prev.hide();
            return;
        }

        $prev.removeClass('active');
        $prev.hide();
    }

    $item.addClass('active');
    $item.show();

    // sub items
    $('ul.pagnation-2 li').removeClass('active');
    if($item.hasClass('has-multi-items')) {
        const $sub = $item.find('ul li').first();
        $sub.addClass('active');
        $sub.show();
        $('#multi-next-multi-item').css('display','block');
        $('#multi-single-next').css('display','none');
    }
});


$('#multi-next-multi-item').click(function() {
    const $item = $('ul.pagnation-2 li.active');
    const $next = $item.next();

    $item.removeClass('active');
    $item.hide();

    $next.addClass('active');
    $next.show();
    if($item.is(':last-child')) {
      $('#multi-next-multi-item').css('display', 'none');
      $('#multi-single-next').css('display', 'block');
	}
    
});
.single-data-item { display: none; }
ul.pagnation-2 li { display: none; }
#multi-next-multi-item { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="multi-single-next" class="button">Single next</button>
<button id="multi-next-multi-item" class="button">Multi item</button>
<ul class="pagnation">
  <li class="single-data-item"><div class="data-item">1</div></li>
  <li class="single-data-item"><div class="data-item">2</div></li>
  <li class="single-data-item has-multi-items">
    <ul class="pagnation-2">
      <li>3a</li>
      <li>3b</li>
      <li>3c</li>
    </ul>
  </li>
  <li class="single-data-item"><div class="data-item">4</div></li>
  <li class="single-data-item"><div class="data-item">5</div></li>
</ul>

Ответы [ 3 ]

1 голос
/ 03 ноября 2019

Немного другой подход с использованием arrays. Вы можете перебирать и устанавливать элементы в массив, а затем поддерживать index текущего видимого элемента. Это оставляет головную боль при разборе дерева во время события click.

var items = [];
var currentIndex = 0;
var currentItem;
$(document).ready(function() {
  $('.single-data-item').each((i, e) => {
    if ($(e).hasClass('has-multi-items')) {
      [...$(e).find('li')].forEach(i => items.push($(i)))
    } else {
      items.push($($(e).find('div')));
    }
  })
});

$('#multi-single-next, #multi-next-multi-item').click(function() {
  if (currentItem) {
    hideItem(currentItem)
  }

  currentItem = items[currentIndex % items.length];
  showItem(currentItem);

  currentIndex++;
});

function showItem(item) {
  if (item.is('div')) {
    item.parent().show();
    $('#multi-single-next').show();
    $('#multi-next-multi-item').hide();
  } else {
    item.show();
    item.closest('.single-data-item').show();
    $('#multi-single-next').hide();
    $('#multi-next-multi-item').show();
  }
}

function hideItem(item) {
  if (item.is('div')) {
    item.parent().hide();
  } else {
    item.hide();
    item.closest('.single-data-item').hide();
  }
}
.single-data-item {
  display: none;
}

ul.pagnation-2 li {
  display: none;
}

#multi-next-multi-item {
  display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="multi-single-next" class="button">Single next</button>
<button id="multi-next-multi-item" class="button">Multi item</button>
<ul class="pagnation">
  <li class="single-data-item">
    <div class="data-item">1</div>
  </li>
  <li class="single-data-item">
    <div class="data-item">2</div>
  </li>
  <li class="single-data-item has-multi-items">
    <ul class="pagnation-2">
      <li>3a</li>
      <li>3b</li>
      <li>3c</li>
    </ul>
  </li>
  <li class="single-data-item">
    <div class="data-item">4</div>
  </li>
  <li class="single-data-item">
    <div class="data-item">5</div>
  </li>
</ul>
1 голос
/ 03 ноября 2019

Вот более простая логика, основанная на совокупности всех <li>, не принадлежащих классу multi-items.

. Следующий элемент определяется индексом активного элемента в этой коллекции. .

Для обеих кнопок можно использовать обработчик одного клика

const $li = $('.pagnation li').not('.has-multi-items'),
  $multi = $('.has-multi-items');


const $buttons = $('#multi-single-next, #multi-next-multi-item').click(function() {
  let $item;
  //easiest to always hide multi then use `add()` below to show the parent as needed
  $multi.hide();
  
  if (!$li.filter('.active').length) {
    $item = $li.first();
  } else {
    const $prev = $li.filter('.active').removeClass('active').hide(),
      nextIdx = $li.index($prev) + 1;
    $item = nextIdx < $li.length ? $li.eq(nextIdx) : $li.first();
  }

  const $multiParent = $item.closest('.has-multi-items')
  // toggle the buttons based on parent being multi or not
  const isMulti = $multiParent.length > 0;
  $buttons.first().toggle(!isMulti)
  $buttons.last().toggle(isMulti)
  // use add() to include the parent multi (if it exists) to show both
  $item.addClass('active').add($multiParent).show();
});
.single-data-item {
  display: none;
}

ul.pagnation-2 li {
  display: none;
}

#multi-next-multi-item {
  display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="multi-single-next" class="button">Single next</button>
<button id="multi-next-multi-item" class="button">Multi item</button>
<ul class="pagnation">
  <li class="single-data-item">
    <div class="data-item">1</div>
  </li>
  <li class="single-data-item">
    <div class="data-item">2</div>
  </li>
  <li class="single-data-item has-multi-items">
    <ul class="pagnation-2">
      <li>3a</li>
      <li>3b</li>
      <li>3c</li>
    </ul>
  </li>
  <li class="single-data-item">
    <div class="data-item">4</div>
  </li>
  <li class="single-data-item">
    <div class="data-item">5</div>
  </li>
</ul>
0 голосов
/ 03 ноября 2019
<ul class="pagnation">
<li class="single-data-item"><div class="data-item">1</div></li>
<li class="single-data-item"><div class="data-item">2</div></li>
<li class="single-data-item has-multi-items"><ul class="pagnation-2">
    <li>3a</li>
    <li>3b</li>
    <li>3c</li>
    **</ul></li>**
<li class="single-data-item"><div class="data-item">4</div></li>
<li class="single-data-item"><div class="data-item">5</div></li>
</ul>

Вы динамически добавляете HTML? если нет, то пытались ли вы удалить эту дополнительную строку в своем коде?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...