I'm working within WordPress and have two menus on a mobile site using viewport media queries to control elements. When viewing the site in 768 wide two mobile menus replace the desktop. To achieve this I'm using widgets in the top left drop down with two custom menus.
The left widget drop down is a Shortcodes Unlimited shortcode embedded.
The main menu on the right is just a basic menu using jquery.dlmenu.js v1.0.1 from http://www.codrops.com.
When visiting the page you can click on the left dropdown widget and it works as expected. You can also click the right dropdown menu and it works as expected. However, once you click on the right downdown menu, you cannot click on the left dropdown widget.
mobile/jquery.dlmenu.js registers first.
shortcodes-ultimate/assets/js/other-shortcodes.js registers second.
jQuery(function($) {
$( "#dl-menu" ).dlmenu({
animationClasses : {
classin : "dl-animate-in-2", classout : "dl-animate-out-2" }
});
});
The scripts are all loaded in the footer.
There are no console errors.
http://iemajen.com/lexingtonhabitatforhumanity/
I think that the problem is in this lines in jquery.dlmenu.js file (themes/bonesv2/mobile/jquery.dlmenu.js);
// clicking somewhere else makes the menu close
$body.off( 'click' ).on( 'click.dlmenu', function() {
self._closeMenu() ;
} );
Your plugin Shortcodes Unlimited bind click listeners to body tag, which listen for the click event into .su-spoiler-title in this case. But in your jquery.dlmenu.js when you click dlmenu, it unbind all click events from body and bind its own.
So to be sure that this is the problem, try to remove this .off('click') command:
// clicking somewhere else makes the menu close
$body.on( 'click.dlmenu', function() {
self._closeMenu() ;
} );
If problem is here, you can try to unbind only 'click.dlmenu' event:
// clicking somewhere else makes the menu close
$body.off( 'click.dlmenu' ).on( 'click.dlmenu', function() {
self._closeMenu() ;
} );
P.S. You must inspect in Inspector if this will unbind properly.
Related
I have been working on this menu plugin, and its working fine, however there is one problem I've noticed, please see this JSFiddle Demo
When menu is opened, I have added a close button (x) on the top right corner of the menu, when I click on close its sliding to left and hiding but when I click on menu again its not opening but if you click once again it works perfectly.
Can somebody please guide how to make my custom close icon working perfectly, as its doing with outside menu click?
I found that on close click, its removing a class and adding inline css of translate3D which I have done same in my jquery, but no luck
Here is my close jQuery function
$(document).ready(function(){
$('.nav-close').click(function(){
$("#mp-pusher").removeClass('mp-pushed').css("transform","translate3d(0px, 0px, 0px)");
$(".mp-level").removeClass('mp-level-open');
});
});
What you want to do is keep a reference to the menu so you can close it in your event.
https://jsfiddle.net/ps855n8r/14/
var menuItem = new mlPushMenu( document.getElementById( 'mp-menu' ), document.getElementById( 'trigger' ) );
That way in your event you can close like so :
menuItem._resetMenu();
Don't try to close it manually using the DOM, which means your even function becomes like this :
$(document).ready(function(){
$('.nav-close').click(function(el){
menuItem._resetMenu();
});
});
Also helpful for calling other methods on the mlPushMenu object elsewhere. In the above example; menuItem is your reference.
I'm using angular.js to build my website, and I have an element that MOUSEOVER event is supposed to show the navbar, and on mobile, clicking on that element, supposed to show the navbar + the menu.
These two events conflict.
Any ideas?
//navbar fade in by mouse over menu button
angular.element('.picture_hamburger>.text').on('mouseover', function() {
angular.element('#navbar').stop().fadeIn();
btnState.setPosition(1);
// navbar fade out by mouse out of button
angular.element('.menu_hamburger').one('mouseout', function() {
btnState.setPosition(0);
});
});
//menu open by click
angular.element('.picture_hamburger>.text').click(function () {
angular.element('#navbar').finish().slideDown();
btnState.openMenu();
});
i finally used this:
var isTouchDevice = 'ontouchstart' in document.documentElement;
and i had a variable that checks for touch screen ability, without adding Modernizr.
If you are able to use Modernizr (js library for checking HTML5 stuff), then it provides the best method for checking if a client is mobile or not. You can do this in pure javascript too I think, but after countless tries I gave it up:
By using Modernizr.touch, you can see if the device is touch capable or not. Touch screens are quite unique to phones and pads, but unfortunately also laptops which have touchscreens (not many of these thank God).
So then the code would be like this:
//navbar fade in by mouse over menu button
angular.element('.picture_hamburger>.text').on('mouseover', function() {
if(Modernizr.touch) {
return;
}
angular.element('#navbar').stop().fadeIn();
btnState.setPosition(1);
// navbar fade out by mouse out of button
angular.element('.menu_hamburger').one('mouseout', function() {
if(Modernizr.touch) {
return;
}
btnState.setPosition(0);
});
});
//menu open by click
angular.element('.picture_hamburger>.text').click(function () {
angular.element('#navbar').finish().slideDown();
btnState.openMenu();
});
So, if its mobile and the mouseover and mouseout fires, then it just returns before executing anything - just the way you want.
Modernizr can be found at http://www.modernizr.com/
I'm building a website where some elements in the navigation menu have a submenu. These submenus are shown when the mouse hovers over the element, but of course on mobile I cannot do that since there is no actual hover. A tap means a click, and that follows the link. I hoped on a simple solution but it doesn't work on my mobile device...
Here's a code snippet inside a loop, this is a menu item (li) that contains a submenu (ul):
$(this).find("a").on("mouseenter focusin click", function(e) {
if(submenu.css("display") != "block") {
e.preventDefault(); //should work on mobile
}
submenu.stop().css('display', 'block').animate({
top: 1.2em,
opacity: 1
}, 200);
});
Now I test this in Firefox. In normal use, you cannot actually click the menu item before the submenu comes out because display becomes block as soon as the mouse hovers over it. So in web console I type in:
$("#nav > ul > li:first-child > a").click()
This gives the expected behaviour. the submenu comes out but the link isn't followed. On mobile, the link is still followed... What gives?
Update
I just entered two alert statements. One that says the event type first thing in the handler, and one that says "preventing default" just before e.preventDefault. On my mobile browser (Dolphin browser for Android) it gives the following on a tap of the menu item:
Event is mouseenter
Preventing default
Event is click
Naturally, when the first event fired is "mouseenter", the default will not be prevented for click as that is the point where the menu shows up. In other words, I would need to make sure that the first mouseenter does show the menu but a click isn't fired... I could check the top css property for that, but I wonder if there is another way.
I got it working by adding another check to see if the submenu is at the proper position, rather than using the value of display.
$(this).find("a").on("mouseenter focusin click", function(e) {
if(e.type == "click" && submenu.css("top") != "1.2em") {
e.preventDefault();
}
submenu.stop().css('display', 'block').animate({
top: 1.2em,
opacity: 1
}, 200);
});
I have created a responsive menu that breaks at 480px and below. I have it to where the following reacts if:
The user clicks on a the "Menu" link.
The menu slideToggles out.
The sub-menus slideToggle out onClick as well.
But you cannot click on any of the pages.
Does this have something to do with the return false?
You may view the example here: http://www.stlredtails.com/construction/
You may need to resize the browser at or belw 480px to see the responsive navigation in action.
Here is the jQuery for the navigation:
jQuery(".navigation ul").hide();
jQuery("#navigation").click(
function() {
jQuery(this).siblings("ul").slideToggle(150, "swing");
return false;
}
);
jQuery(".navigation > ul > li").click(
function() {
jQuery(this).children("ul").slideToggle(150, "swing");
return false;
}
);
Thank you all!
The problem comes from the return false. When you're clicking the links, you're also clicking the ancestors li and ul. Before the link "activates" the functions bound to the ancestors click event execute. Since they return false the default browser behavior (navigating away) is prevented.
There are better solutions for this kind of menu behavior, but using what you already you have (and assuming you won't be changing your html) you can simply add the following to your javascript:
$('.navigation').on('click', 'a:only-child', function(e) {
e.stopPropagation();
});
This searches for all links in the navigation menu that are the only child of their parents (which in this case, happen to be the links you want to continue working as links) and prevents the ancestors click events from executing - the return false shouldn't happen anymore.
I'm trying to figure out how to make a pop-up menu using the jQuery UI menu widget.
After searching around, I finally found the following demo that does what I want:
http://view.jqueryui.com/menubar/demos/popup/popup-menu.html
However, I am having a little trouble understanding this demo. For example:
What is making the menu hidden before any of the buttons are clicked?
What is causing the menu to close when it's open and I click somewhere else on the page?
Any help appreciated.
That demo uses a modified version of jquery.ui.menu.js along with the popup widget: http://view.jqueryui.com/menubar/ui/jquery.ui.popup.js
Menu itself, as released in 1.9, doesn't have any code for showing it as a popup. I recommend writing some custom code to build a popup menu, until a stable release offers a proper solution.
The jQuery UI Popup - Popup Menu you referenced uses unreleased code as Jörn Zaefferer said. (Notice that Jörn is the same guy that closed the bug)
But there is an almost identical-looking solution in jQuery UI Button's Split Button example that doesn't use .popup() and does all the hiding etc. explicitly.
Perhaps you could use that as a starting point instead. I know I'm going to! ;-)
I believe this may be what you're looking for. When you call .menu(), lots of things are triggered in the _create() function (as Derek said), like setting class names etc. Then, at lines 123-135 in jquery.ui.menu.js, this happens:
this.refresh();
// Clicks outside of a menu collapse any open menus
this._on( this.document, {
click: function( event ) {
if ( !$( event.target ).closest( ".ui-menu" ).length ) {
this.collapseAll( event );
}
// Reset the mouseHandled flag
mouseHandled = false;
}
});
The second part makes sure all menus are collapsed when the user clicks on the page (this.document) outside a menu (.ui-menu): this.collapseAll() is called, which calls this._close(), which in turn calls hide(). This should answer your second question.
As for your first question, The first thing the refresh() function does is:
// Initialize nested menus
var menus,
icon = this.options.icons.submenu,
submenus = this.element.find( this.options.menus + ":not(.ui-menu)" )
.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
.hide()
.attr({
role: this.options.role,
"aria-hidden": "true",
"aria-expanded": "false"
});
This finds all submenus not previously initialized (in this case all of them since we're coming from _create()) and initializes them, which includes hiding them.