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();
}