Reputation: 141
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
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
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:
$('.collapse-navbar-first').on('show.bs.collapse')
is fired.bs-body-overlay
$('.collapse-navbar-second').on('show.bs.collapse)
is fired.bs-body-overlay
, it's already there though.$('.collapse-navbar-first').on('hide.bs.collapse')
is fired, because a click outside of the navbar happenedbs-body-overlay
is removedBasicly 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.
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.
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
.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;
}
/**
* @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