jQuery: Как скрыть элементы, когда раскрывается другой

#jquery

Вопрос:

заранее извините, я совершенно новичок, борющийся с jQuery.

Я планирую создать галерею, как показано в JSFiddle. таким образом, есть несколько кнопок, которые при нажатии открывают дополнительный контент. Это то, чего я достиг до сих пор.

Теперь все еще не хватает трех вещей:

  1. Мне не удалось снова скрыть дополнительный контент, когда я нажал другую кнопку
  2. Было бы здорово, если бы был способ автоматически прокручивать обнаруженный дополнительный контент при открытии и возвращаться к кнопке, когда она снова закрывается
  3. Как бы вы создали кнопку закрытия внутри раскрываемого содержимого? Было бы неплохо, если бы он прокрутился обратно к кнопке.

Я был бы очень благодарен, если бы кто-нибудь мог мне помочь! Заранее спасибо!

 jQuery(function($) {
             var revealButtons = {
                '.rv_button_1': '.rv_element_1',
                '.rv_button_2': '.rv_element_2',
                '.rv_button_3': '.rv_element_3',
                '.rv_button_4': '.rv_element_4',
                '.rv_button_5': '.rv_element_5',
                '.rv_button_6': '.rv_element_6',
                '.rv_button_7': '.rv_element_7',
                '.rv_button_8': '.rv_element_8',
                '.rv_button_9': '.rv_element_9'

  };
  $.each(revealButtons, function(revealButton, revealElement) {
    $(revealButton).click(function(e) {
      e.preventDefault();
      $(revealElement).slideToggle();
      $(revealButton).toggleClass('rv_button_opened rv_button_closed');
    });
  });

});

        
 .flex-container {

display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-align-content: center;
-ms-flex-line-pack: center;
align-content: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}

.flex-item1 {
display: flex;
background: grey;
text-align: center;
border: black 5px solid;

margin: 20px;
width: 384px;
max-width: 512px;
height: 400px;
}

.flex-item2 {
display: flex;
background: rgb(177, 29, 29);
text-align: center;
margin: 20px;
border: black 5px solid;
width: 512px;
height: 400px;
}

.flex-item3 {
display: flex;
text-align: center;
background: rgb(160, 151, 238);
margin: 20px;
width: 250px;
height: 400px;
}

.flex-item2block {
background: rgb(238, 151, 212);
display: block;
text-align: center;
position: relative;
display: none;
width: 100vw;

height: 50vh;
}

.flex-item3block {
background: rgb(60, 62, 218);
display: block;
text-align: center;
position: relative;
display: none;
width: 100vw;

height: 50vh;
}

.btn {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
background-color: rgba(0, 0, 255, 0);
color: black;
font-size: 16px;
padding: 12px 24px;
border: none;
cursor: pointer;
border-radius: 5px;
text-align: center;
} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
        <div class="flex-container">
      
      
        <div class="flex-item2">
            <button class="rv_button_1 rv_button_closed btn" onclick="myFunction()">Click Me</button>
          </div>
          <div class="rv_element rv_element_1 flex-item2block">grid-item2block</div>
      
  <div class="flex-item1">
            <button class="rv_button_2 rv_button_closed btn" onclick="myFunction()">Click Me</button>
          </div>
          <div class="rv_element rv_element_2 flex-item2block">grid-item2block</div>
      
      <div class="flex-item3">
            <button class="rv_button_3 rv_button_closed btn" onclick="myFunction()">Click Me</button>
          </div>
          <div class="rv_element rv_element_3 flex-item2block">grid-item2block</div>
      
          <div class="flex-item2">
            <button class="rv_button_4 rv_button_closed btn" onclick="myFunction()">Click Me</button>
          </div>
          <div class="rv_element rv_element_4 flex-item2block">grid-item2block</div>
        
         <div class="flex-item2">
            <button class="rv_button_5 rv_button_closed btn" onclick="myFunction()">Click Me</button>
          </div>
          <div class="rv_element rv_element_5 flex-item2block">grid-item2block</div>
        
       <div class="flex-item1">
            <button class="rv_button_6 rv_button_closed btn" onclick="myFunction()">Click Me</button>
          </div>
          <div class="rv_element rv_element_6 flex-item2block">grid-item2block</div>
                


          <div class="flex-item3">
            <button class="rv_button_7 rv_button_closed btn" onclick="myFunction()">Click Me</button>
          </div>
          <div class="rv_element rv_element_7 flex-item3block">grid-item3block</div>
      
      
       <div class="flex-item2">
            <button class="rv_button_8 rv_button_closed btn" onclick="myFunction()">Click Me</button>
          </div>
          <div class="rv_element rv_element_8 flex-item2block">grid-item2block</div>
        
      
        </div>
      </section> 

Комментарии:

1. Внутри вашей click функции выполните итерацию по списку элементов for (let button in revealButtons) . На каждой итерации сравнивайте имя или класс каждой кнопки с выбранной. Если они совпадают, добавьте стиль, чтобы показать это, или стиль, чтобы скрыть в противном случае.

Ответ №1:

Я изменил HTML так, чтобы функция jQuery запускалась при любом нажатии на ваши элементы «кнопка» и «дополнительный контент». Во-первых, функция jQuery анализирует число, включенное в имена ваших классов. Далее мы определяем количество классов «btn» на странице. Затем я повторил этот список. Когда номер в списке совпадает с номером в классе HTML-элемента, на который был нажат, мы открываем соответствующий «дополнительный контент» с помощью slideToggle(), переключаем класс между «rv_button_opened» и «rv_button_closed» и, наконец, проверяем, был ли нажатый элемент кнопкой или дополнительным контентом. Если в названии класса нажата кнопка «элемент», мы переходим к кнопке, и наоборот. Если номер в списке не совпадает с номером в классе, на который был нажат, мы закрываем «дополнительный контент», идентифицируя любой из этих элементов, где стиль «отображение» не «нет». Наконец, мы удаляем класс «rv_button_opened» из этих элементов.

Для вашего #3 весь div действует как кнопка. Вам нужно будет оформить его так, как вы выберете.

HTML:

 <section>
<div class="flex-container">


    <div class="flex-item2">
        <button class="rv_button_1 rv_button_closed btn" onclick="myFunction(this)">Click Me</button>
    </div>
    <div class="rv_element rv_element_1 flex-item2block" onclick="myFunction(this)">grid-item2block</div>

    <div class="flex-item1">
        <button class="rv_button_2 rv_button_closed btn" onclick="myFunction(this)">Click Me</button>
    </div>
    <div class="rv_element rv_element_2 flex-item2block" onclick="myFunction(this)">grid-item2block</div>

    <div class="flex-item3">
        <button class="rv_button_3 rv_button_closed btn" onclick="myFunction(this)">Click Me</button>
    </div>
    <div class="rv_element rv_element_3 flex-item2block" onclick="myFunction(this)">grid-item2block</div>

    <div class="flex-item2">
        <button class="rv_button_4 rv_button_closed btn" onclick="myFunction(this)">Click Me</button>
    </div>
    <div class="rv_element rv_element_4 flex-item2block" onclick="myFunction(this)">grid-item2block</div>

    <div class="flex-item2">
        <button class="rv_button_5 rv_button_closed btn" onclick="myFunction(this)">Click Me</button>
    </div>
    <div class="rv_element rv_element_5 flex-item2block" onclick="myFunction(this)">grid-item2block</div>

    <div class="flex-item1">
        <button class="rv_button_6 rv_button_closed btn" onclick="myFunction(this)">Click Me</button>
    </div>
    <div class="rv_element rv_element_6 flex-item2block" onclick="myFunction(this)">grid-item2block</div>



    <div class="flex-item3">
        <button class="rv_button_7 rv_button_closed btn" onclick="myFunction(this)">Click Me</button>
    </div>
    <div class="rv_element rv_element_7 flex-item3block" onclick="myFunction(this)">grid-item3block</div>


    <div class="flex-item2">
        <button class="rv_button_8 rv_button_closed btn" onclick="myFunction(this)">Click Me</button>
    </div>
    <div class="rv_element rv_element_8 flex-item2block" onclick="myFunction(this)">grid-item2block</div>


</div>
</section>
 

jQuery:

 function myFunction(button) {
//get the numerical value of the button selected (parse it to an int)
var buttonID = parseInt(button.className.match(/d /));
//get the number of btn classes
var buttonCounter = $('.btn').length;
//iterate through each of the button classes
for (let i = 1; i <= buttonCounter; i  ) {
    //matches the button selected to the element class
    if (i === buttonID) {
        $('.rv_element_'   i).slideToggle();
        $('.rv_button_'   i).toggleClass('rv_button_opened rv_button_closed');
        //if the element clicked has a class name that contains "element" scroll to the button, else scroll to the extra content
        if (button.className.indexOf("element") >= 0) {
            $('html, body').animate({
                scrollTop: $(".rv_button_"   buttonID).offset().top
            }, 1000);
        }
        else {
            $('html, body').animate({
                scrollTop: $(".rv_element_"   buttonID).offset().top
            }, 1000);
        }
    }
    else {
        //hide all of the open elements
        if ($('.rv_element_'   i).css('display') != 'none') {
            $('.rv_element_'   i).slideToggle();
        }
        //remove the open class name
        $('.rv_button_'   i).removeClass('rv_button_opened');
    }
}
 

}

Комментарии:

1. Эй, cpyro, большое спасибо за быстрый ответ! Каким-то образом я все еще пытаюсь внедрить ваш код в свой jsfiddle. Извини, я сейчас действительно придурок. Но чего мне не хватает, чтобы заставить jsfiddle работать? Кстати, большое спасибо за вашу помощь!

2. Я обновил свой jQuery до . длина вместо .size(). Размер больше не поддерживается в последних версиях jQuery. Теперь этот код должен работать в вашем jsfiddle.

3. отлично, теперь это работает как заклинание! осталась только одна проблема: когда дополнительный контент уже открыт и я нажимаю на другую кнопку над открытым дополнительным контентом, он работает идеально(прокрутка останавливается на дополнительном контенте), но если я выберу кнопку под дополнительным контентом, прокрутка зайдет далеко, поэтому мне придется снова прокрутить вверх, чтобы увидеть обнаруженный дополнительный контент: jsfiddle.net/lyrus/km6guw7n/27

4. я предполагаю, что такое поведение заключается в том, что сначала раскрывается новый дополнительный контент, а во-вторых, закрывается более старый дополнительный контент. поэтому, если я выберу кнопку над дополнительным контентом, закрытие старого дополнительного контента не повлияет на действие прокрутки, но если я выберу кнопку ниже, действие закрытия старого дополнительного контента вызовет дополнительный скачок, поэтому прокрутка больше не работает правильно.