Skip to content

Instantly share code, notes, and snippets.

@yratof
Last active December 18, 2015 10:40
Show Gist options
  • Save yratof/70cf499045f819a0be4e to your computer and use it in GitHub Desktop.
Save yratof/70cf499045f819a0be4e to your computer and use it in GitHub Desktop.
`Menu Aim` – Being forgiving when a user interacts with a large menu
!function(e){function t(t){var n=e(this),i=null,o=[],u=null,r=null,c=e.extend({rowSelector:"> li",submenuSelector:"*",submenuDirection:"right",tolerance:75,enter:e.noop,exit:e.noop,activate:e.noop,deactivate:e.noop,exitMenu:e.noop},t),l=3,f=300,a=function(e){o.push({x:e.pageX,y:e.pageY}),o.length>l&&o.shift()},s=function(){r&&clearTimeout(r),c.exitMenu(this)&&(i&&c.deactivate(i),i=null)},h=function(){r&&clearTimeout(r),c.enter(this),v(this)},m=function(){c.exit(this)},x=function(){y(this)},y=function(e){e!=i&&(i&&c.deactivate(i),c.activate(e),i=e)},v=function(e){var t=p();t?r=setTimeout(function(){v(e)},t):y(e)},p=function(){function t(e,t){return(t.y-e.y)/(t.x-e.x)}if(!i||!e(i).is(c.submenuSelector))return 0;var r=n.offset(),l={x:r.left,y:r.top-c.tolerance},a={x:r.left+n.outerWidth(),y:l.y},s={x:r.left,y:r.top+n.outerHeight()+c.tolerance},h={x:r.left+n.outerWidth(),y:s.y},m=o[o.length-1],x=o[0];if(!m)return 0;if(x||(x=m),x.x<r.left||x.x>h.x||x.y<r.top||x.y>h.y)return 0;if(u&&m.x==u.x&&m.y==u.y)return 0;var y=a,v=h;"left"==c.submenuDirection?(y=s,v=l):"below"==c.submenuDirection?(y=h,v=s):"above"==c.submenuDirection&&(y=l,v=a);var p=t(m,y),b=t(m,v),d=t(x,y),g=t(x,v);return d>p&&b>g?(u=m,f):(u=null,0)};n.mouseleave(s).find(c.rowSelector).mouseenter(h).mouseleave(m).click(x),e(document).mousemove(a)}e.fn.menuAim=function(e){return this.each(function(){t.call(this,e)}),this}}(jQuery);
/* Default Wordpress Navigation with Children */
.menu{
@at-root #{&}-item{
/* ... */
@at-root #{&}-has-children{
&.submenu-visible{
> .sub-menu{
display: block;
}
}
}
/* .... */
}
}
// Dependent on Menu-Aim.js in libs this function allows users to be sloppy
// with their navigation. This means they're allowed to hover over other
// items unintentionally and not be punished for it.
$( function(){
var menu = $( ".nav-menu-primary" );
menu.menuAim( {
submenuDirection: "below",
tolerance: 1,
// When the menu is entered
enter: function( a ) {
$( '.submenu-previously-visible' ).addClass( "submenu-visible" );
},
// When user moved to a parent item
activate: function( a ) {
$( a ).addClass( "submenu-visible" );
$( '.submenu-previously-visible' ).removeClass( 'submenu-previously-visible' );
},
// When user moved to another parent item
deactivate: function( a ) {
$( a ).removeClass( "submenu-visible" );
$( '.submenu-previously-visible' ).removeClass( 'submenu-previously-visible' );
},
// When user leaves the menu entirely
exitMenu: function( a ) {
$( ".submenu-visible" ).addClass( 'submenu-previously-visible' ).removeClass( "submenu-visible" );
},
} );
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment