vendor: 5,620 bytes, lines 1-180
1/** 2 * jQuery.menuAim 3 * ãã¼ãã¼ãæä½ã§ããããã«ã«ã¹ã¿ãã¤ãºæ¸ã¿ï¼JIS X 8341-3 ã«å¯¾å¿ï¼ 4 * menu-aim is a jQuery plugin for dropdown menus that can differentiate 5 * between a user trying hover over a dropdown item vs trying to navigate into 6 * a submenu's contents. 7 * 8 * menu-aim assumes that you have are using a menu with submenus that expand 9 * to the menu's right. It will fire events when the user's mouse enters a new 10 * dropdown item *and* when that item is being intentionally hovered over. 11 * 12 * __________________________ 13 * | Monkeys >| Gorilla | 14 * | Gorillas >| Content | 15 * | Chimps >| Here | 16 * |___________|____________| 17 * 18 * In the above example, "Gorillas" is selected and its submenu content is 19 * being shown on the right. Imagine that the user's cursor is hovering over 20 * "Gorillas." When they move their mouse into the "Gorilla Content" area, they 21 * may briefly hover over "Chimps." This shouldn't close the "Gorilla Content" 22 * area. 23 * 24 * This problem is normally solved using timeouts and delays. menu-aim tries to 25 * solve this by detecting the direction of the user's mouse movement. This can 26 * make for quicker transitions when navigating up and down the menu. The 27 * experience is hopefully similar to amazon.com/'s "Shop by Department" 28 * dropdown. 29 * 30 * Use like so: 31 * 32 * $("#menu").menuAim({ 33 * activate: $.noop, // fired on row activation 34 * deactivate: $.noop // fired on row deactivation 35 * }); 36 * 37 * ...to receive events when a menu's row has been purposefully (de)activated. 38 * 39 * The following options can be passed to menuAim. All functions execute with 40 * the relevant row's HTML element as the execution context ('this'): 41 * 42 * .menuAim({ 43 * // Function to call when a row is purposefully activated. Use this 44 * // to show a submenu's content for the activated row. 45 * activate: function() {}, 46 * 47 * // Function to call when a row is deactivated. 48 * deactivate: function() {}, 49 * 50 * // Function to call when mouse enters a menu row. Entering a row 51 * // does not mean the row has been activated, as the user may be 52 * // mousing over to a submenu. 53 * enter: function() {}, 54 * 55 * // Function to call when mouse exits a menu row. 56 * exit: function() {}, 57 * 58 * // Selector for identifying which elements in the menu are rows 59 * // that can trigger the above events. Defaults to "> li". 60 * rowSelector: "> li", 61 * 62 * // You may have some menu rows that aren't submenus and therefore 63 * // shouldn't ever need to "activate." If so, filter submenu rows w/ 64 * // this selector. Defaults to "*" (all elements). 65 * submenuSelector: "*", 66 * 67 * // Direction the submenu opens relative to the main menu. Can be 68 * // left, right, above, or below. Defaults to "right". 69 * submenuDirection: "right" 70 * }); 71 * 72 * https://github.com/kamens/jQuery-menu-aim 73*/ 74(function($) { 75 76 $.fn.menuAim = function(opts) { 77 // Initialize menu-aim for all elements in jQuery collection 78 this.each(function() { 79 init.call(this, opts); 80 }); 81 82 return this; 83 }; 84 85 function init(opts) { 86 var $menu = $(this), 87 activeRow = null, 88 mouseLocs = [], 89 lastDelayLoc = null, 90 timeoutId = null, 91 options = $.extend({ 92 rowSelector: "> ul > li", 93 rowSelectorKeyboard: "> ul > li > a", /* ã¢ã¯ã»ã·ããªãã£ã®ããããã¼ãã¼ãæä½ã«å¯¾å¿ */ 94 submenuSelector: "*", 95 submenuDirection: "below", 96 tolerance: 75, // bigger = more forgivey when entering submenu 97 enter: $.noop, 98 exit: $.noop, 99 activate: $.noop, 100 deactivate: $.noop, 101 exitMenu: $.noop 102 }, opts); 103 104 var MOUSE_LOCS_TRACKED = 3, // number of past mouse locations to track 105 DELAY = 300; // ms delay when user appears to be entering submenu 106 107 /** 108 * Keep track of the last few locations of the mouse. 109 */ 110 var mousemoveDocument = function(e) { 111 mouseLocs.push({x: e.pageX, y: e.pageY}); 112 113 if (mouseLocs.length > MOUSE_LOCS_TRACKED) { 114 mouseLocs.shift(); 115 } 116 }; 117 118 /** 119 * Cancel possible row activations when leaving the menu entirely 120 */ 121 var mouseleaveMenu = function() { 122 if (timeoutId) { 123 clearTimeout(timeoutId); 124 } 125 126 // If exitMenu is supplied and returns true, deactivate the 127 // currently active row on menu exit. 128 if (options.exitMenu(this)) { 129 if (activeRow) { 130 options.deactivate(activeRow); 131 } 132 133 activeRow = null; 134 } 135 }; 136 137 /** 138 * Trigger a possible row activation whenever entering a new row. 139 */ 140 var mouseenterRow = function() { 141 if (timeoutId) { 142 // Cancel any previous activation delays 143 clearTimeout(timeoutId); 144 } 145 146 options.enter(this); 147 possiblyActivate(this); 148 }, 149 mouseleaveRow = function() { 150 options.exit(this); 151 if (!activationDelay) { 152 options.deactivate(this); 153 } 154 }; 155 156 /* 157 * Immediately activate a row if the user clicks on it. 158 var clickRow = function() { 159 activate(this); 160 }; 161 */ 162 /** 163 * Activate a menu row. 164 */ 165 var activate = function(row) { 166 if (row == activeRow || activeRow) { 167 options.deactivate(activeRow); 168 } 169 170 171 options.activate(row); 172 activeRow = row; 173 }; 174 175 /** 176 * Possibly activate a menu row. If mouse movement indicates that we 177 * shouldn't activate yet because user may be trying to enter 178 * a submenu's content, then delay and check again later. 179 */ 180 var possiblyActivate = function(row) {
181 var delay = activationDelay(); 182 if (delay) { 183 timeoutId = setTimeout(function() { 184 possiblyActivate(row); 185 }, delay); 186 } else { 187 activate(row); 188 } 189 }; 190 191 /** 192 * Return the amount of time that should be used as a delay before the 193 * currently hovered row is activated. 194 * 195 * Returns 0 if the activation should happen immediately. Otherwise, 196 * returns the number of milliseconds that should be delayed before 197 * checking again to see if the row should be activated. 198 */ 199 var activationDelay = function() { 200 if (!activeRow || !$(activeRow).is(options.submenuSelector)) { 201 // If there is no other submenu row already active, then 202 // go ahead and activate immediately. 203 return 0; 204 } 205 206 var offset = $menu.offset(), 207 upperLeft = { 208 x: offset.left, 209 y: offset.top - options.tolerance 210 }, 211 upperRight = { 212 x: offset.left + $menu.outerWidth(), 213 y: upperLeft.y 214 }, 215 lowerLeft = { 216 x: offset.left, 217 y: offset.top + $menu.outerHeight() + options.tolerance 218 }, 219 lowerRight = { 220 x: offset.left + $menu.outerWidth(), 221 y: lowerLeft.y 222 }, 223 loc = mouseLocs[mouseLocs.length - 1], 224 prevLoc = mouseLocs[0]; 225 226 if (!loc) { 227 return 0; 228 } 229 230 if (!prevLoc) { 231 prevLoc = loc; 232 } 233 234 if (prevLoc.x < offset.left || prevLoc.x > lowerRight.x || 235 prevLoc.y < offset.top || prevLoc.y > lowerRight.y) { 236 // If the previous mouse location was outside of the entire 237 // menu's bounds, immediately activate. 238 return 0; 239 } 240 241 if (lastDelayLoc && 242 loc.x == lastDelayLoc.x && loc.y == lastDelayLoc.y) { 243 // If the mouse hasn't moved since the last time we checked 244 // for activation status, immediately activate. 245 return 0; 246 } 247 248 // Detect if the user is moving towards the currently activated 249 // submenu. 250 // 251 // If the mouse is heading relatively clearly towards 252 // the submenu's content, we should wait and give the user more 253 // time before activating a new row. If the mouse is heading 254 // elsewhere, we can immediately activate a new row. 255 // 256 // We detect this by calculating the slope formed between the 257 // current mouse location and the upper/lower right points of 258 // the menu. We do the same for the previous mouse location. 259 // If the current mouse location's slopes are 260 // increasing/decreasing appropriately compared to the 261 // previous's, we know the user is moving toward the submenu. 262 // 263 // Note that since the y-axis increases as the cursor moves 264 // down the screen, we are looking for the slope between the 265 // cursor and the upper right corner to decrease over time, not 266 // increase (somewhat counterintuitively). 267 function slope(a, b) { 268 return (b.y - a.y) / (b.x - a.x); 269 }; 270 271 var decreasingCorner = upperRight, 272 increasingCorner = lowerRight; 273 274 // Our expectations for decreasing or increasing slope values 275 // depends on which direction the submenu opens relative to the 276 // main menu. By default, if the menu opens on the right, we 277 // expect the slope between the cursor and the upper right 278 // corner to decrease over time, as explained above. If the 279 // submenu opens in a different direction, we change our slope 280 // expectations. 281 if (options.submenuDirection == "left") { 282 decreasingCorner = lowerLeft; 283 increasingCorner = upperLeft; 284 } else if (options.submenuDirection == "below") { 285 decreasingCorner = lowerRight; 286 increasingCorner = lowerLeft; 287 } else if (options.submenuDirection == "above") { 288 decreasingCorner = upperLeft; 289 increasingCorner = upperRight; 290 } 291 292 var decreasingSlope = slope(loc, decreasingCorner), 293 increasingSlope = slope(loc, increasingCorner), 294 prevDecreasingSlope = slope(prevLoc, decreasingCorner), 295 prevIncreasingSlope = slope(prevLoc, increasingCorner); 296 297 if (decreasingSlope < prevDecreasingSlope && 298 increasingSlope > prevIncreasingSlope) { 299 // Mouse is moving from previous location towards the 300 // currently activated submenu. Delay before activating a 301 // new menu row, because user may be moving into submenu. 302 lastDelayLoc = loc; 303 return DELAY; 304 } 305 306 lastDelayLoc = null; 307 return 0; 308 }; 309 310 /** 311 * Hook up initial menu events 312 */ 313 $menu 314 .mouseleave(mouseleaveMenu) 315 .find(options.rowSelector) 316 .mouseenter(mouseenterRow) 317 .mouseleave(mouseleaveRow); 318// .click(clickRow); 319 320 /** 321 * ã¢ã¯ã»ã·ããªãã£ã®ããããã¼ãã¼ãæä½ã«å¯¾å¿ãã 322 */ 323 $menu 324 .find( options.rowSelectorKeyboard ) 325 .focus( mouseenterRow ); 326 /** 327 * menu-aim ã¯ããã¼ãã¼ãæä½ã§ rowSelector é åããåºãã¨ãã«ã¤ãã³ããçºçããªã 328 * ãã®ãããããã®ç«¯ã¾ã§ãã¼ãã¼ãã§ããã¨ããããããã¦ã³ã¡ãã¥ã¼ãéããªãã®ã解決ãã 329 */ 330 var keyboardFocusLeave = function( event ){ /* ãã©ã¼ã«ã¹ç§»åå¾ã®ç¶æ 㯠keyup ã§ãªãã¨åå¾ã§ããªã */ 331 if( event.keyCode === 9 ){ /* Tab */ 332 if( $(activeRow).closest('li').find( event.target ).length === 0 ){ 333 options.deactivate(activeRow); 334 activeRow = null; 335 } 336 } 337 }; 338 $( document ).on( 'keyup', keyboardFocusLeave ); 339 340 341 342 $(document).mousemove(mousemoveDocument); 343 344 }; 345})(jQuery); 346 347 348$(function(){ 349 350 if( ( document.OBSJL.utility.getDevice !== 'tab' ) && ( document.OBSJL.utility.getDevice !== 'sp' ) ){ /* 'sp' ã¯ã¹ãããããPCçã表示ãããã¨ãã®ãã */ 351 352 /* 353 * ã¢ã¯ã»ã·ããªãã£ã®ããããã¼ãã¼ãã§ãåä½ããããã«è¨å®ããï¼ 354 * rowSelector 㨠rowSelectorKeyboard: ãã¦ã¹ã¯ãããã¯è¦ç´ ã§èµ·åãããããã¼ãã¼ãã¯ãã¼ãã¼ããã©ã¼ã«ã¹ãå½ããè¦ç´ ã§ãªãã¨èµ·åã§ããªãã両æ¹ã§åãããã«ããã 355 * activate: ãã¦ã¹ã¨ãã¼ãã¼ãã§DOMã®èµ·ç¹ãç°ãªãã®ã§ãclosest()ã§ãã¤ãããï¼ä»¥ä¸
355åãï¼ 356 * deactivate: deactivateã¯ã次ã¾ãã¯åã®ã¡ãã¥ã¼ã«ãã¼ãã¼ããã©ã¼ã«ã¹ãç§»ã£ãã¨ãã«èµ·åããã 357 * exit: exitã¯ãã¼ãã¼ãæä½ã§ã¯çºçããªããéã«ããã¨ããã¼ãã¼ãæä½ã§åºããã¡ãã¥ã¼ã¯deactivateã§ãªãã¨éããªãã 358 */ 359 360 $('#header-global-nav').menuAim({ 361 rowSelector: '.global-li', 362 rowSelectorKeyboard : '.global-li > .static > a', 363 activate: function(row){ $(row).closest('.global-li').find('.dropdown').show(); }, 364 deactivate: function(row){ $(row).closest('.global-li').find('.dropdown').hide(); }, 365 exit: function(row){ $(row).closest('.global-li').find('.dropdown').hide(); } 366 }); 367 368 $('#header-local-nav').menuAim({ 369 rowSelector: '.local-li', 370 rowSelectorKeyboard : '.local-li > .static > a', 371 activate: function(row){ $(row).closest('.local-li').find('.dropdown').show(); }, 372 deactivate: function(row){ $(row).closest('.local-li').find('.dropdown').hide(); }, 373 exit: function(row){ $(row).closest('.local-li').find('.dropdown').hide(); } 374 }); 375 376 } 377 378});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.