With a Touch device, you can't "hover" over a link to activate the megamenu. Instead, you'd want to click the top-level menu link to toggle the megamenu.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

doublejosh’s picture

Issue summary: View changes

added code detail.

doublejosh’s picture

I've used Modernizr to provide some mobile functions to clean up behavior and now the larger issue is having better scope used in the MegaMenu module.
The whole js file is written in $(document).ready() when it really should be in Drupal.behaviors
Using QuickTabs as an example. Seems like functions should look more like this...

Drupal.behaviors.megamenu.megamenu_open = function(m) {

		Drupal.behaviors.megamenu.megamenu_canceltimer();

		if ($(m).hasClass('megamenu-parent-title')) {
			Drupal.behaviors.megamenu.hoverParentIdx = Drupal.behaviors.megamenu.megaParentTitles.index($(this));
		}
		else if ($(m).hasClass('megamenu-bin')) {
			Drupal.behaviors.megamenu.hoverParentIdx = Drupal.behaviors.megamenu.megaParents.index($(m).parents('.megamenu-parent'));
		}

		Drupal.behaviors.megamenu.hoverParent = Drupal.behaviors.megamenu.megaParents.eq(Drupal.behaviors.megamenu.hoverParentIdx);

		if (Drupal.behaviors.megamenu.hoverParentIdx != Drupal.behaviors.megamenu.oldParentIdx) {
			Drupal.behaviors.megamenu.megamenu_close();
			Drupal.behaviors.megamenu.megamenu_hovertimer();
		} else {
			Drupal.behaviors.megamenu.megamenu_display();
		}
};

Though it might be good to create a config object, that can be simplified within each function.

Then I believe I'll be able to access critical functions via the namespace to do some unbind and binding to mobile friendly events.
eg:

// Add mobile-friendly off trigger
$('html').bind('touchstart', function(e){
    e.stopPropagation();
    Drupal.behaviors.megamenu.megamenu_closeAll();
});
doublejosh’s picture

Priority: Major » Normal

My temporary solution was to set the scope of a function variable for megamenu_closeAll outside $(document).ready() and then redeclare the function as a var.

megamenu.js

var megamenu_closeAll;
$(document).ready(function() {
//...
	megamenu_closeAll = function () {
		if(hoverBin) hoverBin.css('top', hideOffset);
		for ( var i=0 ; i < megaParents.length ; i++ ) {
			megaParents.trigger('megamenu_close');
			megaParents.eq(i).removeClass('hovering');
		}
		oldParentIdx = -1;
	}
//...
});

Then I can use that function in my mobile only js (via modernizr addTest)

// Remove href from menu parent items.
$('#megamenu-primary-links .megamenu-parent-title a').removeAttr('href');
// Add mobile-friendly off trigger.
$('html').bind('touchstart', function(e){
    e.stopPropagation();
    megamenu_closeAll();
});

Killing off parent menu items requires that you have extra "overview" menu items that are hidden from desktop users. Something like...

$('#megamenu-primary-links .megamenu-slots-vertical  a[title="overview"]').parents('.megamenu-slot').hide();

Hope this helps someone else, and perhaps helps provide some reason for cleaning up the javascript architecture for this module.

Anonymous’s picture

Priority: Normal » Major

Agreed, the javascript is definitely in need of some over hauling.

doublejosh’s picture

Priority: Normal » Major

PS: Here is a resource about doing the iPad test inline with your binding incase you don't want to deal with Modernizr.
http://www.danwellman.co.uk/fixing-jquery-click-events-for-the-ipad/

You'll end up with something like this:

var ua = navigator.userAgent,
    event = (ua.match(/iPad/i)) ? "touchstart" : "click";
$('html').bind(event, function(e) {
    e.stopPropagation();
    megamenu_closeAll();
}

Still requires fixing the scope though.

2dareis2do’s picture

I know this is only a few days old since last post but it does sem that lack of Touch device support is going to be an issue on a site I am currently working on. I mean iPhone has been out for a while now. Does anyone know what timescale for this issue to be addressed?

There are a few other sites that suport mega-menus that seem to provide better support for touch devices that might be of some interest:

http://www.concrete5.org/marketplace/addons/mega-menu/
http://johnlewis.com

doublejosh’s picture

There's also GigaMenu, believe that works with iPad. (used it on another site.)

2dareis2do’s picture

Not sure this is the right place to post but I could not find any examples of GigaMenu to see it working on touch devices and ie6. Do you have a link to the site you worked on?

doublejosh’s picture

Turns out my solution does not work. Still searching.

2dareis2do’s picture

Gigamenu does seem to work though?!

doublejosh’s picture

Oh perhaps my version is just too old.
In case this helps someone, what finally worked for me is...

// Remove href from menu parent items.
$('#megamenu-primary-links h2.megamenu-parent-title a').removeAttr('href');

// Add mobile-friendly off trigger.
$('html').bind('touchstart', function(e){
    megamenu_closeAll();
});
$(".megamenu-menu").bind('touchstart', function(e){
    e.stopPropagation();
});;
sittard’s picture

Best solution for me based on #10 (thanks) was to add:

	// Remove href from menu parent items for mobile users
	$(".megamenu-menu").bind('touchstart', function(e){
		$('#megamenu-primary-links h2.megamenu-parent-title a').removeAttr('href');
	});

I've included this in megamenu.js around line 170.

Simply removing the href (link) allows the menu to activate. I'm not sure if this takes care of the mouseout (closing the menu), although I'm not too worried about this for mobile users (the menu fills most of the screen on an iphone).

erykmynn’s picture

For 7.x-2.x

What is the ideal UX for this? Hover is more convenient on PCs. The top level items have to be clickable in most cases, and touch users will also have to click to activate.

Some options are:

  • Arrow icon or other clickable "Drop" activator -- maybe hover still works for PC's but touch users can also click the icon
  • Double clicking (this seems like bad UI, unless there is some additional indicator)
  • Listening for different device types (might require frequent updating)
  • Listening for Hover before click vs click only (not sure if this works)
lmatthews’s picture

Version: 6.x-2.0-beta2 » 7.x-1.x-dev

Modifying #10, I included the following in megamenu.js. This should fix the scope, while allowing for parent items with no drop down to go to their respective pages:

// Remove href from menu parent items.
function megamenu_open_progress() {
if ($(this).find('ul.megamenu-bin').get(0)) {
$(this).find('h2 a').removeAttr('href');
//alert('anchor removed');
}
}

//Display dropdown
$("#megamenu-main-menu h2.megamenu-parent-title a").bind('touchstart', function(e){
if($('#megamenu-main-menu li').find('.megamenu-active')) {
$('.megamenu-parent').bind('megamenu_open', megamenu_open_progress);
$('.megamenu-parent-title').bind('touchstart', megamenu_open);
//alert('this is visible!');
} else {
$("body").bind('click', megamenu_closeAll);
$('.megamenu-parent').bind('megamenu_close', megamenu_close_progress);
//alert('this is hidden!');
}
});

// Add mobile-friendly off trigger.
$('html').bind('touchstart', function(e){
megamenu_closeAll();
oldParentIdx = -1;
});

$(".megamenu-menu").bind('touchstart', function(e){
e.stopPropagation();
});

coredumperror’s picture

I also need to make the site I'm building with Megamenu work on iPad, but my team has decided that rather than attempting to support two slightly different behaviors (hover-to-expand on desktop and click-to-expand on iPad), we'd rather just get rid of the hover functionality entirely. Thus I'm currently working on a fork of 7.x-1.x (because I can't seem to find any actual code in the 7.x-2.x branch of the git repo) which takes out the expand-on-hover functionality, replacing it with expand-and-stay-open-on-click, which I'm calling "sticky menus."

I'm posting here for two reasons:
1. Would this "sticky menus" functionality make sense (or be doable at all) as an optional mode for Megamenu?
2. Do you folks, who are much more familiar with the code than myself, have any suggestions on how best to implement this?

Anonymous’s picture

1. This is possible.
2. Add an admin option. Pass the selection as JS settings. In megamenu JS, change the event type based on the selection.

coredumperror’s picture

I'm almost done with my patch that will enable Sticky Menus (plus several other improvements like AJAX forms in the "configure mega" pages), but I've got a bit of a conundrum. My code depends on the patch submitted in #1598510: Import/Export settings (Features integration), and also includes the change I made for #1617072: Individual "configure mega" pages behave strangely. So it seems like applying a patch based on my changes would be really sketchy.

What does one do in this situation? I've never done significant work like this on a contrib module before.

Pat Redmond’s picture

coredumperror: post your patch file. Someone can always go through and select the parts they want - it doesn't ALL have to be used.

Alternatively, post a number of patch files which do one specific thing, rather than one patch file which achieves a number of things.

coredumperror’s picture

Status: Active » Needs review
FileSize
47.61 KB

In the 2 months since I posted my original intent to make a patch, I've made numerous additional alterations and improvements to Magamenu. Unfortunately, I've also completely lost track of which changes are mine and which are based on other patches that I applied. So, the attached patch is based on the 7.x-1.x branch, and it incorporates all of the differences between my currently-in-use Megamenu code, and that branch's last commit (in March).

I also make no promises that the upgrade code is perfect. I tried my best to make it look right, but I've never written upgrade scripts before, and I dont know how to test it.

Pat Redmond’s picture

Wow - there's a lot going on in there, that's for sure. I am going to run through it at some stage and pull out the bits I'm after. I will break it into a few smaller patches then.

coredumperror’s picture

Sorry it's so complicated! I'm not at all an expert in patching, or git in general, for that matter, so I have no idea how to break a patch up into different functionality changes. And I did make several significant, wide-ranging changes across pretty much the entire Megamenu code base, many of which were stylistic/best-practices changes.

MrPaulDriver’s picture

Just wondering where Megamenu is right now in terms of 'touch' suitability. I see that there is a recent Dev release and wondered whether second touch (mouseout) behaviour is now provided.

MrPaulDriver’s picture

Issue summary: View changes

cleaner text.

jessehs’s picture

Issue summary: View changes
FileSize
2.25 KB

The Modernizr javascript library can provide a lightweight means of detecting whether a device is a Touch device. This patch assumes that you have loaded the Modernizr library with a build configured for the "Misc: Touch Events" option.

The attached patch detects whether the modernizr library is included, and if the device is a Touch device, the menu triggering behavior is adjusted.

pandroid’s picture

#22 works quite well, but unfortunately it now seems to be impossible to select the root items actually on the main menu bar. Clicking on one of these items opens up the mega-menu ok, clicking on it again closes the mega menu. How can I get it to actually select the item on the bar? The only choice seems to be to hold the item selected and wait for the 'open in a new window' option to pop up.
(This is on an iPad)

ram4nd’s picture

Status: Needs review » Needs work

We would need some other way of doing this. Third library with device detection seems overkill.