📄 dommenu.js
字号:
}
var isRootLevel = in_newActiveElement.data.items['level'] == 1 ? true : false;
var closeDelay = isRootLevel ? settings.items['closeMouseoutMenuDelay'] : settings.items['closeMouseoutSubMenuDelay'];
}
else {
var isRootLevel = false;
var closeDelay = settings.items['closeMouseoutMenuDelay'];
window.status = window.defaultStatus;
}
// override the close delay with that passed in
if (typeof(in_closeDelay) != 'undefined') {
closeDelay = in_closeDelay;
}
// if there is an intersect sibling, then we need to work from there up to
// preserve the active path
if (intersectSibling) {
// only if this is not the root level to we allow the scheduled close
// events to persist...otherwise we close immediately
if (!isRootLevel) {
// toggle the sibling highlight (only one sibling highlighted at a time)
domMenu_toggleHighlight(intersectSibling, false);
}
// we are moving to another top level menu
// {!} clean this up {!}
else {
// add lingering menus outside of old active path to active path
for (var i in domMenu_timeouts['close'].items) {
if (!oldActivePath.hasItem(i)) {
var tmp_element = document.getElementById(i);
if (tmp_element.data.items['basename'] == basename) {
oldActivePath.setItem(i, tmp_element);
}
}
}
}
}
// schedule the old active path to be closed
for (var i in oldActivePath.items) {
if (newActivePath.hasItem(i)) {
continue;
}
// make sure we don't double schedule here
domMenu_cancelTimeout(i, 'close');
if (isRootLevel) {
domMenu_toggleHighlight(oldActivePath.items[i], false);
domMenu_toggleSubMenu(oldActivePath.items[i], 'hidden');
}
else {
var tmp_args = new Array();
tmp_args[0] = oldActivePath.items[i];
var tmp_function = 'domMenu_toggleHighlight(argv[0], false); domMenu_toggleSubMenu(argv[0], ' + domMenu_quote('hidden') + ');';
// if this is the top level, then the menu is being deactivated
if (oldActivePath.items[i].data.items['level'] == 1) {
tmp_function += ' domMenu_activeElement.setItem(' + domMenu_quote(basename) + ', false);';
}
domMenu_callTimeout(tmp_function, closeDelay, tmp_args, i, 'close');
}
}
return in_newActiveElement;
}
// }}}
// {{{ domMenu_deactivate()
function domMenu_deactivate(in_basename, in_delay)
{
if (!in_delay) {
in_delay = 0;
}
domMenu_changeActivePath(false, domMenu_activeElement.items[in_basename], in_delay);
}
// }}}
// {{{ domMenu_openEvent()
/**
* Handle the mouse event to open a menu
*
* When an event is received to open the menu, this function is
* called, handles reinitialization of the menu state and sets
* a timeout interval for opening the submenu (if one exists)
*/
function domMenu_openEvent(in_this, in_event, in_openDelay)
{
if (domMenu_isGecko) {
window.getSelection().removeAllRanges();
}
// setup the cross-browser event object and target
var eventObj = domMenu_isIE ? event : in_event;
var currentTarget = domMenu_isIE ? in_this : eventObj.currentTarget;
var basename = currentTarget.data.items['basename'];
// if we are moving amoungst children of the same element, just ignore event
if (eventObj.type != 'mousedown' && domMenu_getElement(eventObj[domMenu_eventFrom], basename) == currentTarget) {
return;
}
// if we click on an open menu, close it
if (eventObj.type == 'mousedown' && domMenu_activeElement.items[basename]) {
var settings = domMenu_settings.items[basename];
domMenu_changeActivePath(false, domMenu_activeElement.items[basename], currentTarget.data.items['level'] == 1 ? settings.items['closeClickMenuDelay'] : settings.items['closeClickSubMenuDelay']);
return;
}
// if this element has children, popup the child menu
if (currentTarget.data.items['numChildren']) {
// the top level menus have no delay when moving between them
// so activate submenu immediately
if (currentTarget.data.items['level'] == 1 && domMenu_activeElement.items[basename]) {
// ** I place changeActivePath() call here so the hiding of selects does not flicker **
// {!} instead I could tell changeActivePath to clear select ownership but not
// toggle visibility....hmmm....{!}
domMenu_activateSubMenu(currentTarget);
// clear the active path and initialize the new one
domMenu_activeElement.setItem(basename, domMenu_changeActivePath(currentTarget, domMenu_activeElement.items[basename]));
}
else {
// clear the active path and initialize the new one
domMenu_activeElement.setItem(basename, domMenu_changeActivePath(currentTarget, domMenu_activeElement.items[basename]));
var tmp_args = new Array();
tmp_args[0] = currentTarget;
var tmp_function = 'if (!domMenu_activeElement.items[' + domMenu_quote(basename) + ']) { domMenu_activeElement.setItem(' + domMenu_quote(basename) + ', argv[0]); } domMenu_activateSubMenu(argv[0]);';
domMenu_callTimeout(tmp_function, in_openDelay, tmp_args, currentTarget.id, 'open');
}
}
else {
// clear the active path and initialize the new one
domMenu_activeElement.setItem(basename, domMenu_changeActivePath(currentTarget, domMenu_activeElement.items[basename]));
}
}
// }}}
// {{{ domMenu_closeEvent()
/**
* Handle the mouse event to close a menu
*
* When an mouseout event is received to close the menu, this function is
* called, sets a timeout interval for closing the menu.
*/
function domMenu_closeEvent(in_this, in_event)
{
// setup the cross-browser event object and target
var eventObj = domMenu_isIE ? event : in_event;
var currentTarget = domMenu_isIE ? in_this : eventObj.currentTarget;
var basename = currentTarget.data.items['basename'];
var relatedTarget = domMenu_getElement(eventObj[domMenu_eventTo], basename);
// if the related target is not a menu element then we left the menu system
// at this point (or cannot discern where we are in the menu)
if (domMenu_activeElement.items[basename]) {
if (!relatedTarget) {
domMenu_changeActivePath(false, domMenu_activeElement.items[basename]);
}
}
// we are highlighting the top level, but menu is not yet 'active'
else {
if (currentTarget != relatedTarget) {
domMenu_cancelTimeout(currentTarget.id, 'open');
domMenu_toggleHighlight(currentTarget, false);
}
}
}
// }}}
// {{{ domMenu_getElement()
function domMenu_getElement(in_object, in_basename)
{
while (in_object) {
try {
if (in_object.id && in_object.id.search(new RegExp('^' + in_basename + '(\\[[0-9]\\])*\\[[1-9]\\]$')) == 0) {
return in_object;
}
else {
in_object = in_object.parentNode;
}
}
catch(e) {
return false;
}
}
return false;
}
// }}}
// {{{ domMenu_detectCollisions()
function domMenu_detectCollisions(in_menuObj, in_recover)
{
// no need to do anything for opera
if (domMenu_isOpera) {
return;
}
if (typeof(domMenu_selectElements) == 'undefined') {
domMenu_selectElements = document.getElementsByTagName('select');
}
// if we don't have a menu, then unhide selects
if (in_recover) {
for (var cnt = 0; cnt < domMenu_selectElements.length; cnt++) {
if (domMenu_isGecko && domMenu_selectElements[cnt].size <= 1 && !domMenu_selectElements[cnt].multiple) {
continue;
}
var thisSelect = domMenu_selectElements[cnt];
thisSelect.hideList.removeItem(in_menuObj.id);
if (!thisSelect.hideList.length) {
domMenu_selectElements[cnt].style.visibility = 'visible';
}
}
return;
}
// okay, in_menu exists, let's hunt and destroy
var menuOffsets = domMenu_getOffsets(in_menuObj);
for (var cnt = 0; cnt < domMenu_selectElements.length; cnt++) {
var thisSelect = domMenu_selectElements[cnt];
// mozilla doesn't have a problem with regular selects
if (domMenu_isGecko && thisSelect.size <= 1 && !thisSelect.multiple) {
continue;
}
// {!} make sure this hash is congruent with domTT hash {!}
if (!thisSelect.hideList) {
thisSelect.hideList = new domMenu_Hash();
}
var selectOffsets = domMenu_getOffsets(thisSelect);
// for mozilla we only have to worry about the scrollbar itself
if (domMenu_isGecko) {
selectOffsets.setItem('left', selectOffsets.items['left'] + thisSelect.offsetWidth - domMenu_scrollbarWidth);
selectOffsets.setItem('leftCenter', selectOffsets.items['left'] + domMenu_scrollbarWidth/2);
selectOffsets.setItem('radius', Math.max(thisSelect.offsetHeight, domMenu_scrollbarWidth/2));
}
var center2centerDistance = Math.sqrt(Math.pow(selectOffsets.items['leftCenter'] - menuOffsets.items['leftCenter'], 2) + Math.pow(selectOffsets.items['topCenter'] - menuOffsets.items['topCenter'], 2));
var radiusSum = selectOffsets.items['radius'] + menuOffsets.items['radius'];
// the encompassing circles are overlapping, get in for a closer look
if (center2centerDistance < radiusSum) {
// tip is left of select
if ((menuOffsets.items['leftCenter'] <= selectOffsets.items['leftCenter'] && menuOffsets.items['right'] < selectOffsets.items['left']) ||
// tip is right of select
(menuOffsets.items['leftCenter'] > selectOffsets.items['leftCenter'] && menuOffsets.items['left'] > selectOffsets.items['right']) ||
// tip is above select
(menuOffsets.items['topCenter'] <= selectOffsets.items['topCenter'] && menuOffsets.items['bottom'] < selectOffsets.items['top']) ||
// tip is below select
(menuOffsets.items['topCenter'] > selectOffsets.items['topCenter'] && menuOffsets.items['top'] > selectOffsets.items['bottom'])) {
thisSelect.hideList.removeItem(in_menuObj.id);
if (!thisSelect.hideList.length) {
thisSelect.style.visibility = 'visible';
}
}
else {
thisSelect.hideList.setItem(in_menuObj.id, true);
thisSelect.style.visibility = 'hidden';
}
}
}
}
// }}}
// {{{ domMenu_getOffsets()
function domMenu_getOffsets(in_object)
{
var originalObject = in_object;
var originalWidth = in_object.offsetWidth;
var originalHeight = in_object.offsetHeight;
var offsetLeft = 0;
var offsetTop = 0;
while (in_object) {
offsetLeft += in_object.offsetLeft;
offsetTop += in_object.offsetTop;
in_object = in_object.offsetParent;
}
return new domMenu_Hash(
'left', offsetLeft,
'top', offsetTop,
'right', offsetLeft + originalWidth,
'bottom', offsetTop + originalHeight,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -