init
This commit is contained in:
parent
06f61d8ce8
commit
f301cb744d
2271 changed files with 103162 additions and 0 deletions
131
02-ui/05-widgets/06-widget-tasks/09-hover-menu-onclick/solution/menu.js
Executable file
131
02-ui/05-widgets/06-widget-tasks/09-hover-menu-onclick/solution/menu.js
Executable file
|
@ -0,0 +1,131 @@
|
|||
function Menu(options) {
|
||||
var elem = options.elem;
|
||||
var self = this;
|
||||
|
||||
var activeLi;
|
||||
|
||||
elem.on('click', 'a.title', onTitleClick);
|
||||
|
||||
// item clicks are all inside ol
|
||||
elem.on('click', 'ol a', onLiClick);
|
||||
|
||||
// I use "a" here instead of LI, because hover on LI also works if going over it's child container OL
|
||||
// child container may have paddings etc, so the click may happen on that OL, outside of this item
|
||||
elem.on('hoverintent', 'ol a', onLiHoverIntent);
|
||||
|
||||
// ----------------------
|
||||
|
||||
function onLiClick(e) {
|
||||
|
||||
close();
|
||||
|
||||
var li = $(e.currentTarget).closest('li');
|
||||
|
||||
$(self).triggerHandler({
|
||||
type: 'select',
|
||||
value: getLiValue(li)
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function onTitleClick() {
|
||||
if (elem.hasClass('open')) {
|
||||
close();
|
||||
} else {
|
||||
open();
|
||||
}
|
||||
}
|
||||
|
||||
function onLiHoverIntent(e) {
|
||||
var li = $(this).closest('li');
|
||||
|
||||
if (isActiveLi(li)) return;
|
||||
|
||||
activateLi(li);
|
||||
openChildren();
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
|
||||
function isActiveLi(li) {
|
||||
if (activeLi && activeLi[0] == li[0]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function close(argument) {
|
||||
|
||||
elem.removeClass('open');
|
||||
|
||||
if (activeLi) {
|
||||
activeLi.parentsUntil(elem).andSelf().removeClass('active');
|
||||
activeLi = null;
|
||||
}
|
||||
|
||||
$(document).off('.menu-nested');
|
||||
}
|
||||
|
||||
function getLiValue(li) {
|
||||
if (!li.length) return null;
|
||||
return li.children('a').attr('href').slice(2);
|
||||
}
|
||||
|
||||
function open() {
|
||||
|
||||
elem.addClass('open');
|
||||
|
||||
// TODO: close menu on document click outside of it
|
||||
$(document).on('click.menu-nested', function(e) {
|
||||
if ( $(e.target).closest(elem).length ) return;
|
||||
close();
|
||||
});
|
||||
}
|
||||
|
||||
function getParentLi(li) {
|
||||
return li.parent().parent();
|
||||
}
|
||||
|
||||
function activateLi(li) {
|
||||
|
||||
if (activeLi && getParentLi(li)[0] != activeLi[0]) { // if (new li is not child of activeLi)
|
||||
// not a child item, then need to close currently active ones
|
||||
// collapse parents of last active until container of new element
|
||||
collapseActiveUntil(li);
|
||||
}
|
||||
|
||||
activeLi = li;
|
||||
activeLi.addClass("active");
|
||||
}
|
||||
|
||||
function collapseActiveUntil(li) {
|
||||
|
||||
var el = activeLi;
|
||||
for(;;) {
|
||||
el.removeClass('active');
|
||||
if (el[0].parentNode == li[0].parentNode) break;
|
||||
el = getParentLi(el);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function openChildren() {
|
||||
var subcontainer = activeLi.children('ol');
|
||||
if (!subcontainer.length) return;
|
||||
|
||||
// show children
|
||||
|
||||
var left = activeLi.width(); // to the right of the parent
|
||||
var top = activeLi.position().top; // at same height as current parent
|
||||
|
||||
// lift it up, so that first subchild will be aligned with the parent
|
||||
top -= subcontainer.children('li').position().top;
|
||||
top -= subcontainer.prop('clientTop')
|
||||
|
||||
subcontainer.css({
|
||||
left: left,
|
||||
top: top
|
||||
})
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue