Toggle dropdown when screen size < 1200 - javascript

I write such function which on screen with width > 1200 have hover effect and show menu
$(window).resize(function(){
var width = $(window).innerWidth();
dropDown(width);
});
var dropDown = function(width){
if(width > 1200){
$(".dropdown").hover(function() {
$('.dropdown-menu', this).stop( true, true ).fadeIn("fast");
$(this).toggleClass('open');
$('b', this).toggleClass("caret caret-up");
}, function() {
$('.dropdown-menu', this).stop( true, true ).fadeOut("fast");
$(this).toggleClass('open');
$('b', this).toggleClass("caret caret-up");
}
);
}
};
The problem is when i refresh page on mobile size - all looks fine, but then change size of window > 1200px and then change size of window < 1200px my dropDown show when i hover, but i don't need it, it must open only when i click. Where is the problem? What i should do?
My html
<li class="dropdown">
DROPDOWN <b class="caret"></b>
<ul class="dropdown-menu">
<li>1</li>
<li>2</li>
</ul>
</li>

You've not removed the hover handler when the window is less that 1200 wide, so the event handler still exists and works. The else part of the if statement below will fix that for you...
var openDropDown = function(el) {
var $el = $(el);
$('.dropdown-menu', $el).stop( true, true ).fadeIn("fast");
$el.toggleClass('open');
$('b', $el).toggleClass("caret caret-up");
};
var closeDropDown = function(el) {
var $el = $(el);
$('.dropdown-menu', $el).stop( true, true ).fadeOut("fast");
$el.toggleClass('open');
$('b', $el).toggleClass("caret caret-up");
};
var dropDown = function(width){
if(width > 1200){
$(".dropdown")
.off("click")
.hover(function() {
openDropDown(this);
}, function() {
closeDropDown(this);
});
}
else {
$(".dropdown")
.off("mouseenter mouseleave")
.on("click", function() {
if ($(this).hasClass("open")) {
closeDropDown(this);
}
else {
openDropDown(this);
}
});
}
};
I've also moved the code to open and close the dropdown into separate functions so that it can be reused. I then added a click handler to make the dropdown work when clicked when the window is < 1200 wide.

Related

How to execute action only once in jquery?

I have been using this script to show modal popup window on my site with some QR code inside and it works on single pages but on category pages its called multiple times and because of that it shows 10 times the same window. How can I limit this to be showed only once on the nearest ancor position?
Code:
<li class="qrcode">
<a class="popup-trigger"></a>
</li>
</ul>
<div class="contain-popup">
<div class="popup">
my qr code
<span class="popup-btn-close">X</span>
</div>
</div>
<script>
// Popup Window
var scrollTop = '10';
var newHeight = '100';
$(window).bind('scroll', function() {
scrollTop = $( window ).scrollTop();
newHeight = scrollTop + 100;
});
$('.popup-trigger').click(function(e) {
e.stopPropagation();
if(jQuery(window).width() < 767) {
$(this).after( $( ".popup" ) );
$('.popup').show().addClass('popup-mobile').css('top', 0);
} else {
$('.popup').removeClass('popup-mobile').css('top', newHeight).toggle();
};
});
$('html').click(function() {
$('.popup').hide();
});
$('.popup-btn-close').click(function(e){
$('.popup').hide();
});
$('.popup').click(function(e){
e.stopPropagation();
});
</script>
One simple way to achieve it is to remove() it's html with hiding it at the same time:
$('html').click(function() {
$('.popup').hide();
$('.popup').remove();
});
Instead of hide(), remove the class assign to it.
$('.popup').remove();
// Popup Window
var scrollTop = '10';
var newHeight = '100';
$(window).bind('scroll', function() {
scrollTop = $( window ).scrollTop();
newHeight = scrollTop + 100;
});
$('.popup-trigger').click(function(e) {
e.stopPropagation();
if(jQuery(window).width() < 767) {
$(this).after( $( ".popup" ) );
$('.popup').show().addClass('popup-mobile').css('top', 0);
} else {
$('.popup').removeClass('popup-mobile').css('top', newHeight).toggle();
};
});
$('html').click(function() {
$('.popup').hide();
$('.popup').remove();
});
$('.popup-btn-close').click(function(e){
$('.popup').hide();
});
$('.popup').click(function(e){
e.stopPropagation();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="qrcode">
<a class="popup-trigger"></a>
</li>
</ul>
<div class="contain-popup">
<div class="popup">
my qr code
<span class="popup-btn-close">X</span>
</div>
</div>
Solution was quite simple, I don't know how I missed it:
jQuery(document).ready(function($){
$('.popup-trigger').click(function(){
$(this).closest('.caption').find('.popup');
});
})

How to Close toggle menu when clicking navigation item anchor link

Please see my FIDDLE
I've got a 1 page website with a "responsive" navigation menu (with anchor links to elements on the page) that prepends to a menu icon when the browser viewport is smaller than a specific width (in my case 767px) using this javascript:
jQuery(document).ready(function($){
$('#menu_wrapper').prepend('<div id="menu-icon">Menu</div>');
$("#menu-icon").on("click", function(){
$("#menu").slideToggle();
$(this).toggleClass("active");
});
});
As you can see in the fiddle I'm also using javascript to make the navigation sticky when scrolling down past navigation element regardless of the viewport size.
Now the problem I have is that when I am below the viewport of 767px, I click on the toggle 'MENU' button to open / show the navigation and when I click an option in the menu, the page scrolls to the correct part of the page BUT the menu stays open.
What I want is the menu to close (slide back up) when an option is clicked in the menu (obviously this must only apply when I am below below the viewport of 767px).
How can I do this?
$('#menu li a').on("click", function(){
$('#menu').slideUp();
});
just slideUp() if #menu li a is clicked
updated jsFiddle: http://jsfiddle.net/ayhpp8ax/1/
Just add this in $(document).ready function
$('#menu li').on('click', function(){
$("#menu").hide();
$("#menu-icon").removeClass("active");
});
(function($) {
$.fn.menumaker = function(options) {
var cssmenu = $(this), settings = $.extend({
title: "Menu",
format: "dropdown",
sticky: false
}, options);
return this.each(function() {
cssmenu.prepend('<div id="menu-button">' + settings.title + '</div>');
$(this).find("#menu-button").on('click', function(){
$(this).toggleClass('menu-opened');
var mainmenu = $(this).next('ul');
if (mainmenu.hasClass('open')) {
mainmenu.hide().removeClass('open');
}
else {
mainmenu.show().addClass('open');
if (settings.format === "dropdown") {
mainmenu.find('ul').show();
}
}
});
cssmenu.find('li ul').parent().addClass('has-sub');
multiTg = function() {
cssmenu.find(".has-sub").prepend('<span class="submenu-button"></span>');
cssmenu.find('.submenu-button').on('click', function() {
$(this).toggleClass('submenu-opened');
if ($(this).siblings('ul').hasClass('open')) {
$(this).siblings('ul').removeClass('open').hide();
}
else {
$(this).siblings('ul').addClass('open').show();
}
});
};
if (settings.format === 'multitoggle') multiTg();
else cssmenu.addClass('dropdown');
if (settings.sticky === true) cssmenu.css('position', 'fixed');
resizeFix = function() {
if ($( window ).width() > 1500) {
cssmenu.find('ul').show();
}
if ($(window).width() <= 900) {
cssmenu.find('ul').hide().removeClass('open');
}
};
resizeFix();
return $(window).on('resize', resizeFix);
});
};
})(jQuery);
(function($){
$(document).ready(function(){
$("#cssmenu").menumaker({
title: "Menu",
format: "multitoggle"
});
});
})(jQuery);

Detect window width on the fly in jQuery

I am using a template and it come with a jQuery function to detect the window width, but it only works if you open the window up or refresh the page, not when you adjust the window width.. From what IU have read I need to integrate the resize function into my codebase
$(window).resize(function()
but as my jQuery is limited I'm not sure how to put it in this script
var ww = $(window).width();
/* Menu */
$(document).ready(function() {
"use strict";
$('body').find("#mainmenu li a").each(function() {
if ($(this).next().length > 0) {
$(this).addClass("parent");
}
});
$('body').find(".toggleMenu").click(function(e) {
e.preventDefault();
$(this).toggleClass("active");
$('body').find("#mainmenu").toggle();
});
adjustMenu();
});
$(window).load(function () {
$('body').find("#mainmenu").css('pointer-events', 'auto');
});
var adjustMenu = function() {
"use strict";
if (ww < 900) {
$('body').find(".toggleMenu").css("display", "inline-block");
if (!$('body').find(".toggleMenu").hasClass("active")) {
$('body').find("#mainmenu").hide();
} else {
$('body').find("#mainmenu").show();
}
$('body').find("#mainmenu li").unbind('mouseenter mouseleave');
$('body').find("#mainmenu li a.parent").unbind('click').bind('click', function(e) {
e.preventDefault();
$(this).parent("li").toggleClass("hover");
});
}
else if (ww >= 900) {
$('body').find(".toggleMenu").css("display", "none");
$('body').find("#mainmenu").show();
$('body').find("#mainmenu li").removeClass("hover");
$('body').find("#mainmenu li a").unbind('click');
$('body').find("#mainmenu li").unbind('mouseenter mouseleave').bind('mouseenter mouseleave', function() {
$(this).toggleClass('hover');
$(this).toggleClass('activelink');
$(this).find("ul").toggleClass('animatedfast');
$(this).find("ul").toggleClass('fadeInUp');
});
$('body').find("#mainmenu ul li").unbind('mouseenter mouseleave').bind('mouseenter mouseleave', function() {
$(this).toggleClass('hover');
$(this).find("ul li").toggleClass('animatedfast');
$(this).find("ul li").toggleClass('fadeInLeft');
});
}
};
I can see that the logic is taking place in the adjustMenu function, so would I wrap that in the resize function?
Maybe I'm missing something obvious, but why not pull the whole thing out of
$(document).ready ()
Place it in a function
Function doAllOfThis (
//do everything
);
And then call it on document ready?
$(document).ready(function ({
doAllOfThis();
});
$(widow).resize (function ({
doAllOfThis();
});
I don't see anything that would be an issue. But you could just extract the code with "if ww =" conditions and move that to a function, then do as above with the function.
BETTER SOLUTION
Just noticed the
adjustMenu();
Function is already set for you, so add
$(window).resize(function({
var ww = $(window).width();
adjustMenu();
});
Utilize the resize event.
$(window).resize(function() {
var ww = $(window).width(); // will contain width after resize
// your adjust logic here
});

Executing different jQuery on browser size (hover vs click)

In my main nav I have a series of submenus. My issue is that on regular browser size I need the menu to open on a hover and on a mobile view I need it to open on a click. I have jQuery that works however I cant turn off the hover on mobile and the click on regular view
HTML
<ul class="mainMenu">
<li>
ITEM
<ul class="subMenu">
<li></li>
</ul>
</li>
</ul>
jQuery (code works but cant turn off on mobile/regular view)
$(document).ready(function () {
$('.mainMenu li').hover(function () {
$(this).find('.subMenu').stop().fadeIn();
}, function () {
$(this).find('.subMenu').stop().fadeOut();
});
$('.mainMenu li').click(function () {
$(this).find('.subMenu').stop().slideToggle();
});
});
** ALSO TRIED ** (targeting browser size, code doesnt work anymore)
var $browserWidth = window.innerWidth || document.documentElement.clientWidth;
if ($browserWidth > 768) {
$('.mainMenu li').hover(function () {
$(this).find('.subMenu').stop().fadeIn();
}, function () {
$(this).find('.subMenu').stop().fadeOut();
});
} else if($browserWidth < 768) {
$('.mainMenu li').click(function () {
$(this).find('.subMenu').stop().slideToggle();
});
}
Check out this link.
It details how you can use media queries in JavaScript.
Basically, there's a matchMedia() function whose matches property will return a boolean when you pass it a css media query.
So in your case:
if(window.matchMedia("(min-width: 768px)").matches){
//your desktop code
}
else{
//your mobile code.
}
#Ed Hinchcliffe got me on the right track... this is the answer that ended up working
$(document).ready(function () {
menuStuff();
});
$(window).resize(function () {
menuStuff();
});
function menuStuff() {
var $browserWidth = window.innerWidth || document.documentElement.clientWidth;
if ($browserWidth > 768) {
$('.mainMenu > li').unbind().bind({
mouseenter: function (e) {
$(this).find('.subMenu').stop().fadeIn();
},
mouseleave: function (e) {
$(this).find('.subMenu').stop().fadeOut();
}
})
} else {
$('.mainMenu > li').unbind().click(function () {
$(this).find('.subMenu').stop().slideToggle();
});
}
}

Responsive Button using jquery and css

I have a div with a heading using and i have a Vertical Navigation menu in same div.
To make it responsive i use media query and "Display:none and position:abolute" to Navigation Container.
it works perfectly fine till this step.
NOW what i want is that. when i click this heading the the Navigation menu appears and when i click a Link on the Navigation Menu disappears means the menu itself become"Display:none"
I used .toggle() jquery to achieve this.
when this works perfectly fine.
but problem is that i want that this .toggle() function not to work when the width of window is more then 980px;
<h2 id="heading"><span>Office<span class="blue">Managnment</span></span></h2>
<ul id="list">
<li>P</li>
<li>A</li>
<li>N</li>
<li>L</li>
<li>A</li>
<li>R</li>
<li>P</li>
</ul>
and javascript
$(function () {
$("#heading").click(function () {
$("#list").toggle();
});
$("#list").click(function () {
$("#list").toggle('hide');
});
});
and yes i tried if statement to execute this code only when the width is less then 980px but problem is that it only check for width when the page load. i.e if the window is less then 980 on load. script works fine. but when window is more then 980 on load the script do not work even on resizing it to less then 980px.
i dont understand how to achieve this. mainly problem in choosing the condition for the the if else statement.
load the window and check the width
if it is less then 980px execute the script
if it is more then 980 do not execute the script.
on resize of the window check the new width
if it was more then 980 previously
check if the width increased. if it is increased do nothing(script should not work)
check if the width is now less then 980 . START the script.Script should work now.
if it was less then 980 previosly.
check if the width increased more then 980. if it is increased STOP the script. it should not work now
check if the width is now less then 980 . Do nothing. Script should work now.
IN SHORT turn on the toggle function when width less then 980px. and turn the toggle off and set to show when width is more then 980px.
I figured it out as below. It works, but sometimes when i resize slowly it behave strangely.
var $window = $(window),
ONLOADtoggleEnabled = false,
smallscreenbefore = false;
$window.on('resize', function() {
if (smallscreenbefore == false && $window.width() > 1220) {
} else if( smallscreenbefore == false && $window.width() < 1220) {
$( "#Tablist" ).hide(400);
$( "#heading" ).click(function() {
$( "#Tablist" ).toggle(400);
});
$( "#Tablist" ).click(function() {
$( "#Tablist" ).toggle(400);
});
smallscreenbefore = true;
}
else if(smallscreenbefore == true && $window.width() > 1220 ) {
$( "#heading" ).unbind('click');
$( "#Tablist" ).unbind('click');
$( "#Tablist" ).show(400);
smallscreenbefore = false;
}
else if(smallscreenbefore == true && $window.width() < 1220 ) {
smallscreenbefore = false;
}
});
var $window = $(window);
$window.on('load', function() {
if ($window.width() < 1220) {
$( "#heading" ).click(function() {
$( "#Tablist" ).toggle(400);
});
$( "#Tablist" ).click(function() {
$( "#Tablist" ).toggle(400);
});
smallscreenbefore = true;
}
else if($window.width() > 1220) {
smallscreenbefore = false;
}
});
You can listen for the resize event on the window and then use the width to decide what you want to do. I suppose something like this should work:
var MAX_WIDTH = 980,
$window = $(window),
toggleEnabled = false;
$window.on('resize', function() {
// Check window width and check if toggle isn't already enabled
if ($window.width() < MAX_WIDTH) {
// Check if toggle isn't enabled yet
if (!toggleEnabled) {
// Use on() to add eventListener
$("#heading").on('click', function () {
$("#list").toggle();
});
$("#list").on('click', function () {
$("#list").toggle('hide');
});
toggleEnabled = true;
}
} else if (toggleEnabled) {
// Use off() to remove eventListener
$("#heading").off('click');
$("#list").off('click');
// Show the list
$('#list').show();
toggleEnabled = false;
}
$('#output').text('Width: ' + $window.width() + ', toggleEnabled: ' + toggleEnabled);
});
// You can trigger the resize event at the start to set the initial state of the menu
$window.trigger('resize');
Working version with your list: http://jsfiddle.net/srm6p/3/

Categories