JQuery Метод slideToggle () - PullRequest
       35

JQuery Метод slideToggle ()

1 голос
/ 17 января 2020

Я написал простой код для списка часто задаваемых вопросов; каждый вопрос открывается по событию клика и должен быть закрыт вручную. Есть ли способ переделать этот код так, чтобы в случае нажатия на вопрос, который нужно открыть (слайдон), те, которые были ранее открыты, автоматически сдвигаются, чтобы закрыться?

{% javascript %}
(function() {
  $('body').on('click', '.shopify_explorer_faq__question', function() {
    $(this).next('.shopify_explorer_faq__answer').slideToggle(250).toggleClass('active');
    $(this).toggleClass('active');
  });

  $(document).on('shopify:block:select', '#shopify-section-page-shopify_explorer_faq-template', function(event) {
    $(event.target).find('.shopify_explorer_faq__answer').slideDown(250);
  });

  $(document).on('shopify:block:deselect', '#shopify-section-page-shopify_explorer_faq-template', function(event) {
    $(event.target).find('.shopify_explorer_faq__answer').slideUp(250);
  });
}());
{% endjavascript %}

Ответы [ 3 ]

1 голос
/ 17 января 2020

Вы можете сделать это, отслеживая текущий открытый FAQ. Просто чтобы исправить идею и сделать ее настолько простой, насколько это возможно, допустим, что каждый из блоков FAQ имеет идентификатор, а сами блоки - это div:

<div id="faq-1" class="faq-box">
  Text of the FAQ 1
</div>

<div id="faq-2" class="faq-box">
  Text of the FAQ 2
</div>

...

<div id="faq-n" class="faq-box">
  Text of the FAQ n
</div>

Вы можете получить поведение, которое вы ищете, как это:

var current_faq = ''; // Keep track of the current faq box opened

jQuery( '.faq-box' ).on( 'click', function() {
  // Check if it has been clicked the current box
  if ( jQuery( this ).attr( 'id' ) == current_faq ) {
    // It has been clicked the current box, just slide it up to close
    jQuery( this ).removeClass( 'active' ).slideUp();
    // Set current box opened to empty
    current_faq = '';
  else {
    // Slide down this box
    jQuery( this ).addClass( 'active' ).slideDown();
    // Check if there's a current box opened
    if ( current_faq != '' ) {
      // Slide up the current box
      jQuery( current_faq ).removeClass( 'active' ).slideUp();
    }
    // Set the current box
    current_faq = jQuery( this ).attr( 'id' );
  }
} );
0 голосов
/ 17 января 2020

HTML

Предполагая, что HTML является чередующимся шаблоном схем .question и .answer.

<ul class="faq">
  <li class="question">...</li>
  <li class="answer">...</li>
  ...
</ul>

Сузить основной селектор до .faq. $("body") и $(document) должны использоваться для определенных событий, таких как "key" или "load" типы событий - не распространенные события, такие как "click".


jQuery

Второй параметр event.data используется для обозначения this (в этом случае также event.target). В приведенном ниже примере .question - это this:

$('.faq').on('click', '.question', function(event) {...

Ссылка $(this).next('.answer') с переменной. Переменная, ссылающаяся на jQuery Объект, обычно имеет префикс $ (рекомендуется, но не обязательна).

let $answer = $(this).next('.answer');

Требуемое поведение - это поведение аккордеона :

  • Если щелкнуть элемент из нескольких одинаковых элементов одного элемента (.question, то есть this или event.target), произойдет открывать (и / или связанный с ним элемент - $answer), если он был изначально закрыт, и наоборот.

    $answer.slideToggle(250).toggleClass('active');
    $(this).toggleClass('active');
    
  • Все родственные элементы закроются с исключение this (и связанных элементов, если применимо). Исключение можно выбрать с помощью метода .not().

    $('.question').not(this).removeClass('active')
    $('.answer').not($answer).slideUp(250).removeClass('active');
    

'shopify:block:select/deselect' - это нестандартные события, уникальные для Shopify платформа. Не уверен на 100%, сработает ли следующее, но если их можно делегировать с помощью метода .on(), то, вероятно, его можно запустить с помощью метода .trigger().

if ($(this).hasClass('active')) {
  $answer.trigger('shopify:block:select');
  $('.answer').not($answer).trigger('shopify:block:deselect');
} else {
  $('.answer').trigger('shopify:block:deselect');
} 

Демо

$(function() {
  $('.answer').hide();
  $('.faq').on('click', '.question', function(e) {
    let $answer = $(this).next('.answer');
    $answer.slideToggle(250).toggleClass('active');
    $(this).toggleClass('active');
    $('.question').not(this).removeClass('active');
    $('.answer').not($answer).slideUp(250).removeClass('active');
    if ($(this).hasClass('active')) {
      $answer.trigger('shopify:block:select');
      $('.answer').not($answer).trigger('shopify:block:deselect');
    } else {
      $('.answer').trigger('shopify:block:deselect');
    }
  });
});
:root {
  font: 400 3vw/6vh Arial
}

li {
  padding: 3vh 2vw 1vh;
  margin-bottom: 2vh
}

.question {
  cursor: pointer
}

.answer {
  list-style: none;
  color: blue
}

.active {
  text-decoration: underline;
  font-weight: 900
}
<main>
  <section>
    <header>
      <h1>FAQ</h1>
    </header>
    <ul class='faq'>
      <li class='question'>Question?</li>
      <li class='answer'>Answer.</li>
      <li class='question'>Question?</li>
      <li class='answer'>Answer.</li>
      <li class='question'>Question?</li>
      <li class='answer'>Answer.</li>
      <li class='question'>Question?</li>
      <li class='answer'>Answer.</li>
      <li class='question'>Question?</li>
      <li class='answer'>Answer.</li>
    </ul>
  </section>
</main>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
0 голосов
/ 17 января 2020

Вы можете достичь желаемого поведения, просто добавив строку в верхней части первой функции, которая использует селектор .not():

$('body').on('click', '.shopify_explorer_faq__question', function() {
  $('.shopify_explorer_faq__question').not(this).next('.shopify_explorer_faq__answer').slideUp(250);
  $(this).next('.shopify_explorer_faq__answer').slideToggle(250).toggleClass('active');
  $(this).toggleClass('active');
});
...