How to close a sidebar when clicking outside? - javascript

I have a right sidebar appearing when this function its called
var toggleSidebar = function() {
$('#sidebar .arrow-box').click(function() {
if (s === 0) {
s = 1;
$('#sidebar').css('left', '0');
$('#sidebar .arrow').removeClass('dir-two');
$('#sidebar .arrow').addClass('dir-one');
$('#content').css('padding-left', '0');
} else {
s = 0;
$('#sidebar').css('left', '-300px');
$('#sidebar .arrow').addClass('dir-two');
$('#sidebar .arrow').removeClass('dir-one');
$('#content').css('padding-left', '300px');
}
});
};
but as you see I can open and close that sidebar only when clicking on that specific element, what should I do in order to close it when I click outside?
And just in case: as per UX I am not able to use a dark background in the whole view when the sidebar comes up.

Test the target of the click. If it does not match the target you want to close, then close it. All the other elements are children of the body - so clicking anywhere outside of the panel will retrieve a click target.
$sidebar = $('#sidebar');
$( "body" ).click(function( event ) {
var a = event.target;
if(a === $sidebar){
//close the sidebar
//you may also want to test if it is actually open before calling the close function.
}
});

Take a look at this:
How do I detect a click outside an element?
$('html').click(function() {
// Hide the sidebar
});
$('#sidebar').click(function(event){
event.stopPropagation(); // prevents executing the above event
});

I would do it like this... (DEMO HERE)
sideBarOpen=false;
function openSidebar(){
sideBarOpen = true;
$('#sidebar').css('margin-left', '0');
$('#sidebar .arrow').removeClass('dir-two');
$('#sidebar .arrow').addClass('dir-one');
$('#content').css('padding-left', '0');
}
function closeSidebar(){
sideBarOpen=false;
$('#sidebar').css('margin-left', '-300px');
$('#sidebar .arrow').addClass('dir-two');
$('#sidebar .arrow').removeClass('dir-one');
$('#content').css('padding-left', '300px');
}
$( document ).click(function( event ) {
var target = $( event.target );
if(sideBarOpen){
closeSideBar();
} else {
if(target.is( '#sidebar' )){
openSideBar();
}
}
});
This will close it if the user clicks anywhere, but open it, if the user clicks the sidebar
UPDATE
If you want to also be able to click on the stuff inside the sidebar
Just give them a class, and add to the target.is check.
Example for links inside the bar
<a href='#' class='menuLinks'>Test Link</a>
Then your click handler
if(target.is( '#sidebar' ) || target.is('.menuLinks')){
openSideBar();
} else {
if(sideBarOpen){
closeSideBar();
}

Just detect clicks on an element that encompasses the page. And prevent clicks on the sidebar from bubbling up to that element.
$("body").click(function () {
toggleSidebar();
});
$("#sidebar").click(function (e) {
e.stopPropagation();
});

Related

Need to toggle CSS slide-in function with click on different div?

I have this JSfiddle and i need to slide in, when clicking on a div, and not when page is loaded. Simultaneously it should be possible to close by clicking anywhere outside the slide-in box.
$( document ).ready(function() {
$(function(){
$(".slide-in").addClass("active");
console.log($(".slide-in"));
});
});
I think the solution could be some kind of toggle system, but i can't figure out how to?
Thank you!
Opens the slider on click of .button. Closes it on click anywhere outside the slider (including the button)
var isOpened = false;
$(document).click(function(e) {
if(isOpened && e.target.className=='slide-in') {
$(".slide-in").removeClass("active");
isOpened = false;
} else if(!isOpened && e.target.className=='button'){
$(".slide-in").addClass("active");
isOpened = true;
}
});
Better is to use IDs. So your code would be:
<div id="slide-in"></div>
<div id="button"></div>
and the javascript:
var isOpened = false;
$(document).click(function(e) {
if(isOpened && e.target.id!='slide-in') {
$("#slide-in").removeClass("active");
isOpened = false;
} else if(!isOpened && e.target.id=='button'){
$("#slide-in").addClass("active");
isOpened = true;
}
});
You'll also need to change the CSS from classes to IDs
Try this.
var someDiv = document.getElementById('yourDiv');
someDiv.style.cursor = 'pointer';
someDiv.onclick = function() {
//do something
}
how to make div click-able?
https://jsfiddle.net/zer00ne/jne1rasb/
$(document).ready(function() {
$('.button').on('click dblclick', function(e) {
$('.slide-in').toggleClass('active');
e.stopPropagation();
});
$(document).on('click', function() {
$(".slide-in").removeClass("active");
});
});
I think this should do the trick.
Edit:
$( document ).ready(function() {
$(".button").on("click",function(){
if($(".slide-in").hasClass("active")){
$(".slide-in").removeClass("active");
}else{
$(".slide-in").addClass("active");
}
});
});

Open JS menu on first click, on 2nd click go to URL

Im trying to create a dropdown menu that when first click, shows the children elements, if you click on a child you go to the childs url and if you click the country name again the child menu collapses.
I've got it working to an extent on I can't get the children to link through to their respective links.
Im guessing its to do with my e.preventDefault ?
JS
$('.sub-lang').on('click', function(e){
if ($(this).hasClass('active') && $(e.target).parent().hasClass('active')) {
$(this).removeClass('active');
$(this).css('height', 'auto');
$(this).children('ul').hide();
} else {
$(this).addClass('active');
$(this).css('height', $(this).find('ul').height() + 65 );
$(this).children('ul').show();
}
e.preventDefault();
});
demo
just add javascript:void(0); inside the href attribute of your languages.
English
And remove the preventDefault:
$('.sub-lang').on('click', function(e){
if ($(this).hasClass('active') && $(e.target).parent().hasClass('active')) {
$(this).removeClass('active');
$(this).css('height', 'auto');
$(this).children('ul').hide();
} else {
$(this).addClass('active');
$(this).css('height', $(this).find('ul').height() + 65 );
$(this).children('ul').show();
}
});
the fiddle: http://jsfiddle.net/k4gz3e0s/4/
The problem is that the click event is being propagated up the ancestors as the items are nested under the click target (the .sub-lang element). The e.preventdefault() therefore stops all link clicks anywhere inside that element from performing their default behaviour.
You could just check that the target is the sub-link and conditionally return true or false to allow default behaviour:
return !$(e.target).parent().hasClass('active');
JSFiddle: http://jsfiddle.net/TrueBlueAussie/k4gz3e0s/5/

How to close an open collapsed navbar when clicking outside of the navbar element in Bootstrap 3?

How can I close an open collapsed navbar on clicking outside of the navbar element? Currently, the only way to open or close it is by clicking on the navbar-toggle button.
See here for an example and code:
So far, I have tried the following which doesn't seem to work:
jQuery(document).click(function() {
});
jQuery('.navbar').click(function(event) {
jQuery(".navbar-collapse").collapse('hide');
event.stopPropagation();
});
Have a look that:
$(document).ready(function () {
$(document).click(function (event) {
var clickover = $(event.target);
var _opened = $(".navbar-collapse").hasClass("navbar-collapse in");
if (_opened === true && !clickover.hasClass("navbar-toggle")) {
$("button.navbar-toggle").click();
}
});
});
Your fiddle works with that: http://jsfiddle.net/52VtD/5718/
Its a modified version of this answer, which lacks the animation and is also a tiny bit more complicated.
I know, invoking the click() isn't very elegant, but collapse('hide') did not work for me either, and i think the animation is a bit nicer than adding and removing the classes hardly.
The accepted answer doesn't appear to work correctly. It only needs to check if "navbar-collapse" has the "in" class. We can then fire the collapse method as expected by using our reference to the navbar.
$(document).click(function (event) {
var clickover = $(event.target);
var $navbar = $(".navbar-collapse");
var _opened = $navbar.hasClass("in");
if (_opened === true && !clickover.hasClass("navbar-toggle")) {
$navbar.collapse('hide');
}
});
Using this works for me.
$(function() {
$(document).click(function (event) {
$('.navbar-collapse').collapse('hide');
});
});
The solution I decided to use was taken from the accepted answer here and from this answer
jQuery('body').bind('click', function(e) {
if(jQuery(e.target).closest('.navbar').length == 0) {
// click happened outside of .navbar, so hide
var opened = jQuery('.navbar-collapse').hasClass('collapse in');
if ( opened === true ) {
jQuery('.navbar-collapse').collapse('hide');
}
}
});
This hides an opened collapsed nav menu if the user clicks anywhere outside of the .navbar element. Of course clicking on .navbar-toggle still works to close the menu too.
Converted nozzleman's answer for Bootstrap 4(.3.1):
$(document).ready(function () {
$(document).click(
function (event) {
var target = $(event.target);
var _mobileMenuOpen = $(".navbar-collapse").hasClass("show");
if (_mobileMenuOpen === true && !target.hasClass("navbar-toggler")) {
$("button.navbar-toggler").click();
}
}
);
});
Placed in the ngOnInit().
When the document is loaded, this code waits for click events. If the mobile menu dropdown is open (i.e. the collapsible part of the navbar has the "show" class) and the clicked object (target) is not the mobile menu button (i.e. does not have the "navbar-toggler" class), then we tell the mobile menu button it has been clicked, and the menu closes.
stopPropagation() is not always the best solution. Rather use something like:
jQuery(document.body).on('click', function(ev){
if(jQuery(ev.target).closest('.navbar-collapse').length) return; // Not return false
// Hide navbar
});
I think it's dangerous to assume that you never want to listen to any other event from the .navbar. Which is impossible if you use stopPropagation().
I had a scenario where I had plain text and I didn't want the panel to close if a user clicks on the plain text on accident. The other answers here will close the panel even if you click on the text of an item that isn't a link.
To fix this I added on to Paul Tarr's answer by wrapping the solution in a check to see whether or not the click occurred anywhere inside:
if ($(event.target).parents(".navbar-collapse").length < 1) { }
The full code would become:
$(document).click(function (event) {
if ($(event.target).parents(".navbar-collapse").length < 1) {
var clickover = $(event.target);
var $navbar = $(".navbar-collapse");
var _opened = $navbar.hasClass("in");
if (_opened === true && !clickover.hasClass("navbar-toggle")) {
$navbar.collapse('hide');
}
}
});
In this demo fiddle you can see that if you click on a non-link inside of the panel it won't collapse it.
For latest Bootstrap, this is the correct answer.
$(document).click(function (event) {
var clickover = $(event.target);
var $navbar = $(".navbar-collapse");
var _opened = $navbar.hasClass("show");
if (_opened === true && !clickover.hasClass("navbar-toggler")) {
$navbar.collapse('hide');
}
});
It reads if .navbar-collapse has the word show in classes (which means menu is opened) and hides the navbar when you click/tap anywhere.
I've added a condition to #nozzleman's answer to check if the tap or click has been made on any element within the menu, and if that's the case, not to collapse it.
$(document).ready(function () {
$(document).click(function (event) {
var clickover = $(event.target);
var _opened = $(".navbar-collapse").hasClass("navbar-collapse in");
if (_opened === true && !clickover.hasClass("navbar-toggle") && clickover.parents('.navbar-collapse').length == 0) {
$("button.navbar-toggle").click();
}
});
});
The following code works for me and the advantage is that on small screens, it does not hide the .collapse when you click on its nav parent with .navbar .navbar-expand classes:
$(document).click(function (e) {
if($('.collapse').hasClass('show') && !$('nav').is(e.target) && $('nav').has(e.target).length === 0){
$('.navbar-toggler').click()
}
})
Vanilla Javascript.
Working on Bootstrap 5.2.
window.onload = function () {
document.addEventListener("click", function (event) {
// if the clicked element isn't child of the navbar, you must close it if is open
if (!event.target.closest("#navbar_id") && document.getElementById("navbarSupportedContent").classList.contains("show")) {
document.getElementById("hamburger_menu_button").click();
}
});
}
https://jsfiddle.net/j4tgpbxz/
You just need to add an id to the navbar element, and then check if the clicked element is a child of that same navbar and the content you want to hide (dropdown) is being shown.
For Bootstrap 4
Bootstrap 4 doesn't have an in class. This is Coffeescript.
$(document).click (e)->
#console.log e.target
unless $('#toggle-button').has(e.target).length || $('#toggle-menu').has(e.target).length
$('#toggle-menu').collapse('hide')
So basically, unless you click the button or the menu, close the menu.
Note: Strange, on iOS clicking on text doesn't register a click event, nor a mouseup event. Clicking on an image does fire events though.
For Bootstrap 4:
$(document).click(function(event) {
$(event.target).closest(".navbar").length || $(".navbar-collapse.show").length && $(".navbar-collapse.show").collapse("hide")
});
$(document).click(function (event) {
if ($('.navbar-collapse').attr('aria-expanded') == "true") {
$('.navbar-collapse:visible').click();
}
});
$(window).click(function (e) {
if ($(e.target).closest('.codehim-dropdown').length) {
return;
}
if ($(e.target).closest(offCanvas).length) {
return;
}
//check if menu really opened
if ($(hamburger).hasClass("active")) {
closeMenu();
}
$(dimOverlay).fadeOut();
$(".menu-items").slideUp();
$(".dropdown-heading").removeClass("active");
});
I had some problems with some answers here, and I would like to also be able to close the expanded menu on demand. So I did it with a simple function, and simulating the click.
function closeMenu(){
element = document.getElementById('nav_top');
if(element){
if(element.classList.contains('show')){
document.getElementById('navbar_toggler').dispatchEvent(new CustomEvent('click'));
}
}
}
$(document).ready(function () {
$(document).click(function (event) {
closeMenu();
});
});
Using this method you can close it when clicked outside, but also you can call the closeMenu() at any time from any other function.
I know its quite awhile for the answer. But I think the answer here could helps.
Lets say the condition: if user want to close the navbar when click outside but not when user click any element inside of the navbar
use the event.target and target the element's closest classname whether its has the navbar class or not. If yes which means user is clicking element inside of the navbar and not to close the navbar.
$(function() {
$(document).click(function (event) {
var clickover = $(event.target);
var _opened = $(".navbar-collapse").hasClass("navbar-collapse collapse show");
if (_opened === true && clickover.closest('.navbar').length === 0) {
$(".navbar-collapse").collapse('hide');
}
});
});

hiding div if clicked anywhere in DOM

I have a a textbox in my app, onkeyup I show a div that gets result from database. so whenever user enters something I show the div, the problem is that I want to hide the div if users clicks somewhere else in the DOM.
just like when you select a drop down if you click somewhere else the drop down is closed.
Is there any builtin mechanism for this in jquery or javascript?
$( "body" ).click(function() {
$( "#yourDivIdHere" ).hide();
});
https://api.jquery.com/hide/
Use event delegation and check the originator of a click event. Something like:
$('body').on('click',function (e) {
var origin = e.target || e.srcElement;
if (/* [origin.id != your dropdowndiv.id] */) {
/* hide your dropdowndiv */
}
});
Try this.
Demo: http://jsbin.com/xatanicu/4/edit
$(document).ready(function() {
$('input').focusout(function() {
$(document).click(function(e) {
var targetId = $(e.target)[0].id;
if((targetId !== 'hide-div')) {
$('div').hide();
}
});
});
});
You can hide the result div when the textbox loses focus:
//vanilla JavaScript
textBoxId.onblur = divId.style.display = 'none';
//jQuery
$("#textBoxId").blur(function() {
$("#divId").hide();
});
UPDATE:
It should not hide the result div if the user clicked on the result div itself. (The answer is based on Action on blur except when specific element clicked with jQuery)
var keepFocus = false;
function hideList(){
if(!keepFocus){
$('#divId').hide();
}
}
$('#textBoxId').blur(function() {
keepFocus = false;
window.setTimeout(hideList, 100);
}).focus(function(){
keepFocus = true;
});
$('#divId').blur(function() {
keepFocus = false;
window.setTimeout(hideList, 100);
}).click(function(){
keepFocus = true;
});
See this solution in action here:
http://jsfiddle.net/XC2D7/

jQuery Accordion arrow icons with seperate close button

I've got an accordion with arrow icons indicating when a section is open and closed. Once the accordion is opened the arrow points down showing the content below it.
However I've created a close button that gets appended into each section. This sits at the bottom of every section in the accordion.
I want it so that once the close button is pressed the arrow changes it's state back to closed.
$(function() {
$('#accordion h3').each(function(){
var $set = $(this).nextUntil("h3");
$set.wrapAll('<div />');
});
$('#accordion').accordion({ collapsible:true, active:true, heightStyle:"content", disabled:true, animated: false});
$('.ui-accordion-header').bind('click',function(){
theOffset = $(this).offset();
$(window).scrollTop(theOffset.top - 50);
});
$('#accordion h3.ui-accordion-header').click(function(){
var _this = $(this);
$('.ui-accordion-header-icon', _this).toggleClass('ui-icon-triangle-1-e ui-icon-triangle-1-s');
_this.next().slideToggle();
return false;
});
$('.ui-accordion-content').append('Close<div class="clearfix"></div>');
$('.close').click(function(){
$(this).closest('.ui-accordion-content').toggleClass('ui-icon-triangle-1-s');
$(this).parent().slideUp('slow', function(){
$(window).scrollTop(theOffset.top - 50);
var hidecollapsebutton = true;
$('.ui-accordion-content').each(function(){
if($(this).css('display') == 'block')
{
hidecollapsebutton = false;
}
});
if(hidecollapsebutton)
{
$('.accordion-expand-all').show();
$('.accordion-collapse-all').hide();
}
});
return false;
})
});
Any help would be much appreciated. I can provide more information if it's needed. Thanks.
http://jsfiddle.net/EZT6A/
$('.close').click(function(){
$(this).closest('.ui-accordion-content').toggleClass('ui-icon-triangle-1-s');
As you could have found out yourself with a little simple debugging, $(this).closest('.ui-accordion-content') does not match any element here. (That’s because your close button is within div.ui-accordion-content, and the h3.ui-accordion-header is the previous sibling of that div element.)
Simple to fix: Go up to parent div (.ui-accordion-content), get previous h3 (.ui-accordion-header), and then the span (.ui-accordion-header-icon) element within it:
$(this).parents('.ui-accordion-content')
.prev('.ui-accordion-header')
.find('.ui-accordion-header-icon')
.removeClass('ui-icon-triangle-1-s')
.addClass('ui-icon-triangle-1-e');
http://jsfiddle.net/EZT6A/2/
I'd try changing click to on:
$(document).on("click", ".close", function(){
//change arrow state
});
It's because not every .close element exist as you binding click event.

Categories

Resources