diff --git a/README.md b/README.md index cb5292c..2b7010d 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,116 @@ jQuery-menu-aim =============== -menu-aim is a jQuery plugin for dropdown menus that can differentiate +Menu-aim is a jQuery plugin for dropdown menus that can differentiate between a user trying hover over a dropdown item vs trying to navigate into -a submenu's contents. +a submenu's contents. It's originally developed by [kamens](//github.com/kamens/). +You can check out original [project](https://github.com/kamens/jQuery-menu-aim) for reference +and creation history. -[Try a demo.](https://rawgithub.com/kamens/jQuery-menu-aim/master/example/example.html) +[Try a demo.](https://rawgit.com/banesto/jQuery-menu-aim/master/advanced_example/index.html) -![Amazon screenshot](https://raw.github.com/kamens/jQuery-menu-aim/master/amazon.png) +Menu-aim tries to solve accidental sibling submenu openings by detecting the direction of +the user's mouse movement. In the image blue triangle represents a possible movement area +for mouse cursor towards submenu edges when submenu will stay open until `defaultDelay` will end. +If mouse cursor moves out of this triange, then sibling submenu will pop up. This can make +for quicker transitions when navigating up and down the menu. The experience is similar to +Amazon's "Shop by Department" dropdown. -This problem is normally solved using timeouts and delays. menu-aim tries to -solve this by detecting the direction of the user's mouse movement. This can -make for quicker transitions when navigating up and down the menu. The -experience is hopefully similar to amazon.com/'s "Shop by Department" -dropdown. +![Amazon screenshot](https://raw.github.com/banesto/jQuery-menu-aim/master/amazon.png) ## Use like so: $("#menu").menuAim({ - activate: $.noop, // fired on row activation - deactivate: $.noop // fired on row deactivation + activateCallback: $.noop, // fired on row activation + deactivateCallback: $.noop // fired on row deactivation }); -...to receive events when a menu's row has been purposefully (de)activated. +You have to create activation and deactivation functions in you own page that could simply +add 'open' class to active submenu like that: + + function activate(row) { + $(row).addClass('open'); + } + + function deactivate(row) { + $(row).removeClass('open'); + } The following options can be passed to menuAim. All functions execute with the relevant row's HTML element as the execution context ('this'): - .menuAim({ - // Function to call when a row is purposefully activated. Use this - // to show a submenu's content for the activated row. - activate: function() {}, - - // Function to call when a row is deactivated. - deactivate: function() {}, - - // Function to call when mouse enters a menu row. Entering a row - // does not mean the row has been activated, as the user may be - // mousing over to a submenu. - enter: function() {}, - - // Function to call when mouse exits a menu row. - exit: function() {}, - - // Function to call when mouse exits the entire menu. If this returns - // true, the current row's deactivation event and callback function - // will be fired. Otherwise, if this isn't supplied or it returns - // false, the currently activated row will stay activated when the - // mouse leaves the menu entirely. - exitMenu: function() {}, - - // Selector for identifying which elements in the menu are rows - // that can trigger the above events. Defaults to "> li". - rowSelector: "> li", - - // You may have some menu rows that aren't submenus and therefore - // shouldn't ever need to "activate." If so, filter submenu rows w/ - // this selector. Defaults to "*" (all elements). - submenuSelector: "*", - - // Direction the submenu opens relative to the main menu. This - // controls which direction is "forgiving" as the user moves their - // cursor from the main menu into the submenu. Can be one of "right", - // "left", "above", or "below". Defaults to "right". - submenuDirection: "right" - }); - -menu-aim assumes that you are using a menu with submenus that expand + $("#menu").menuAim({ + triggerEvent: "hover", // A means of activating submenu. + // It's either 'hover' or 'click' or 'both + rowSelector: "> li", // Selector for identifying which elements + // in the menu are rows + handle: "> a", // Handle for triggering mouse clicks on menu item + submenuSelector: "*", // You may have some menu rows that aren't submenus + // and thereforeshouldn't ever need to "activate." + // If so, filter submenu rows w/ + // this selector. Defaults to "*" (all elements). + submenuDirection: "right", // Direction the submenu opens relative to the + // main menu. Can be left, right, above, or below. + // Defaults to "right". + openClassName: "open", // Class that will be applied to menu item + // when activated + + tolerance: 75, // Bigger = more tolerant for mouse movement + // precision when entering submenu + activationDelay: 300, // Delay (ms) for first submenu opening + mouseLocsTracked: 3, // Number of past mouse locations to track direction + defaultDelay: 300, // Delay (ms) when user appears to be entering + // submenu and mouse movement is being tracked + + enterCallback: $.noop, // Function to call when mouse enters a menu row. + // Entering a row does not mean the row has been + // activated, as the user may be + // mousing over to a submenu. + activateCallback: $.noop, // Function to call when a row is purposefully + // activated. Use this to show a submenu's + // content for the activated row. + deactivateCallback: $.noop, // Function to call when a row is deactivated. + exitCallback: $.noop, // Function to call when mouse exits a menu row. + exitMenuCallback: $.noop // Function to call when mouse exits whole menu. + // This is needed for autoclosing submenu + }); + +Submenus can be placed in multiple positions relatively to main menu - `left`, `right`, `above` or `below`. +By default menu-aim assumes that you are using a menu with submenus that expand to the menu's right. It will fire events when the user's mouse enters a new -dropdown item *and* when that item is being intentionally hovered over. +menu item *and* when that item is being intentionally hovered over. + +### Changing submenu open trigger + +You can change submenu opening trigger from `hover` to `click`: + + $("#menu").('switchToClick'); + +And from `click` to `hover`: + + $("#menu").('switchToHover'); ## Want an example to learn from? -Check out example/example.html -- it has [a working dropdown for you to play with](https://rawgithub.com/kamens/jQuery-menu-aim/master/example/example.html): +[Advanced Example](https://rawgit.com/banesto/jQuery-menu-aim/master/advanced_example/index.html) of submenus opening below main menu with ability to switch opening trigger on the fly: + +![Advanced example screenshot](https://raw.github.com/banesto/jQuery-menu-aim/master/advanced_example.png) + +[Bootstrap example](https://rawgithub.com/banesto/jQuery-menu-aim/master/example/example.html) with menu-aim applied to secondary menu which opens to right: -![Example screenshot](https://raw.github.com/kamens/jQuery-menu-aim/master/example.png)
+![Example screenshot](https://raw.github.com/banesto/jQuery-menu-aim/master/example.png)
_Play with the above example full of fun monkey pictures by opening example/example.html after downloading the repo._ -## FAQ +## Features + + * UX enhancement for drop-down menus to achieve behavior when moving mouse cursor towards submenu through sibling menu item, current submenu stays open and sibling submenu does not open + * Ability to set first submenu activation delay - in case menu opening is optional and not crutial and is potentially annoying to users + * When mouse cursor leaves menu submenu autocloses (if set in 'hover' mode) + * When in 'click' mode, user can close submenu by clicking outside menu + * Ability to set whether submenu opens on 'hover' (default) or 'click' + * Ability to change submenu opening trigger on-the-fly + +## Licence + +Project lincensed under [MIT](http://en.wikipedia.org/wiki/MIT_License) license. -1. What's the license? [MIT](http://en.wikipedia.org/wiki/MIT_License). -2. Does it support horizontal menus or submenus that open to the left? Yup. Check out the submenuDirection option above. -3. I work at a big company that requires a version number on this third party code before I can use it. Do you have a version number? Sure, current version: 1.1 -4. I'm not nearly bored enough. Got anything else? [Read about this plugin's creation](http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown). diff --git a/advanced_example.png b/advanced_example.png new file mode 100644 index 0000000..3d8f4d8 Binary files /dev/null and b/advanced_example.png differ diff --git a/advanced_example/css/component.css b/advanced_example/css/component.css new file mode 100755 index 0000000..c6c27ca --- /dev/null +++ b/advanced_example/css/component.css @@ -0,0 +1,143 @@ +.cbp-hrmenu { + width: 100%; + border-bottom: 4px solid #47a3da; +} + +/* general ul style */ +.cbp-hrmenu ul { + margin: 0; + padding: 0; + list-style-type: none; +} + +/* first level ul style */ +.cbp-hrmenu > ul, +.cbp-hrmenu .cbp-hrsub-inner { + width: 90%; + max-width: 70em; + margin: 0 auto; + padding: 0 1.5em; +} + +.cbp-hrmenu > ul > li { + display: inline-block; + background-color: #efefef; +} + +.cbp-hrmenu > ul > li > a { + font-weight: 700; + padding: 1em 2em; + color: #999; + display: inline-block; +} + +.cbp-hrmenu > ul > li > a:hover { + color: #47a3da; +} + +.cbp-hrmenu > ul > li.cbp-hropen a, +.cbp-hrmenu > ul > li.cbp-hropen > a:hover { + color: #fff; + background: #47a3da; +} + +/* sub-menu */ +.cbp-hrmenu .cbp-hrsub { + display: none; + position: absolute; + background: #47a3da; + width: 100%; + left: 0; +} + +.cbp-hropen .cbp-hrsub { + display: block; + padding-bottom: 2em; +} + +.cbp-hrmenu .cbp-hrsub-inner > div { + width: 33%; + float: left; + padding: 0 2em 0; +} + +.cbp-hrmenu .cbp-hrsub-inner:before, +.cbp-hrmenu .cbp-hrsub-inner:after { + content: " "; + display: table; +} + +.cbp-hrmenu .cbp-hrsub-inner:after { + clear: both; +} + +.cbp-hrmenu .cbp-hrsub-inner > div a { + line-height: 1.5em; +} + +.cbp-hrsub h4 { + color: #afdefa; + padding: 1em 0 0.6em; + margin: 0; + font-size: 130%; + font-weight: 300; +} + +/* Examples for media queries */ + +@media screen and (max-width: 52.75em) { + + .cbp-hrmenu { + font-size: 80%; + } + +} + +@media screen and (max-width: 43em) { + + .cbp-hrmenu { + font-size: 120%; + border: none; + } + + .cbp-hrmenu > ul, + .cbp-hrmenu .cbp-hrsub-inner { + width: 100%; + padding: 0; + } + + .cbp-hrmenu .cbp-hrsub-inner { + padding: 0 2em; + font-size: 75%; + } + + .cbp-hrmenu > ul > li { + display: block; + border-bottom: 4px solid #47a3da; + } + + .cbp-hrmenu > ul > li > a { + display: block; + padding: 1em 3em; + } + + .cbp-hrmenu .cbp-hrsub { + position: relative; + } + + .cbp-hrsub h4 { + padding-top: 0.6em; + } + +} + +@media screen and (max-width: 36em) { + .cbp-hrmenu .cbp-hrsub-inner > div { + width: 100%; + float: none; + padding: 0 2em; + } +} + + + diff --git a/advanced_example/css/default.css b/advanced_example/css/default.css new file mode 100755 index 0000000..f115228 --- /dev/null +++ b/advanced_example/css/default.css @@ -0,0 +1,107 @@ +/* General Demo Style */ +@import url(//fonts.googleapis.com/css?family=Lato:300,400,700); + +body, html { font-size: 100%; padding: 0; margin: 0;} + +/* Reset */ +*, +*:after, +*:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +/* Clearfix hack by Nicolas Gallagher: http://nicolasgallagher.com/micro-clearfix-hack/ */ +.clearfix:before, +.clearfix:after { + content: " "; + display: table; +} + +.clearfix:after { + clear: both; +} + +body { + font-family: 'Lato', Calibri, Arial, sans-serif; + color: #47a3da; +} + +a { + color: #f0f0f0; + text-decoration: none; +} + +a:hover { + color: #000; +} + +h2 { + margin: 1.5em 0 0.8em; +} + +p { + margin: 0.5em 0 1em; +} + +.container > header, +.container > main { + width: 90%; + max-width: 70em; + margin: 0 auto; + padding: 1em 1.5em; +} + +.container > main a { + color: #47a3da; + text-decoration: none; + font-weight: bold; +} + +.container > main a:hover { + color: #999; +} + +.container > main a.action { + display: inline-block; + color: #fff; + text-decoration: none; + font-weight: bold; + background-color: #47a3da; + padding: 5px; + margin: 0 5px 0 0; +} + +.container > main a.action:hover { + background-color: #999; +} + +.container > main a.action.active { + border-bottom: 5px solid #000; +} + +.container > main > ul { + margin-bottom: 2em; +} + +.container > main > ul li { + font-size: 110%; + line-height: 1.6em; +} + +.container > header h1 { + font-size: 2.125em; + line-height: 1.3; + margin: 0; + /*float: left;*/ + font-weight: 400; +} + +.container > header span { + display: block; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.5em; + padding: 0 0 0.6em 0.1em; +} diff --git a/advanced_example/index.html b/advanced_example/index.html new file mode 100755 index 0000000..918b323 --- /dev/null +++ b/advanced_example/index.html @@ -0,0 +1,281 @@ + + + + + + + MenuAim advanced example + + + + + +
+
+

MenuAim jQuery plugin advanced example

+ with Responsive Horizontal Drop-Down Menu +
+
+ +
+
+

Features

+ + +

Switch submenu open trigger

+ +

+ Switch to CLICK + Switch to HOVER +

+ +

Repository

+

You can clone, download or see additional project details on https://github.com/banesto/jQuery-menu-aim.

+ +
+

Menu design by codrops

+
+
+ + + + + diff --git a/amazon.png b/amazon.png index 50a2465..eb7c79d 100644 Binary files a/amazon.png and b/amazon.png differ diff --git a/example/example.html b/example/example.html index c81ede4..4df5f18 100644 --- a/example/example.html +++ b/example/example.html @@ -23,7 +23,7 @@ -