Created
April 19, 2012 23:14
Vanilla JS Dropdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Given a list of items, adds and removes an active class as you hover over | |
* them. Used to create a dropdown menu. | |
* | |
* Copyright (c) 2012 Blake Haswell | |
* Licensed under the MIT license: http://opensource.org/licenses/MIT | |
* | |
* Example: | |
* var items = document.getElementById("dropdown").children; | |
* new Dropdown(items); | |
*/ | |
(function () { | |
"use strict"; | |
window.Dropdown = function (items) { | |
this._items = items; | |
this._initEventHandlers(); | |
}; | |
window.Dropdown.prototype = { | |
show: function (item) { | |
this._addClass(item, this._activeClass); | |
}, | |
hide: function (item) { | |
this._removeClass(item, this._activeClass); | |
}, | |
_activeClass: "active", | |
_initEventHandlers: function () { | |
var self = this; | |
for (var i = 0, l = this._items.length; i < l; ++i) { | |
var item = this._items[i]; | |
item.onmouseover = function () { | |
self.show(this); | |
}; | |
item.onmouseout = function (e) { | |
if (self._mouseHasLeftElem(e, this)) { | |
self.hide(this); | |
} | |
}; | |
} | |
}, | |
// mouseHasLeftElem function stolen from PPK, with some changes to | |
// improve readability. | |
// | |
// http://www.quirksmode.org/js/events_mouse.html | |
_mouseHasLeftElem: function (e, elem) { | |
var e = e || window.event; | |
var relatedTarget = e.relatedTarget || e.toElement; | |
// Keep moving up the DOM until we hit either the element or the body. | |
while (relatedTarget !== elem && relatedTarget.nodeName !== "BODY") { | |
relatedTarget = relatedTarget.parentNode; | |
} | |
// If we hit the element first, then the related target was a child so | |
// we haven't left the element. | |
if (relatedTarget === elem) { | |
return false; | |
} | |
return true; | |
}, | |
// Class manipulation functions stolen from Arjan Haverkamp (av01d). | |
// | |
// http://www.avoid.org/?p=78 | |
_hasClass: function (el, name) { | |
return new RegExp('(\\s|^)' + name + '(\\s|$)').test(el.className); | |
}, | |
_addClass: function (el, name) { | |
if (!this._hasClass(el, name)) { | |
el.className += (el.className ? ' ' : '') + name; | |
} | |
}, | |
_removeClass: function (el, name) { | |
if (this._hasClass(el, name)) { | |
el.className = el.className.replace(new RegExp('(\\s|^)' + name + '(\\s|$)'), ' ').replace(/^\s+|\s+$/g, ''); | |
} | |
} | |
}; | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment