Вращать стрелку у пункта выпадающего списка только с 2 клика

Рейтинг: 1Ответов: 1Опубликовано: 14.02.2023

Есть задача доработать фильтры сортировки. Сейчас реализовано следующее:

  1. Значение по умолчанию - первое, у него, помимо класса ".sort-option', есть ещё и класс ".selected". Также стрелка у этого пункта смотрит вверх
  2. При клике на другой элемент ему добавляется класс ".selected", его стрелка начинает смотреть вверх

Что я пытаюсь доработать: необходимо, чтобы при повторном клике на уже выбранный пункт фильтра, его стрелка должна опускаться вниз, так как есть функция, меняющая порядок сортировки. Если кликать на пункт, то с каждым кликом стрелка должна вращаться, но этого не происходит. В чем моя ошибка?

$('body').click(function(e) {
  if ($('.sort-options').is(':visible')) {
    var $target = $(e.target);
    $('.dropdown-selector').toggleClass('vis')
    if (!$target.hasClass('sort-options') && !$target.hasClass('sort-option') && !$target.hasClass('currently-selected')) {
      $('.sort-options').slideUp(200, 'swing');
    }
  }

  if ($('.sort-option').is('.selected')) {
    $('.sort-option > .sort-option-arr').removeClass('clicked');
    $('.sort-option.selected > .sort-option-arr').addClass('clicked');
  }
});


$('.dropdown-selector').click(function() {
  $('.sort-options').slideToggle(200, 'swing');
});

$('.sort-options > li').click(function() {
  var clickedText = $(this).text(),
    clickedVal = $(this).attr('data-value'),
    currentOptionCont = $('.dropdown-selector').find('.currently-selected'),
    currentOptionText = currentOptionCont.text(),
    currWidth = $(window).width();
  if (clickedText != currentOptionText) {
    $('.sort-options').find('.selected').removeClass('selected');
    $(this).addClass('selected');
    currentOptionCont.text(clickedText).attr('data-value', clickedVal);
  }
});

var clicked = true;
$('.sort-option.selected').click(function() {
  if (clicked) {
    $('.sort-option-arr').removeClass('clicked');
    $('.sort-option-arr').addClass('clicked');
  }
  clicked = !clicked;
});
.dropdown-sort {
  right: 50%;
  top: 50%;
  height: 44px;
  position: absolute;
  z-index: 10;
}

.sort-options {
  display: none;
  position: relative;
  list-style: none;
  margin: 0px;
  background: #fff;
  border: 1px solid #dddddd;
  border-top: none;
  border-radius: 0 0 5px 5px;
}

.sort-options li {
  transition: 0.2s ease-in-out;
}

.sort-option {
  padding: 1em;
  cursor: pointer;
  background-color: #ffffff;
}

.sort-option span {
  display: inline-block;
  color: #4e4e4e;
}

.sort-option img {
  width: 8px;
  height: 8px;
}

.sort-option-arr.clicked {
  transform: rotate(180deg);
}

.angle-selectors {
  height: 30px;
  width: 100%;
  float: right;
  display: block;
}

.angle-selectors .drop {
  width: 100%;
}

.dropdown-selector {
  width: 255px;
  color: #4e4e4e;
  background-color: #ffffff;
  border: 1px solid #dddddd;
  border-radius: 5px;
  font-weight: 500;
  font-size: 14px;
  line-height: 17px;
  color: #4e4e4e;
  z-index: 10;
}

.currently-selected {
  height: 44px;
  display: flex;
  align-items: center;
  padding-left: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown-sort">
  <div class="dropdown-selector">
    <div id="sort-by">
      <div class="currently-selected" data-value="По дате начала продажи">По дате начала продажи</div>
      <ul id="sortOptions" class="sort-options">
        <li class="sort-option selected" data-value="По дате начала продажи">По дате начала продажи <svg class="sort-option-arr" width="12" height="7" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.271242 0.295165C-0.0921565 0.662571 -0.0914839 1.25422 0.272749 1.6208L5.29075 6.67114C5.68179 7.06469 6.31846 7.06469 6.7095 6.67114L11.7243 1.62401C12.0903 1.25566 12.091 0.661134 11.7258 0.291944C11.3556 -0.0824116 10.7509 -0.0824112 10.3806 0.291945L6.35561 4.36133C6.15992 4.55918 5.84034 4.55918 5.64464 4.36133L1.62283 0.295165C1.2508 -0.0809641 0.643268 -0.0809636 0.271242 0.295165Z" fill="#DDDDDD"/>
</svg>
        </li>
        <li class="sort-option" data-value="По цене объекта">По цене объекта <svg class="sort-option-arr" width="12" height="7" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.271242 0.295165C-0.0921565 0.662571 -0.0914839 1.25422 0.272749 1.6208L5.29075 6.67114C5.68179 7.06469 6.31846 7.06469 6.7095 6.67114L11.7243 1.62401C12.0903 1.25566 12.091 0.661134 11.7258 0.291944C11.3556 -0.0824116 10.7509 -0.0824112 10.3806 0.291945L6.35561 4.36133C6.15992 4.55918 5.84034 4.55918 5.64464 4.36133L1.62283 0.295165C1.2508 -0.0809641 0.643268 -0.0809636 0.271242 0.295165Z" fill="#DDDDDD"/></li>
        <li class="sort-option" data-value="По цене за метр">По цене за метр <svg class="sort-option-arr" width="12" height="7" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.271242 0.295165C-0.0921565 0.662571 -0.0914839 1.25422 0.272749 1.6208L5.29075 6.67114C5.68179 7.06469 6.31846 7.06469 6.7095 6.67114L11.7243 1.62401C12.0903 1.25566 12.091 0.661134 11.7258 0.291944C11.3556 -0.0824116 10.7509 -0.0824112 10.3806 0.291945L6.35561 4.36133C6.15992 4.55918 5.84034 4.55918 5.64464 4.36133L1.62283 0.295165C1.2508 -0.0809641 0.643268 -0.0809636 0.271242 0.295165Z" fill="#DDDDDD"/></li>
      </ul>
    </div>
  </div>
</div>

Ответы

▲ 1Принят

На мой взгляд, в скрипте было много лишнего, поэтому я его почти полностью переписал (думаю, стало намного короче и понятнее):

/* Закрытие всех списков, кроме текущего */
$('body').click(function(ev) {
  $('.sort-options').not(ev.target.nextElementSibling).slideUp(200, 'swing');
});
/* Раскрытие списка */
$('.currently-selected').click(function() {
  $(this).next('.sort-options').slideDown(200, 'swing');
});
/* Выбор типа и направления сортировки */
$('.sort-options > li').click(function(ev) {
  let $this = $(this);
  // Если пункт уже выбран
  if ($this.is('.selected')) {
    // Меняем направление сортировки
    $this.find('.sort-option-arr').toggleClass('clicked');
  // Иначе выбираем новый пункт
  } else {
    $this.siblings().removeClass('selected');
    $this.addClass('selected');
    $this.parent().siblings('.currently-selected').text($this.text()).attr('data-value', $this.attr('data-value'));
  }
  $this.closest('.sort-options').slideUp(200, 'swing');
});
.dropdown-sort {
  /* Отключено для примера
  position: absolute;
  right: 50%; top: 50%; z-index: 10; */
  height: 44px;
  float: left; /* <-- Добавлено для примера */
}
/* Без изменений */
.dropdown-selector{width:255px;color:#4e4e4e;background-color:#fff;border:1px solid #ddd;border-radius:5px;font-weight:500;font-size:14px;line-height:17px;color:#4e4e4e;z-index:10}
.currently-selected{height:44px;display:flex;align-items:center;padding-left:15px}
.sort-options{display:none;position:relative;list-style:none;margin:0;background:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 5px 5px}
.sort-options li{transition:.2s ease-in-out}
.sort-option{padding:1em;cursor:pointer;background-color:#fff}
.sort-option span{display:inline-block;color:#4e4e4e}
.sort-option img{width:8px;height:8px}
/* Стрелка направления сортировки */
.sort-option-arr {
  display: inline-block;
  width: 12px; height: 7px;
  background-image: url('data:image/svg+xml,%3Csvg width="12" height="7" viewBox="0 0 12 7" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="M.27 .3C-.09 .66 -.09 1.25 .27 1.62L5.29 6.67C5.68 7.06 6.32 7.06 6.71 6.67L11.72 1.62C12.09 1.26 12.09 .66 11.73 .29C11.36 -.08 10.75 -.08 10.38 .29L6.36 4.36C6.16 4.56 5.84 4.56 5.64 4.36L1.62 .3C1.25 -.08 .64 -.08 .27 0.3Z" fill="%23F00"/%3E%3C/svg%3E');
}
/* Без изменений */
.sort-option-arr.clicked{transform:rotate(180deg)}
.angle-selectors{height:30px;width:100%;float:right;display:block}
.angle-selectors .drop{width:100%}
/* Добавлено для примера */
.selected { background-color: #08f2; }
body { min-height: 90vh; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Первый список -->
<div class="dropdown-sort">
  <div class="dropdown-selector">
    <div id="sort-by">
      <div class="currently-selected" data-value="По дате начала продажи">По дате начала продажи</div>
      <ul id="sortOptions" class="sort-options">
        <li class="sort-option selected" data-value="По дате начала продажи">По дате начала продажи
          <div class="sort-option-arr"></div>
        </li>
        <li class="sort-option" data-value="По цене объекта">По цене объекта
          <div class="sort-option-arr"></div>
        </li>
        <li class="sort-option" data-value="По цене за метр">По цене за метр
          <div class="sort-option-arr"></div>
        </li>
      </ul>
    </div>
  </div>
</div>
<!-- Второй список для примера и аналогичен первому за исключением ID -->
<div class="dropdown-sort"><div class="dropdown-selector"><div id="sort-by2"><div class="currently-selected" data-value="По дате начала продажи">По дате начала продажи</div><ul id="sortOptions2" class="sort-options"><li class="sort-option selected" data-value="По дате начала продажи">По дате начала продажи <div class="sort-option-arr"></div></li><li class="sort-option" data-value="По цене объекта">По цене объекта <div class="sort-option-arr"></div></li><li class="sort-option" data-value="По цене за метр">По цене за метр <div class="sort-option-arr"></div></li></ul></div></div></div>

Также перенёс изображение стрелки в CSS.