Как при наведении на элемент развернуть/свернуть список, но чтобы при быстром повторе сворач/разворач не вставало в очередь. Выполнялось однократно

196
08 февраля 2020, 02:10

Есть несколько выпадающих списков, применяю к ним эффекты jquery.ui. При наведении разворачиваю список, а при уведении сворачиваю. И все бы нормально, но при многократном повторении, списки начинают болтаться туда сюда.

Это не ошибка но раздражает, как сделать, чтобы списки вели себя так как если бы мы это написали на css (css использовать не буду, нужен js). То есть независимо от того сколько раз мы навели на список срабатывало только последнее действие и оно же перебивало выполнение остальных. (этот момент до конца сообразить не могу, но вроде бы так правильно, то есть на время выполнения функции она не блокировалась а наоборот перебивала выполнение предыдущей.

Сейчас же получается что выполнение функций встает в очередь

Пробовал создавать массив, при наведении проверять есть ли в нем текущий элемент, если нет, то выполнять функции и добавлять, а при уведении, удалять. Такой массив из флагов, но результат тот же: прыгают

$('.filter-item').hover(function() { 
  var dd_menu = $(this); 
  setTimeout(function() { 
    dd_menu.addClass('open'); 
  }, 50); 
  dd_menu.children('.dropdown-menu').slideDown(200); 
}, function() { 
  $('.filter-item').removeClass('open').children('.dropdown-menu').slideUp(300, function() { 
    $(this).closest('.filter-item').removeClass('open'); 
  }); 
});
.top_row { 
  display: flex; 
} 
 
ul.dropdown-menu { 
  display: none; 
  padding: 0; 
  margin: 0; 
} 
 
ul.dropdown-menu>li { 
  padding: 0; 
  margin: 0; 
  list-style: none; 
} 
 
label { 
  cursor: pointer; 
} 
 
.btn-group { 
  width: calc(100% / 6); 
} 
 
label.param-wprapper input { 
  display: none; 
} 
 
label.param-wprapper input:checked+span { 
  font-weight: bold; 
} 
 
button.btn.btn-default.dropdown-toggle { 
  display: block; 
  width: 100%; 
  background: #fff; 
  border: 1px solid #ccc; 
  padding: 8px; 
  border-radius: 15px; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script> 
<div class="top_row"> 
  <div class="btn-group filter-item field_transaction_type active" data-filter="field_transaction_type"> <button class="btn btn-default dropdown-toggle" data-default="Купить"><span class="value">Купить</span> </button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_transaction_type" type="radio" value="100"><span>Купить</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_transaction_type" type="radio" value="99"><span>Снять</span></label></li> 
    </ul> 
  </div> 
  <div class="btn-group filter-item field_catalog active" data-filter="field_catalog"> <button class="btn btn-default dropdown-toggle" data-default="Квартиру"><span class="value">Квартиру</span></button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="23"><span>Квартиру</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="93"><span>Комнату</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="24"><span>Частный дом</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="68"><span>Коммерческая</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="94"><span>Земельный участок</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="95"><span>Гараж</span></label></li> 
    </ul> 
  </div> 
  <div class="btn-group filter-item field_apartment_type visible active" data-filter="field_apartment_type"> <button class="btn btn-default dropdown-toggle" data-default="Вторичка"><span class="value">Вторичка</span></button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_apartment_type" type="radio" value="oldbuild"><span>Вторичка</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_apartment_type" type="radio" value="newbuild"><span>Новостройка</span></label></li> 
    </ul> 
  </div> 
  <div class="btn-group filter-item field_type_commece" data-filter="field_type_commece"><button class="btn btn-default dropdown-toggle" data-default="Тип объекта"><span class="value">Тип объекта</span></button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="106"><span>Автосервис</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="107"><span>Гостиница</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="104"><span>Готовый бизнес</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="96"><span>Офис</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="105"><span>Свободн. назначения</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="102"><span>Производство</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="98"><span>Склад</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="97"><span>Торговое помещ.</span></label></li> 
    </ul> 
  </div> 
  <div class="btn-group filter-item field_rooms visible" data-filter="field_rooms"> <button class="btn btn-default dropdown-toggle" data-default="Комнат"><span class="value">Комнат</span></button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="25"><span>Студия</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="26"><span>1</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="27"><span>2</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="28"><span>3</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="29"><span>4</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="30"><span>4+</span></label></li> 
    </ul> 
  </div> 
  <div class="btn-group filter-item field_district" data-filter="field_district"> <button class="btn btn-default dropdown-toggle" data-default="Район"><span class="value">Район</span></button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_district" type="checkbox" value="41"><span>Дзержинский</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_district" type="checkbox" value="45"><span>Ленинский</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_district" type="checkbox" value="42"><span>Промышленный</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_district" type="checkbox" value="31"><span>Центральный</span></label></li> 
    </ul> 
  </div> 
</div>

Answer 1

Я немного упростил и выровнял функционал. И ввёл понятие буферного времени. Если элемент меню переключался только недавно, то он не будет этого делать снова.

В то же время, если мы переключаемся на другой элемент меню, и этот элемент переключался достаточно давно, то он выключает остальные элементы, а сам включается.

Задержка определяется переменной bufferTime.

function openMenu(dd_menu) { 
  dd_menu.children('.dropdown-menu').slideDown(200, 
    function() { 
      dd_menu.addClass('open'); 
    } 
  ); 
} 
 
function closeMenu(dd_menu) { 
  dd_menu.children('.dropdown-menu').slideUp(300, 
    function() { 
      dd_menu.removeClass('open'); 
    } 
  ); 
} 
 
var bufferTime = 500 //ms 
 
$('.filter-item').hover( 
  function() { 
    var dd_menu = $(this); 
    var currTime = (new Date()).getTime(); 
    var delta = currTime - dd_menu.attr('data-action-time')||5000; 
    dd_menu.attr('data-action-time', currTime); 
    if (delta > bufferTime) { 
      $('.filter-item').not(dd_menu).each(function() { 
        closeMenu($(this)); 
      }); 
      openMenu(dd_menu); 
    } 
  }, 
  function() { 
    var dd_menu = $(this); 
    var currTime = (new Date()).getTime(); 
    var delta = currTime - dd_menu.attr('data-action-time')||5000; 
    dd_menu.attr('data-action-time', currTime); 
    if (delta > bufferTime) { 
      closeMenu(dd_menu); 
    } 
  } 
);
.top_row { 
  display: flex; 
} 
 
ul.dropdown-menu { 
  display: none; 
  padding: 0; 
  margin: 0; 
} 
 
ul.dropdown-menu>li { 
  padding: 0; 
  margin: 0; 
  list-style: none; 
} 
 
label { 
  cursor: pointer; 
} 
 
.btn-group { 
  width: calc(100% / 6); 
} 
 
label.param-wprapper input { 
  display: none; 
} 
 
label.param-wprapper input:checked+span { 
  font-weight: bold; 
} 
 
button.btn.btn-default.dropdown-toggle { 
  display: block; 
  width: 100%; 
  background: #fff; 
  border: 1px solid #ccc; 
  padding: 8px; 
  border-radius: 15px; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script> 
<div class="top_row"> 
  <div class="btn-group filter-item field_transaction_type active" data-filter="field_transaction_type" data-action-time="0"> <button class="btn btn-default dropdown-toggle" data-default="Купить"><span class="value">Купить</span> </button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_transaction_type" type="radio" value="100"><span>Купить</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_transaction_type" type="radio" value="99"><span>Снять</span></label></li> 
    </ul> 
  </div> 
  <div class="btn-group filter-item field_catalog active" data-filter="field_catalog"> <button class="btn btn-default dropdown-toggle" data-default="Квартиру"><span class="value">Квартиру</span></button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="23"><span>Квартиру</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="93"><span>Комнату</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="24"><span>Частный дом</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="68"><span>Коммерческая</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="94"><span>Земельный участок</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_catalog" type="radio" value="95"><span>Гараж</span></label></li> 
    </ul> 
  </div> 
  <div class="btn-group filter-item field_apartment_type visible active" data-filter="field_apartment_type"> <button class="btn btn-default dropdown-toggle" data-default="Вторичка"><span class="value">Вторичка</span></button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_apartment_type" type="radio" value="oldbuild"><span>Вторичка</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_apartment_type" type="radio" value="newbuild"><span>Новостройка</span></label></li> 
    </ul> 
  </div> 
  <div class="btn-group filter-item field_type_commece" data-filter="field_type_commece"><button class="btn btn-default dropdown-toggle" data-default="Тип объекта"><span class="value">Тип объекта</span></button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="106"><span>Автосервис</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="107"><span>Гостиница</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="104"><span>Готовый бизнес</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="96"><span>Офис</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="105"><span>Свободн. назначения</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="102"><span>Производство</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="98"><span>Склад</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_type_commece" type="radio" value="97"><span>Торговое помещ.</span></label></li> 
    </ul> 
  </div> 
  <div class="btn-group filter-item field_rooms visible" data-filter="field_rooms"> <button class="btn btn-default dropdown-toggle" data-default="Комнат"><span class="value">Комнат</span></button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="25"><span>Студия</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="26"><span>1</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="27"><span>2</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="28"><span>3</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="29"><span>4</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_rooms" type="checkbox" value="30"><span>4+</span></label></li> 
    </ul> 
  </div> 
  <div class="btn-group filter-item field_district" data-filter="field_district"> <button class="btn btn-default dropdown-toggle" data-default="Район"><span class="value">Район</span></button> 
    <ul class="dropdown-menu"> 
      <li class="item"><label class="param-wprapper"><input name="field_district" type="checkbox" value="41"><span>Дзержинский</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_district" type="checkbox" value="45"><span>Ленинский</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_district" type="checkbox" value="42"><span>Промышленный</span></label></li> 
      <li class="item"><label class="param-wprapper"><input name="field_district" type="checkbox" value="31"><span>Центральный</span></label></li> 
    </ul> 
  </div> 
</div>

READ ALSO
Связанные select jQuery

Связанные select jQuery

У меня есть три условных двумерных массивa:

203
Передача данных между компонентами React

Передача данных между компонентами React

Есть две компоненты одного уровня, мне нужно передать значение которое было получено в компоненте NavigationBar в компоненту SearchLine

200
Как достать значение из JSON

Как достать значение из JSON

Нужно достать вот эти msgПытался через точку получить и через квадратные скобки, ничего не получается

188
css анимация и three.js

css анимация и three.js

На странице используется графика построенная с использованием threejs, пока графика строится хотел использовать прелоадер на css (крутилка, вертелка)

206