Hide a list when clicking outside (part 2) - javascript

The code below partly works, clicking the button toggles the menu. When the menu is visible I can click anywhere to close it.
But, if I click the button when the menu is visible it hides and then shows it again. That's not the expected behaviour.
$(".lang-toggle-btn").click(function() {
event.preventDefault();
$(this.nextElementSibling).fadeToggle();
});
$(document).mouseup(function(e) {
if (e.target.className == "lang-toggle-btn") {
return false;
}
var container = $(".lang-menu");
if (!container.is(e.target) && container.has(e.target).length === 0) {
container.fadeOut();
}
});
.lang-menu {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="lang-wrap">
<div class="lang-toggle">
<span>Currently viewing</span>
<button class="lang-toggle-btn"><span class="flag"></span><span class="country">United Kingdom</span></button>
<div class="lang-menu">
<ul>
<li><span class="flag"></span><span class="country">Deutschland</span></li>
<li><a class="active" href="/"><span class="flag"></span><span class="country">United Kingdom</span></a></li>
</ul>
</div>
</div>
</div>

You can try this code. This is happening cause when you click on button the class of the target element is country not lang-toggle-btn.
jQuery(".lang-toggle-btn").click(function() {
event.preventDefault();
event.stopPropagation();
jQuery(this.nextElementSibling).fadeToggle();
});
jQuery(document).mouseup(function(e) {
if(e.target.className == "lang-toggle-btn" || e.target.className == "flag" || e.target.className == "country"){
return false;
}
var container = $(".lang-menu");
if (!container.is(e.target) && container.has(e.target).length === 0) {
container.fadeOut();
}
});
.lang-menu {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="lang-wrap">
<div class="lang-toggle">
<span>Currently viewing</span>
<button class="lang-toggle-btn"><span class="flag"></span><span class="country">United Kingdom</span></button>
<div class="lang-menu">
<ul>
<li><span class="flag"></span><span class="country">Deutschland</span></li>
<li><a class="active" href="/"><span class="flag"></span><span class="country">United Kingdom</span></a></li>
</ul>
</div></div>
</div>

Try this code
$(document).ready(function() {
$(".lang-toggle-btn").click(function() {
event.preventDefault();
$(this.nextElementSibling).fadeToggle();
});
$(document).mouseup(function(e) {
if (e.target.className == "country") {
return false;
}
var container = $(".lang-menu");
if (!container.is(e.target) && container.has(e.target).length === 0) {
container.fadeOut();
}
});
});
Demo : https://codepen.io/creativedev/pen/wXKwOJ

When click outside, you also need the exclude the situation when click on the button. other wise the fadeToggle() will trigger twice.
$(".lang-toggle-btn").click(function(event) {
event.preventDefault();
$(this.nextElementSibling).fadeToggle();
});
$(document).mouseup(function(e) {
if (e.target.className == "lang-toggle-btn") {
return false;
}
var container = $(".lang-menu");
if (!$(".country").is(e.target) &&!container.is(e.target) && container.has(e.target).length === 0) {
container.fadeOut();
}
});
.lang-menu {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="lang-wrap">
<div class="lang-toggle">
<span>Currently viewing</span>
<button class="lang-toggle-btn"><span class="flag"></span><span class="country">United Kingdom</span></button>
<div class="lang-menu">
<ul>
<li><span class="flag"></span><span class="country">Deutschland</span></li>
<li><a class="active" href="/"><span class="flag"></span><span class="country">United Kingdom</span></a></li>
</ul>
</div>
</div>
</div>

Related

jquery problem how to perform the function when button will clicked?

enter image description here
html code
<nav class="nav-menu d-none d-lg-block" >
<ul>
#foreach($get_section as $section)
<li class="drop-down">{{$section['name']}}
<ul>
#foreach($section['categories'] as $category)
<li class="#if(!empty($category['sub_category']))drop-down #endif">{{$category['category_name']}}
<ul>
#foreach($category['sub_category'] as $sub_cate)
<li>
{{$sub_cate['category_name']}}
</li>
#endforeach
</ul>
</li>
#endforeach
</ul>
</li>
#endforeach
<li id="navbar"> admin Login </li>
{{--<li id="navbar"> <i class="flaticon-padlock"> </i> customer Login </li>--}}
</ul>
</nav>
javascript code
if ($('.nav-menu').length) {
var $mobile_nav = $('.nav-menu').clone().prop({
class: 'mobile-nav d-lg-none' //mobile nav class
});
$('body').append($mobile_nav);
$('body').prepend('<button type="button" class="mobile-nav-toggle d-lg-none"><i class="icofont-navigation-menu"></i></button>');
$('body').append('<div class="mobile-nav-overly"></div>');
$(document).on('click', '.mobile-nav-toggle', function(e) {
$('body').toggleClass('mobile-nav-active');
$('.mobile-nav-toggle i').toggleClass('icofont-navigation-menu icofont-close');
$('.mobile-nav-overly').toggle();
});
$(document).on('click', '.mobile-nav .drop-down > a', function(e) {
e.preventDefault();
$(this).next().slideToggle(300);
$(this).parent().toggleClass('active');
});
$(document).click(function(e) {
var container = $(".mobile-nav, .mobile-nav-toggle");
if (!container.is(e.target) && container.has(e.target).length === 0) {
if ($('body').hasClass('mobile-nav-active')) {
$('body').removeClass('mobile-nav-active');
$('.mobile-nav-toggle i').toggleClass('icofont-navigation-menu icofont-close');
$('.mobile-nav-overly').fadeOut();
}
}
});
} else if ($(".mobile-nav, .mobile-nav-toggle").length) {
$(".mobile-nav, .mobile-nav-toggle").hide();
}
As shown in the image (mobile version) when the user clicks the admin login button then cross button at the top also clicked simultaneously
so, what should I change in my code to get this functionality

Auto hide navigation on click

So, I have this code, and I'm trying to understand how it works.
Let's say, I wanna make it auto hide when click on link on mobile, what should I add to my code? I guess it is something with js
Begginer here, so thanks to everyone! :)
(function ($) {
"use strict";
// Mobile Navigation
if ($('.main-nav').length) {
var $mobile_nav = $('.main-nav').clone().prop({
class: 'mobile-nav d-lg-none'
});
$('body').append($mobile_nav);
$('body').prepend('<button type="button" class="mobile-nav-toggle d-lg-none"><i class="fa fa-bars"></i></button>');
$('body').append('<div class="mobile-nav-overly"></div>');
$(document).on('click', '.mobile-nav-toggle', function(e) {
$('body').toggleClass('mobile-nav-active');
$('.mobile-nav-toggle i').toggleClass('fa-times fa-bars');
$('.mobile-nav-overly').toggle();
});
$(document).on('click', '.mobile-nav .drop-down > a', function(e) {
e.preventDefault();
$(this).next().slideToggle(300);
$(this).parent().toggleClass('active');
});
$(document).click(function(e) {
var container = $(".mobile-nav, .mobile-nav-toggle");
if (!container.is(e.target) && container.has(e.target).length === 0) {
if ($('body').hasClass('mobile-nav-active')) {
$('body').removeClass('mobile-nav-active');
$('.mobile-nav-toggle i').toggleClass('fa-times fa-bars');
$('.mobile-nav-overly').fadeOut();
}
}
});
} else if ($(".mobile-nav, .mobile-nav-toggle").length) {
$(".mobile-nav, .mobile-nav-toggle").hide();
}
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header id="header" class="fixed-top">
<div class="container">
<div class="logo float-left">
<img src="assets/img/logo/logo2.png" alt="" class="img-fluid">
</div>
<nav class="main-nav float-right d-none d-lg-block">
<ul>
<li class="active">Home</li>
<li>About Us</li>
<li>Services</li>
<li>Why Choose Us</li>
<li>Team</li>
<li>Contact Us</li>
</ul>
</nav><!-- .main-nav -->
</div>
</header>

Click outside div and icon, div hide

HTML:
<div class="menu-right">
<img class="menu-icon" src="images/menu-icon.jpg" alt="menu">
<div class="menu-drop">
<ul>
<li>ABOUT</li>
<li>SERVICES</li>
</ul>
</div>
</div>
Jquery:
$("header .menu-icon").click(function() {
$(".menu-drop").slideToggle();
});
CSS:
.menu-drop {
display: none;
}
I want when click outside .menu-drop and .menu-icon then .menu-drop div hide
when clicking menu-drop div it will stay not hide.
Use mouseup with document like below.
const $menu = $('.menu-icon, .menu-drop');
$(document).mouseup(e => {
if (!$menu.is(e.target) &&
$menu.has(e.target).length === 0) {
$(".menu-drop").hide();
}
});
$('.menu-icon').on('click', () => {
$(".menu-drop").slideToggle();
});
.menu-drop {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu-right">
<img class="menu-icon" src="images/menu-icon.jpg" alt="menu">
<div class="menu-drop">
<ul>
<li>ABOUT</li>
<li>SERVICES</li>
</ul>
</div>
</div>
On document click, you can check whether the clicked element has the specific class or not, if it does not have the class slideUp() the menu. You also have to prevent the event propagation on clicking the menu.
$(".menu-icon").click(function(e) {
e.stopPropagation();
$(".menu-drop").slideToggle();
});
$(document).click(function(e) {
if(!$(e.target).hasClass('menu-right') && !($(e.target).hasClass('menu-drop')|| $(e.target).parents('.menu-drop').hasClass('menu-drop'))){
$(".menu-drop").slideUp();
}
});
.menu-drop {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu-right">
<img class="menu-icon" src="images/menu-icon.jpg" alt="menu">
<div class="menu-drop">
<ul>
<li>ABOUT</li>
<li>SERVICES</li>
</ul>
</div>
</div>
Use a single event listener on the body. Query the event target and show and hid the menu as required.
$(document).ready(function() {
/*Add event listener to document*/
$(document).click(function(event) {
//If the target is the icon, toggle the menu
console.log(event.target);
console.log($(event.target).closest(".menu-drop").length)
if(event.target.matches(".menu-icon"))
{
$(".menu-drop").slideToggle();
}
//Otherwise if outside the menu, slide up
else if($(event.target).closest(".menu-drop").length === 0 )
{
$(".menu-drop").slideUp();
}
});
});
.menu-drop {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu-right">
<img class="menu-icon" src="images/menu-icon.jpg" alt="menu">
<div class="menu-drop">
<ul>
<li>ABOUT</li>
<li>SERVICES</li>
</ul>
</div>
</div>
Here some modification
$(".menu-icon").click(function(e) {
$(".menu-drop").slideDown();
});
$(document).on('click', function (e) {
if(!$(e.target).hasClass('menu-icon'))
$(".menu-drop").slideUp();
});
.menu-drop {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu-right">
<img class="menu-icon" src="images/menu-icon.jpg" alt="menu">
<div class="menu-drop">
<ul>
<li>ABOUT</li>
<li>SERVICES</li>
</ul>
</div>
</div>

Dropdown Button Closing on every click anywhere on the drop down

I made a dropdown that I took from templates on the internet. Here's what I've comed up with but is having a trouble. The problem is, everytime I'm clicking on each link on the dropdown, the dropdown closes. Here's the code:
jQuery(document).ready(function($){
//open/close mega-navigation
$('.cd-dropdown-trigger').on('click', function(event){
event.preventDefault();
toggleNav();
});
//close meganavigation
$('.cd-dropdown .cd-close').on('click', function(event){
event.preventDefault();
toggleNav();
});
//on mobile - open submenu
$('.has-children').children('a').on('click', function(event){
//prevent default clicking on direct children of .has-children
event.preventDefault();
var selected = $(this);
selected.next('ul').removeClass('is-hidden').end().parent('.has-children').parent('ul').addClass('move-out');
});
//on desktop - differentiate between a user trying to hover over a dropdown item vs trying to navigate into a submenu's contents
var submenuDirection = ( !$('.cd-dropdown-wrapper').hasClass('open-to-left') ) ? 'right' : 'left';
$('.cd-dropdown-content').menuAim({
activate: function(row) {
$(row).children().addClass('is-active').removeClass('fade-out');
if( $('.cd-dropdown-content .fade-in').length == 0 ) $(row).children('ul').addClass('fade-in');
},
deactivate: function(row) {
$(row).children().removeClass('is-active');
if( $('li.has-children:hover').length == 0 || $('li.has-children:hover').is($(row)) ) {
$('.cd-dropdown-content').find('.fade-in').removeClass('fade-in');
$(row).children('ul').addClass('fade-out')
}
},
exitMenu: function() {
$('.cd-dropdown-content').find('.is-active').removeClass('is-active');
return true;
},
submenuDirection: submenuDirection,
});
//submenu items - go back link
$('.go-back').on('click', function(){
var selected = $(this),
visibleNav = $(this).parent('ul').parent('.has-children').parent('ul');
selected.parent('ul').addClass('is-hidden').parent('.has-children').parent('ul').removeClass('move-out');
});
function toggleNav(){
var navIsVisible = ( !$('.cd-dropdown').hasClass('dropdown-is-active') ) ? true : false;
$('.cd-dropdown').toggleClass('dropdown-is-active', navIsVisible);
$('.cd-dropdown-trigger').toggleClass('dropdown-is-active', navIsVisible);
if( !navIsVisible ) {
$('.cd-dropdown').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',function(){
$('.has-children ul').addClass('is-hidden');
$('.move-out').removeClass('move-out');
$('.is-active').removeClass('is-active');
});
}
}
//IE9 placeholder fallback
//credits http://www.hagenburger.net/BLOG/HTML5-Input-Placeholder-Fix-With-jQuery.html
if(!Modernizr.input.placeholder){
$('[placeholder]').focus(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
}).blur(function() {
var input = $(this);
if (input.val() == '' || input.val() == input.attr('placeholder')) {
input.val(input.attr('placeholder'));
}
}).blur();
$('[placeholder]').parents('form').submit(function() {
$(this).find('[placeholder]').each(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
})
});
}
});
HTML Code
<div class="cd-dropdown-wrapper nav-div cd-dropdown-trigger" href="#0" id="nav-icon2">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<nav class="cd-dropdown">
<h2>Title</h2>
Close
<ul class="cd-dropdown-content">
<li class="has-children">Catalog
<ul class="cd-secondary-dropdown is-hidden">
<li class="go-back">Menu</li>
<li class="see-all">All Products</li>
<li class="has-children">Travel Gear
<ul class="is-hidden">
<li class="go-back">Clothing</li>
<li class="has-children">Soft Shell
<ul class="is-hidden">
<li class="go-back"></li>
<li>Soft Shell Gen1</li>
<li>Soft Shell Joey</li>
<li class="see-all">All Soft Shell Jackets</li>
</ul>
</li>
<li class="has-children">Sweatshirts
<ul class="is-hidden">
<li class="go-back"></li>
<li class="see-all">All Sweatshirt Jackets</li>
<li>Sweatshirts Gen1</li>
<li>Sweatshirt Joey</li>
</ul>
</li>
<li class="has-children">Polar Fleece
<ul class="is-hidden">
<li class="go-back"></li>
<li class="see-all">All Polar Fleece</li>
<li>Polar Fleece Gen1</li>
<li>Joey Polar Fleece</li>
</ul>
</li>
<li>Windbreakers</li>
<li>Travel Pillow</li>
</ul>
</li>
</ul>
<!-- .cd-secondary-dropdown -->
</li>
<li>About Us</li>
<li>FAQ</li>
<li>Make Money Selling our Jackets</li>
</ul>
<!-- .cd-dropdown-content -->
</nav>
<!-- .cd-dropdown -->
</div>
<script>
$(document).ready(function(){
$('#nav-icon2').click(function(){
$(this).toggleClass('open');
});
});
$("document").ready(function() {
$('#nav-icon2').on('click', function(e) {
if($(this).hasClass('open')) {
e.stopPropagation();
}
});
});
</script>
if you have a open and close button, you should do a hide show. not a toggle.
for instance have a button that adds a style or adds a class with the CSS display:none;
<div style="display:none;">Hidden Stuff</div>
then have a button that gives it the CSS property display:block;
<div style="display:block;">Shown Stuff</div>
but more importantly, its not included in the snippit but i thought i'd ask, do you include jQuery in the <head> tag of your index.html?

True or False Statements JQuery Working Different in IE and Chrome

Live Link : http://velnikolic.com/elliotDev5/
contentActive = true;
var selector = '.mainNav li';
$(selector).on('click', function(){
$(selector).removeClass('active');
$(this).addClass('active');
});
$(".filter").click(function() {
category = $(this).data("filter");
if ($(this).hasClass("active")) {
$(this).removeClass('active');
}
pLoaded();
if (contentActive == true && status == "false") {
$('.contentWrap').children().fadeOut('slow').promise().done(function() {
$('#portfolio').mixItUp({
load: {
filter: category
}
});
contentActive = false;
});
} else {
$('#portfolio').mixItUp({
load: {
filter: category
}
});
}
});
$('.link a').click(function() {
var id = $(this).attr('href');
$('.contentWrap').children().fadeOut('slow').promise().done(function() {
pLoaded();
alert(status);
if(status == "true") {
$('#portfolio').fadeOut('slow').promise().done(function() {
$('#portfolio').mixItUp('destroy', true);
$('#portfolio').removeAttr('style');
$(id).fadeIn('slow', function () {
// Animation complete
});
});
} else {
$(id).fadeIn('slow', function () {
// Animation complete
});
}
contentActive = true;
});
});
var status;
status = false;
function pLoaded() {
status = $('#portfolio').mixItUp('isLoaded');
return status;
}
$(".nav li a").click(function(){
if ($( "#navMenu" ).hasClass( "canvas-slid" )) {
$('#navMenu').offcanvas('hide');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-3 col-sm-4 offcanvas-xs" id="navMenu">
<div class="sidebar-nav">
<div class="navbar navbar-default" role="navigation">
<ul class="nav navbar-nav mainNav">
<img id="logo" class="img-responsive hidden-xs" src="assets/img/logo2.jpg" />
<li class="link">
Home
</li>
<li class="link">
About
</li>
<li class="filter" data-filter=".category-1">
Animation
</li>
<li class="filter" data-filter=".category-2">
Commercial
</li>
<li class="filter" data-filter=".category-3">Documentary
</li>
<li class="filter" data-filter=".category-4">
Film
</li>
<li class="filter" data-filter=".category-5">
Music
</li>
<li class="filter" data-filter=".category-6">
Video Games
</li>
<li class="link">
Services
</li>
</ul>
</div>
</div>
</div>
<div class="contentWrap">
//content
</div>
<div id="portfolio">
</div>
Basically when you click a non filter link it check if theres the portfolio div and fade it out if there is, then load the content.
If a filter is clicked it should check if there is any other content fade it out if so and load the portfolio.
The problem seems to be with the if statements, different iterations work in firefox and chrome and different iterations work only in IE. Driving me crazy to figure out one that works for both
For whatever reason, mixitup2's callback .mixItUp('isLoaded'); returns as a string in IE 11 and a boolean in Chrome and Firefox. My solution could probably be more elegant, but this is what I'm using for not.
if ( (contentActive == true) && (status == "false" || status == false ))

Categories

Resources