Skip to content

Commit 4018f15

Browse files
author
Ben Kamens
committed
initial commit of plugin and test file
1 parent 0df54e6 commit 4018f15

File tree

2 files changed

+216
-0
lines changed

2 files changed

+216
-0
lines changed

jquery.menu-aim.js

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/**
2+
* STOPSHIP(kamens)
3+
*/
4+
(function($) {
5+
$.fn.menuAim = function(opts) {
6+
7+
// STOPSHIP
8+
var $menu = $(this),
9+
activeRow = null,
10+
mouseLocs = [],
11+
lastDelayLoc = null,
12+
timeoutId = null,
13+
options = $.extend({
14+
tolerance: 50, // STOPSHIP
15+
enter: $.noop,
16+
exit: $.noop,
17+
activate: $.noop,
18+
deactivate: $.noop
19+
}, opts);
20+
21+
var MOUSE_LOCS_TRACKED = 4, // STOPSHIP
22+
DELAY = 300; // STOPSHIP
23+
24+
/**
25+
* STOPSHIP
26+
*/
27+
var mousemove = function(e) {
28+
mouseLocs.push({x: e.pageX, y: e.pageY});
29+
30+
if (mouseLocs.length > MOUSE_LOCS_TRACKED) {
31+
// STOPSHIP
32+
mouseLocs.shift();
33+
}
34+
},
35+
mouseenter = function() {
36+
// STOPSHIP remove?
37+
},
38+
mouseleave = function() {
39+
// STOPSHIP remove?
40+
if (timeoutId) {
41+
clearTimeout(timeoutId);
42+
}
43+
};
44+
45+
/**
46+
* STOPSHIP
47+
*/
48+
var mouseenterRow = function() {
49+
if (timeoutId) {
50+
clearTimeout(timeoutId);
51+
}
52+
53+
options.enter(this);
54+
possiblyActivate(this);
55+
},
56+
mouseleaveRow = function() {
57+
options.exit(this);
58+
};
59+
60+
/**
61+
* STOPSHIP
62+
*/
63+
var activate = function(row) {
64+
if (activeRow) {
65+
options.deactivate(activeRow);
66+
}
67+
68+
options.activate(row);
69+
activeRow = row;
70+
},
71+
possiblyActivate = function(row) {
72+
var delay = activationDelay();
73+
74+
if (delay) {
75+
timeoutId = setTimeout(function() {
76+
possiblyActivate(row)
77+
}, delay);
78+
} else {
79+
activate(row);
80+
}
81+
},
82+
activationDelay = function() {
83+
var offset = $menu.offset(),
84+
upperRight = {
85+
x: offset.left + $menu.outerWidth(),
86+
y: offset.top - options.tolerance
87+
},
88+
lowerRight = {
89+
x: offset.left + $menu.outerWidth(),
90+
y: offset.top + $menu.outerHeight() + options.tolerance
91+
},
92+
loc = mouseLocs[mouseLocs.length - 1],
93+
prevLoc = mouseLocs[0];
94+
95+
if (!loc) {
96+
// STOPSHIP
97+
return 0;
98+
}
99+
100+
if (!prevLoc) {
101+
// STOPSHIP
102+
prevLoc = loc;
103+
}
104+
105+
if (lastDelayLoc &&
106+
loc.x == lastDelayLoc.x && loc.y == lastDelayLoc.y) {
107+
// STOPSHIP
108+
return 0;
109+
}
110+
111+
// STOPSHIP -- how all this works
112+
function slope(a, b) {
113+
return (b.y - a.y) / (b.x - a.x);
114+
};
115+
116+
var upperSlope = slope(loc, upperRight),
117+
lowerSlope = slope(loc, lowerRight),
118+
prevUpperSlope = slope(prevLoc, upperRight),
119+
prevLowerSlope = slope(prevLoc, lowerRight);
120+
121+
if (upperSlope < prevUpperSlope &&
122+
lowerSlope > prevLowerSlope) {
123+
// STOPSHIP
124+
lastDelayLoc = loc;
125+
return DELAY;
126+
}
127+
128+
lastDelayLoc = null;
129+
return 0;
130+
};
131+
132+
/**
133+
* STOPSHIP
134+
*/
135+
var init = function() {
136+
$menu
137+
.mouseenter(mouseenter)
138+
.mouseleave(mouseleave)
139+
.find(options.rowSelector)
140+
.mouseenter(mouseenterRow)
141+
.mouseleave(mouseleaveRow);
142+
143+
$(document).mousemove(mousemove);
144+
};
145+
146+
init();
147+
return this;
148+
};
149+
})(jQuery);
150+

menu-aim.html

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<html>
2+
<head>
3+
<title>menu-aim jQuery plugin</title>
4+
5+
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
6+
<script type="text/javascript" src="jquery.menu-aim.js"></script>
7+
8+
<style>
9+
ul {
10+
position: absolute;
11+
top: 20px;
12+
left: 20px;
13+
height: 400px;
14+
width: 200px;
15+
border: 1px solid black;
16+
background: silver;
17+
padding: 0;
18+
margin: 0;
19+
}
20+
21+
li {
22+
display: block;
23+
width: 100%;
24+
padding: 5px;
25+
}
26+
</style>
27+
28+
<script>
29+
30+
$(function() {
31+
$("#menu").menuAim({
32+
rowSelector: "li",
33+
enter: function(row) {
34+
$(row).css("text-decoration", "underline");
35+
},
36+
exit: function(row) {
37+
$(row).css("text-decoration", "none");
38+
},
39+
activate: function(row) {
40+
console.log("ACTIVATE", row);
41+
$(row).css("background-color", "blue");
42+
},
43+
deactivate: function(row) {
44+
console.log("DEACTIVATE", row);
45+
$(row).css("background-color", "");
46+
}
47+
});
48+
});
49+
50+
</script>
51+
</head>
52+
<body>
53+
<ul id="menu">
54+
<li>Monkeys</li>
55+
<li>Gorillas</li>
56+
<li>Chimpanzees</li>
57+
<li>Giraffes</li>
58+
<li>Octopodes</li>
59+
<li>Shrimp</li>
60+
<li>Cheetah</li>
61+
<li>Porpoise</li>
62+
<li>Dolphin</li>
63+
<li>Fleetwood</li>
64+
</ul>
65+
</body>
66+
</html>

0 commit comments

Comments
 (0)