www.gusucode.com > 掌柜网店购物系统 4.0码程序 > admin/menu.js
var menu = null; function Menu(section,subsection,layeredFlash) { /* Funky animated menu object ========================== Arguments: ----------------- section // (int) section (if any) to show as "highlighted" (fixed open, static) subsection // (int) subsection (if any) to highlight layeredFlash // (boolean) apply nav logic (or not) based on flash layering support - dependant also on flash embedding support */ var self = this; this.menu = null; this.menuID = 'menu'; // menu container element ID if (typeof(layeredFlash)=='undefined') { layeredFlash = false; } else { // logical AND with flash support check // enable menu drop-down if flash not supported (but is flagged as being on this page) layeredFlash &= flash.hasVersion(5); } this.containers = []; this.frames = [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1]; this.tweens = []; this.menuGroups = []; this.menuHeight = []; this.menuItems = []; this.items = []; this.itemCount = 0; this.createTweens = function() { // Generate array of pixel offsets for nav containers for (var i=0; i<this.containers.length; i++) { this.tweens[i] = [0]; this.tmp = 0; menuOffset = ua.isIE?10:9; for (var j=0; j<this.frames.length; j++) { this.tmp += ((this.menuHeight[i]+menuOffset)*(this.frames[j]*.01)); this.tweens[i][this.tweens[i].length] = parseInt(this.tmp); } this.tweens[i][this.tweens[i].length] = this.menuHeight[i]+menuOffset; } } this.findNode = function(n) { // find a non-text node if (!n || !n.nodeType) return null; while (n.nodeType==3 && n.parentNode) { n = n.parentNode; } return n; } this.isChildOfId = function(targetId, target) { if (!target) return false; do { if (target.id && target.id.indexOf(targetId)+1) { return true; } else if (target.parentNode) { target = target.parentNode; } } while (target.parentNode && target.parentNode.nodeName != 'BODY'); return false; } this.init = function() { // Grab items and create menu item objects, assign event handlers this.menu = document.getElementById(this.menuID); itemsTmp = this.menu.getElementsByTagName('li'); for (var i=0; i<itemsTmp.length; i++) { if (itemsTmp[i].className && itemsTmp[i].className.indexOf('nav-groups')+1) { this.menuGroups[this.menuGroups.length] = itemsTmp[i]; // only add to item count if menu has sub-items if (this.menuGroups[this.menuGroups.length-1].getElementsByTagName('ul').length) this.itemCount++; } } if (this.supported) { // remove CSS offset for static containers for (i=0; i<this.itemCount; i++) { if (section != i) { // don't remove padding from "stuck" open section document.getElementById('sub-group'+i).style.paddingTop = '0px'; } else if (section == i && subsection+1) { // show highlighted sub-menu item, if applicable document.getElementById('nav-group'+i).getElementsByTagName('a')[subsection].className = 'active'; } } } for (i=0; i<this.itemCount; i++) { // create container objects and nav item objects this.containers[i] = this.menuGroups[i].getElementsByTagName('ul')[0]; this.menuHeight[i] = this.containers[i].offsetHeight; // height plus offset of margin this.menuItems[i] = new this.MenuItem(i); if (this.supported) { // supported browsers: assign animation event handlers or show static based on global "section" variable this.menuItems[i].show(); if (section !=i) { // roll up menu if not selected this.containers[i].style.marginTop = ((this.menuHeight[i])*-1)+'px'; } } else { // unsupported browsers: point to static show/hide function instead this.menuItems[i].move = this.menuItems[i].moveStatic; if (section == i && subsection+1) { document.getElementById('nav-group'+i).getElementsByTagName('a')[subsection].className = 'active'; } } if ('nav-group'+section != this.menuGroups[i].id) { // Assign event handler to top-level anchor tag handler = this.menuItems[i].eventHandler; this.menuGroups[i].getElementsByTagName('a')[0].onmouseover = handler; this.menuGroups[i].getElementsByTagName('a')[0].onmouseout = handler; this.menuGroups[i].getElementsByTagName('div')[1].onmouseout = handler; } else { // do not assign event handlers - show nav and leave open this.menuItems[i].show(); } } } this.ns6Fix = function() { // netscape 6.x "invisible links/disappearing float" nav workaround (strange browser bug?) // fix: change a display property of menu container (causing a reflow) document.getElementById(this.menuID).style.width='100%'; } this.MenuItem = function(menuIndex) { this.direction = null; this.menuIndex = menuIndex; this.frameIndex = 0; this.defaultClassName = ''; this.timers = []; this.active = 0; var me = this; this.animate = function() { if (this.frameIndex<0 || this.frameIndex>self.tweens[this.menuIndex].length) { this.frameIndex = 0; } else { if (this.frameIndex >= self.tweens[this.menuIndex].length) { } else { self.containers[this.menuIndex].style.marginTop = (self.menuHeight[menuIndex]*-1)+(this.direction==1?0:-1)+(self.tweens[this.menuIndex][this.frameIndex])+'px'; } } this.frameIndex += this.direction; } this.reset = function(msg) { // reset after previous animation this.active = 0; this.timers = []; // catch potential frame mis-counts from excessive event firing if (this.frameIndex >= self.tweens[this.menuIndex].length) { this.frameIndex = self.tweens[this.menuIndex].length-1; } } this.clearTimers = function() { for (var i=0; i<this.timers.length; i++) { clearTimeout(this.timers[i]); } this.timers = []; } this.eventHandler = function(e) { e = e||window.event; if (e.relatedTarget || e.target) { var eRelatedTarget = self.findNode(e.relatedTarget); var eTarget = self.findNode(e.target); } if (e.type == 'mouseover' && !e.srcElement) { // W3C-style mouseover if (e.target == this) { me.move(1); } else if (e.target) { // me.move(1,e); } } else if (e.type == 'mouseover') { // IE-style mouseover me.move(1); } else if (e.type == 'mouseout' && !e.srcElement) { // W3C-style mouseout if (e.target == this) { if (!menu.isChildOfId('nav-group'+me.menuIndex,eRelatedTarget)) { me.move(-1); } } else if (!menu.isChildOfId('nav-group'+me.menuIndex,eRelatedTarget)) { // not related, nor a child. me.move(-1); } } else if (e.type == 'mouseout') { // IE-style mouseout if (!menu.isChildOfId('nav-group'+me.menuIndex,e.toElement)) { me.move(-1); } } } this.hide = function() { with (self.containers[me.menuIndex].style) { if (visibility != 'hidden') visibility = 'hidden'; } } this.show = function() { with (self.containers[me.menuIndex].style) { if (visibility != 'visible') visibility = 'visible'; } } this.moveStatic = function(direction,evt) { if (direction==1) { me.show(); } else { me.hide(); } } this.move = function(direction) { if (this.active == 0) { // not currently moving this.clearTimers(); if (this.frameIndex>1 && direction==1) { return false; } this.active = 1; this.direction = direction; this.timeout = 0; for (var i=0; i<self.tweens[this.menuIndex].length; i++) { this.timeout += 20; this.timers[this.timers.length] = setTimeout("menu.menuItems["+this.menuIndex+"].animate()",this.timeout); } this.timers[this.timers.length] = setTimeout("menu.menuItems["+this.menuIndex+"].reset()",this.timeout); } else { // nav is currently moving this.clearTimers(); this.reset(); this.timeout = 0; this.direction = (this.direction==-1?1:-1); if (this.direction==1) { for (var i=this.frameIndex; i<self.tweens[this.menuIndex].length; i++) { this.timeout += 20; this.timers[this.timers.length] = setTimeout("menu.menuItems["+this.menuIndex+"].animate()",this.timeout); } } else { for (var i=this.frameIndex; i>0; i--) { this.timeout += 20; this.timers[this.timers.length] = setTimeout("menu.menuItems["+this.menuIndex+"].animate()",this.timeout); } } this.timers[this.timers.length] = setTimeout("menu.menuItems["+this.menuIndex+"].reset()",this.timeout); } } } // MenuItem // Menu() constructor // determine browser type, assign animate handlers only where supported this.supported = true; if (ua.isMac && layeredFlash) { // Mac has issues with reliably layering HTML overtop of Flash - disable nav dropdown this.supported = false; return null; } if (ua.isMac && (ua.isSafari || ua.isIE || ua.equivalentMozilla < 1.0)) { this.supported = false; } else if (ua.isMac && ua.equivalentMozilla>=1.1 && !layeredFlash) { this.supported = true; } else if (ua.isMac) { this.supported = false; } else if (ua.isWin32) { if ((ua.isNS && ua.equivalentMozilla<1.1) || ua.isNS6x) { this.supported = false; } } if (ua.isNS6x) { // check for netscape 6 display bug setTimeout("menu.ns6Fix()",20); // give time to react - may be related to dynamic flash insert // and now, back to your regularly-scheduled menu script. } if (layeredFlash) { // test for flash "layering" support if (ua.isWin) { if (!ua.isNS && !ua.isIE) { return false; } } if (ua.isNS && ua.equivalentMozilla < 1) { return false; } } this.init(); this.createTweens(); }