?? dommenu.js
字號:
menuTable.cellSpacing = 0;
}
menuTable.style.border = 0;
menuTable.style.borderCollapse = 'collapse';
var menuTableBody = menuTable.appendChild(targetDoc.createElement('tbody'));
var numSiblings = in_parentElement.data.get('numChildren');
for (var index = 1; index <= numSiblings; index++) {
var dataIndex = in_parentElement.data.get('level') == 1 && settings.get('verticalExpand') == 'north' && settings.get('axis') == 'horizontal' ? numSiblings + 1 - index : index;
var menuTableCell = menuTableBody.appendChild(targetDoc.createElement('tr')).appendChild(targetDoc.createElement('td'));
menuTableCell.style.padding = 0;
menuTableCell.id = in_parentElement.id + '-' + dataIndex;
// add element to list of parent children
in_parentElement.data.get('childElements').set(menuTableCell.id, menuTableCell);
// assign the settings to nth level element
menuTableCell.data = in_parentElement.data.get(dataIndex);
menuTableCell.data.merge(new Hash(
'basename', in_parentElement.data.get('basename'),
'parentElement', in_parentElement,
'numChildren', menuTableCell.data.numericLength,
'childElements', new Hash(),
'offsets', new Hash(),
'level', in_parentElement.data.get('level') + 1,
'index', index
));
// assign the styles
menuTableCell.style.cursor = 'default';
var element = menuTableCell.appendChild(targetDoc.createElement('div'));
var outerElement = element;
outerElement.className = settings.get('subMenuElementClass');
if (menuTableCell.data.get('numChildren')) {
element = outerElement.appendChild(targetDoc.createElement('div'));
element.style.backgroundImage = 'url(' + settings.get('expandMenuArrowUrl') + ')';
element.style.backgroundRepeat = 'no-repeat';
if (settings.get('horizontalExpand') == 'east') {
element.style.backgroundPosition = 'right center';
element.style.paddingRight = '12px';
}
else {
element.style.backgroundPosition = 'left center';
element.style.paddingLeft = '12px';
}
}
// fill in the menu item contents
if (domLib_isMacIE) {
// we don't support images in sub-menu elements in MacIE because in order for
// the menu to work consistently the data has to be added with createTextNode()
element.appendChild(targetDoc.createTextNode(menuTableCell.data.get('contents')));
// MacIE has to have a newline and it has to be added with createTextNode!
menuTableCell.appendChild(targetDoc.createTextNode("\n"));
}
else {
element.innerHTML = menuTableCell.data.get('contents');
}
// attach the events
menuTableCell.onmouseover = domMenu_openSubMenuOnmouseoverHandler;
menuTableCell.onmouseout = domMenu_closeMenuHandler;
if (settings.get('openClickSubMenuDelay') >= 0 && menuTableCell.data.get('numChildren')) {
menuTableCell.onmousedown = domMenu_openSubMenuOnclickHandler;
menuTableCell.onmouseup = domLib_cancelBubble;
if (domLib_isIE) {
menuTableCell.ondblclick = domMenu_openSubMenuOnclickHandler;
}
}
else if (menuTableCell.data.get('uri')) {
menuTableCell.style.cursor = domMenu_pointerStyle;
menuTableCell.onclick = domMenu_resolveLinkHandler;
}
else if (!menuTableCell.data.get('numChildren')) {
outerElement.className += ' ' + settings.get('subMenuElementHeadingClass');
}
// prevent highlighting of text
if (domLib_isIE) {
menuTableCell.onselectstart = makeFalse;
}
menuTableCell.oncontextmenu = makeFalse;
}
menu = targetDoc.body.appendChild(menu);
domMenu_toggleSubMenu(in_parentElement, 'visible');
}
// }}}
// {{{ domMenu_changeActivePath()
/**
* Close the old active path up to the new active element
* and return the value of the new active element (or the same if unchanged)
* NOTE: If the new active element is not set (false), the top level is assumed
*
* @return mixed new active element or false if not set
*/
function domMenu_changeActivePath(in_newActiveElement, in_oldActiveElement, in_closeDelay)
{
// protect against crap
if (!in_oldActiveElement && !in_newActiveElement) {
return false;
}
// cancel open timeouts since we know we are opening something different now
for (var i in domMenu_timeouts['open'].elementData) {
domLib_clearTimeout(domMenu_timeouts['open'].get(i));
}
// grab some info about this menu system...will this ever be null?
var basename = in_oldActiveElement ? in_oldActiveElement.data.get('basename') : in_newActiveElement.data.get('basename');
var settings = domMenu_settings.get(basename);
// build the old active path and unhighlight previously selected element, if appropriate
var oldActivePath = new Hash();
if (in_oldActiveElement) {
var tmp_newActiveLevel = in_newActiveElement ? in_newActiveElement.data.get('level') : -1;
var tmp_oldActivePathElement = in_oldActiveElement;
do {
// NOTE: using set() causes IE to lag and leaves behind highlighted artifacts!
oldActivePath.elementData[tmp_oldActivePathElement.id] = tmp_oldActivePathElement;
// unhighlight if sibling of new element, even if it has open submenus
if (tmp_newActiveLevel >= 0 && tmp_oldActivePathElement.data.get('level') == tmp_newActiveLevel) {
domMenu_toggleHighlight(tmp_oldActivePathElement, false);
}
} while ((tmp_oldActivePathElement = tmp_oldActivePathElement.data.get('parentElement')) && tmp_oldActivePathElement.id != basename);
// unhighlight element immediately if no submenu (or submenu is closed)
if (!in_oldActiveElement.data.get('subMenu') || in_oldActiveElement.data.get('subMenu').style.visibility == 'hidden') {
domMenu_toggleHighlight(in_oldActiveElement, false);
}
}
// build the new path and...(explain me!)
var newActivePath = new Hash();
var intersectPoint;
if (in_newActiveElement) {
var actualActiveElement = in_newActiveElement;
window.status = in_newActiveElement.data.get('statusText') + ' ';
// in the event we have no old active element, just highlight new one and return
// without setting the new active element (handled later)
if (!in_oldActiveElement) {
domLib_clearTimeout(domMenu_timeouts['close'].get(in_newActiveElement.id));
domMenu_toggleHighlight(in_newActiveElement, true);
return false;
}
// if the new element is in the path of the old element, then pretend event is
// on the old active element
else if (oldActivePath.has(in_newActiveElement.id)) {
in_newActiveElement = in_oldActiveElement;
}
var tmp_newActivePathElement = in_newActiveElement;
do {
// if we have met up with the old active path, then record merge point
if (!intersectPoint && oldActivePath.has(tmp_newActivePathElement.id)) {
intersectPoint = tmp_newActivePathElement;
}
newActivePath.set(tmp_newActivePathElement.id, tmp_newActivePathElement);
domLib_clearTimeout(domMenu_timeouts['close'].get(tmp_newActivePathElement.id));
// FIXME: this is ugly!
if (tmp_newActivePathElement != in_oldActiveElement || actualActiveElement == in_oldActiveElement) {
domMenu_toggleHighlight(tmp_newActivePathElement, true);
}
} while ((tmp_newActivePathElement = tmp_newActivePathElement.data.get('parentElement')) && tmp_newActivePathElement.id != basename);
// if we move to the child of the old active element
if (in_newActiveElement.data.get('parentElement') == in_oldActiveElement) {
return in_newActiveElement;
}
// if the new active element is in the old active path
else if (in_newActiveElement == in_oldActiveElement) {
return in_newActiveElement;
}
// find the sibling element
var intersectSibling;
if (intersectPoint && oldActivePath.length > 0) {
for (var i in oldActivePath.elementData) {
if (oldActivePath.get(i).data.get('parentElement') == intersectPoint) {
intersectSibling = oldActivePath.get(i);
break;
}
}
}
var isRootLevel = in_newActiveElement.data.get('level') == 1 ? true : false;
var closeDelay = isRootLevel ? settings.get('closeMouseoutMenuDelay') : settings.get('closeMouseoutSubMenuDelay');
}
else {
var isRootLevel = false;
var closeDelay = settings.get('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
// FIXME: clean this up
else {
// add lingering menus outside of old active path to active path
for (var i in domMenu_timeouts['close'].elementData) {
if (!oldActivePath.has(i)) {
var tmp_element = document.getElementById(i);
if (tmp_element.data.get('basename') == basename) {
oldActivePath.set(i, tmp_element);
}
}
}
}
}
// schedule the old active path to be closed
for (var i in oldActivePath.elementData) {
if (newActivePath.has(i)) {
continue;
}
// make sure we don't double schedule here
domLib_clearTimeout(domMenu_timeouts['close'].get(i));
if (isRootLevel) {
domMenu_toggleHighlight(oldActivePath.get(i), false);
domMenu_toggleSubMenu(oldActivePath.get(i), 'hidden');
}
else {
domMenu_timeouts['close'].set(i, domLib_setTimeout(domMenu_closeMenuCallback, closeDelay, [oldActivePath.get(i), basename]));
}
}
return in_newActiveElement;
}
// }}}
// {{{ domMenu_deactivate()
function domMenu_deactivate(in_basename, in_delay)
{
if (!in_delay) {
in_delay = 0;
}
domMenu_changeActivePath(false, domMenu_activeElement.get(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_delayType)
{
if (domLib_isGecko) {
window.getSelection().removeAllRanges();
}
// setup the cross-browser event object and target
var eventObj = domLib_isIE ? event : in_event;
// ensure the event is from the correct frame
if (domLib_isIE && in_this.data.get('level') > 1) {
var targetFrame = domMenu_settings.get(in_this.data.get('basename')).get('subMenuTargetFrame');
if (targetFrame) {
eventObj = targetFrame.event;
}
}
var currentTarget = domLib_isIE ? in_this : eventObj.currentTarget;
var basename = currentTarget.data.get('basename');
var settings = domMenu_settings.get(basename);
// if we are moving amoungst DOM 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.get(basename)) {
domMenu_changeActivePath(false, domMenu_activeElement.get(basename), currentTarget.data.get('level') == 1 ? settings.get('closeClickMenuDelay') : settings.get('closeClickSubMenuDelay'));
return;
}
// if this element has children, popup the child menu
if (currentTarget.data.get('numChildren')) {
// the top level menus have no delay when moving between them
// so activate submenu immediately
if (currentTarget.data.get('level') == 1 && domMenu_activeElement.get(basename)) {
// ** I place changeActivePath() call here so the hiding of selects does not flicker **
// THOUGHT: 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.set(basename, domMenu_changeActivePath(currentTarget, domMenu_activeElement.get(basename)));
}
else {
// clear the active path and initialize the new one
domMenu_activeElement.set(basename, domMenu_changeActivePath(currentTarget, domMenu_activeElement.get(basename)));
domMenu_timeouts['open'].set(currentTarget.id, domLib_setTimeout(domMenu_openMenuCallback, settings.get(in_delayType), [currentTarget, basename]));
}
}
else {
// clear the active path and initialize the new one
domMenu_activeElement.set(basename, domMenu_changeActivePath(currentTarget, domMenu_activeElement.get(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 = domLib_isIE ? event : in_event;
// ensure the event is from the correct frame
if (domLib_isIE && in_this.data.get('level') > 1) {
var targetFrame = domMenu_settings.get(in_this.data.get('basename')).get('subMenuTargetFrame');
if (targetFrame) {
eventObj = targetFrame.event;
}
}
var currentTarget = domLib_isIE ? in_this : eventObj.currentTarget;
var basename = currentTarget.data.get('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.get(basename)) {
if (!relatedTarget) {
domMenu_changeActivePath(false, domMenu_activeElement.get(basename));
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -