tropcool
tropcool

Reputation: 141

How to apply 2 animations?

I do not know how to formulate my question.

On my site (Drupal 8 and Bootstrap 4), there is a navigation menu at the top left and a menu at the top right :

https://dev.s1biose.com/fr/boutique/poupette-cacahuete

When I open the navigation menu, the background becomes dark. Same thing for the filter menu.

THE PROBLEM :

If I open the navigation menu without closing it and open the filter menu, there is no dark background.

Why the effect is not displayed ?

There is the same problem with the plus button at the bottom left. I click on the plus button and the bottom is darkened. If I click directly on the menu at the top left, the bottom is not darkened. If I close and open the menu, it works.

Here is my custom JS file :

/**
 * @file
 * Global utilities.
 *
 */
(function ($, Drupal) {

  'use strict';

  $(document).click(function (event) {
    if ($(event.target).is('button')) {
      $('.navbar-collapse').collapse('hide');
    }
  });

  $(document).click(function (event) {
    if (!$(event.target).is('.navbar-collapse *')) {
      $('.navbar-collapse').collapse('hide');
    }
  });

  $('.collapse-navbar-first').on('show.bs.collapse', function () {
    $('body').addClass('bs-body-overlay');
  });

  $('.collapse-navbar-first').on('hide.bs.collapse', function () {
    $('body').removeClass('bs-body-overlay');
  });

  $('.collapse-navbar-second').on('show.bs.collapse', function () {
    $('body').addClass('bs-body-overlay');
  });

  $('.collapse-navbar-second').on('hide.bs.collapse', function () {
    $('body').removeClass('bs-body-overlay');
  });

  $('.collapse-navbar-first').on('show.bs.collapse', function () {
    $('.bs-background').addClass('bs-background-overlay');
  });

  $('.collapse-navbar-first').on('hide.bs.collapse', function () {
    $('.bs-background').removeClass('bs-background-overlay');
  });

  $('.collapse-navbar-second').on('show.bs.collapse', function () {
    $('.bs-background').addClass('bs-background-overlay');
  });

  $('.collapse-navbar-second').on('hide.bs.collapse', function () {
    $('.bs-background').removeClass('bs-background-overlay');
  });

})(jQuery, Drupal);

Upvotes: 1

Views: 64

Answers (2)

Pietro Nadalini
Pietro Nadalini

Reputation: 1800

This error is caused because when it opens the other menu it tries to add the class on the element (which already has it) and then the first menu removes the class when it's closed.

One easy fix you can do for this (probably not the most optimal one) is changing all the addClass and removeClass to make it toggleClass like this:

$('.collapse-navbar-first').on('show.bs.collapse', function () {
  $('.bs-background').toggleClass('bs-background-overlay');
});
$('.collapse-navbar-first').on('hide.bs.collapse', function () {
  $('.bs-background').toggleClass('bs-background-overlay');
});

And to make the code shorter, you can join both events like this:

$('.collapse-navbar-first').on('show.bs.collapse hide.bs.collapse', function () {
  $('.bs-background').toggleClass('bs-background-overlay');
});

Upvotes: 1

Lars
Lars

Reputation: 3573

You're attaching event handlers, it's probably a good idea to group the code that's has the same event as its trigger. (I've done just that in the code snippet).

Event handlers fire in order of the events happening. The behavior you're seeing is because of the code in each event handler:

  1. user clicks left navbar button
    event: $('.collapse-navbar-first').on('show.bs.collapse') is fired.
    It adds the bs-body-overlay
    ---wait for next user click------
  2. user clicks right navbar button
    event $('.collapse-navbar-second').on('show.bs.collapse) is fired.
    It also tries to add the bs-body-overlay, it's already there though.
    event $('.collapse-navbar-first').on('hide.bs.collapse') is fired, because a click outside of the navbar happened
    the bs-body-overlay is removed
    then you're left in the state you're describing.

solution 1: Add css classes for both bars

Basicly the bs-body-overlay is used for both the left and right navbar, you could split that class into 2 seperate ones so that they don't interfere with eachother bs-body-overlay-left and bs-body-overlay-right apply the same rules, they can co-exsist on the element.

solution 2: Check if any of the navbars is open

You could also check if any of the navbars is open, and not remove the bs-body-overlay class when that is the case. it get's a bit finnicky to check this though, since bootstrap is still doing the animation. IE both the left and right bar get the collapsing class before they get the show class.

solution 3: Manually keep track of how many bars are open/closed

You could keep a track of the amounts of open/closes and only remove the bs-body-overlay when you're certain it can be removed I would go with solution 1

css:

.bs-body-overlay, .bs-body-overlay-left, .bs-body-overlay-right {
    overflow: hidden;
}

.bs-background-overlay. .bs-background-overlay-left, .bs-background-overlay-right {
    opacity: .8;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1001;
    width: 100vw;
    height: 100vh;
    background-color: #000;
    transition: .5s ease-out;
}

js:

/**
 * @file
 * Global utilities.
 *
 */
(function ($, Drupal) {

  'use strict';

  $(document).click(function (event) {  // fired whenever anywhere is clicked
  
    if ($(event.target).is('button') || !$(event.target).is('.navbar-collapse *')) {
        // hide the elemnt when the click wasn't on the navbar or the button was clicked
      $('.navbar-collapse').collapse('hide');
    )   
  });

  $('.collapse-navbar-first').on('show.bs.collapse', function () {
    $('body').addClass('bs-body-overlay-left');
    $('.bs-background').addClass('bs-background-overlay-left');
  });

  $('.collapse-navbar-second').on('show.bs.collapse', function () {
    $('body').addClass('bs-body-overlay-right');
    $('.bs-background').addClass('bs-background-overlay-right');
  });
  
  $('.collapse-navbar-first').on('hide.bs.collapse', function () {
    $('body').removeClass('bs-body-overlay-left');
    $('.bs-background').removeClass('bs-background-overlay-left');
  });

  $('.collapse-navbar-second').on('hide.bs.collapse', function () {
    $('body').removeClass('bs-body-overlay-right');
    $('.bs-background').removeClass('bs-background-overlay-right');
  });
})(jQuery, Drupal);

Upvotes: 0

Related Questions