滑动式折叠菜单 - Slashdot's Menu

时间:2022-04-16 03:05:54
折叠菜单让你在尽可能小的地方放置尽可能多的内容,同时加大了操作的简便性,因此,深受前台设计师的喜爱。随着大家对动画效果的钟爱,折叠菜单也开始“动”起来了,本文介绍的就是 DimX 制作的滑动式折叠菜单效果-Slashdot's Menu。
 
  1. <script type="text/javascript">
  2. function SDMenu(id) {
  3.     if (!document.getElementById || !document.getElementsByTagName)
  4.         return false;
  5.     this.menu = document.getElementById(id);
  6.     this.submenus = this.menu.getElementsByTagName("div");
  7.     this.remember = true;
  8.     this.speed = 3;
  9.     this.markCurrent = true;
  10.     this.oneSmOnly = false;
  11. }
  12. SDMenu.prototype.init = function() {
  13.     var mainInstance = this;
  14.     for (var i = 0; i < this.submenus.length; i++)
  15.         this.submenus[i].getElementsByTagName("span")[0].onclick = function() {
  16.             mainInstance.toggleMenu(this.parentNode);
  17.         };
  18.     if (this.markCurrent) {
  19.         var links = this.menu.getElementsByTagName("a");
  20.         for (var i = 0; i < links.length; i++)
  21.             if (links[i].href == document.location.href) {
  22.                 links[i].className = "current";
  23.                 break;
  24.             }
  25.     }
  26.     if (this.remember) {
  27.         var regex = new RegExp("sdmenu_" + encodeURIComponent(this.menu.id) + "=([01]+)");
  28.         var match = regex.exec(document.cookie);
  29.         if (match) {
  30.             var states = match[1].split("");
  31.             for (var i = 0; i < states.length; i++)
  32.                 this.submenus[i].className = (states[i] == 0 ? "collapsed" : "");
  33.         }
  34.     }
  35. };
  36. SDMenu.prototype.toggleMenu = function(submenu) {
  37.     if (submenu.className == "collapsed")
  38.         this.expandMenu(submenu);
  39.     else
  40.         this.collapseMenu(submenu);
  41. };
  42. SDMenu.prototype.expandMenu = function(submenu) {
  43.     var fullHeight = submenu.getElementsByTagName("span")[0].offsetHeight;
  44.     var links = submenu.getElementsByTagName("a");
  45.     for (var i = 0; i < links.length; i++)
  46.         fullHeight += links[i].offsetHeight;
  47.     var moveBy = Math.round(this.speed * links.length);
  48.     var mainInstance = this;
  49.     var intId = setInterval(function() {
  50.         var curHeight = submenu.offsetHeight;
  51.         var newHeight = curHeight + moveBy;
  52.         if (newHeight < fullHeight)
  53.             submenu.style.height = newHeight + "px";
  54.         else {
  55.             clearInterval(intId);
  56.             submenu.style.height = "";
  57.             submenu.className = "";
  58.             mainInstance.memorize();
  59.         }
  60.     }, 30);
  61.     this.collapseOthers(submenu);
  62. };
  63. SDMenu.prototype.collapseMenu = function(submenu) {
  64.     var minHeight = submenu.getElementsByTagName("span")[0].offsetHeight;
  65.     var moveBy = Math.round(this.speed * submenu.getElementsByTagName("a").length);
  66.     var mainInstance = this;
  67.     var intId = setInterval(function() {
  68.         var curHeight = submenu.offsetHeight;
  69.         var newHeight = curHeight - moveBy;
  70.         if (newHeight > minHeight)
  71.             submenu.style.height = newHeight + "px";
  72.         else {
  73.             clearInterval(intId);
  74.             submenu.style.height = "";
  75.             submenu.className = "collapsed";
  76.             mainInstance.memorize();
  77.         }
  78.     }, 30);
  79. };
  80. SDMenu.prototype.collapseOthers = function(submenu) {
  81.     if (this.oneSmOnly) {
  82.         for (var i = 0; i < this.submenus.length; i++)
  83.             if (this.submenus[i] != submenu && this.submenus[i].className != "collapsed")
  84.                 this.collapseMenu(this.submenus[i]);
  85.     }
  86. };
  87. SDMenu.prototype.expandAll = function() {
  88.     var oldOneSmOnly = this.oneSmOnly;
  89.     this.oneSmOnly = false;
  90.     for (var i = 0; i < this.submenus.length; i++)
  91.         if (this.submenus[i].className == "collapsed")
  92.             this.expandMenu(this.submenus[i]);
  93.     this.oneSmOnly = oldOneSmOnly;
  94. };
  95. SDMenu.prototype.collapseAll = function() {
  96.     for (var i = 0; i < this.submenus.length; i++)
  97.         if (this.submenus[i].className != "collapsed")
  98.             this.collapseMenu(this.submenus[i]);
  99. };
  100. SDMenu.prototype.memorize = function() {
  101.     if (this.remember) {
  102.         var states = new Array();
  103.         for (var i = 0; i < this.submenus.length; i++)
  104.             states.push(this.submenus[i].className == "collapsed" ? 0 : 1);
  105.         var d = new Date();
  106.         d.setTime(d.getTime() + (30 * 24 * 60 * 60 * 1000));
  107.         document.cookie = "sdmenu_" + encodeURIComponent(this.menu.id) + "=" + states.join("") + "; expires=" + d.toGMTString() + "; path=/";
  108.     }
  109. };
  110. </script>

调用方式
HTML:

    1.  
    2. var myMenu = new SDMenu("main_menu"); // 菜单ID
    3.  
    4. // 默认参数
    5. myMenu.speed = 3; // 折叠速度
    6. myMenu.remember = true; // 是否记录状态
    7. myMenu.oneSmOnly = false; // 一次只有一个菜单打开
    8. myMenu.markCurrent = true; // 是否高亮当前菜单
    9.  
    10. myMenu.init();
    11.  
    12. // 附加方法
    13. var firstSubmenu = myMenu.submenus[0];
    14. myMenu.expandMenu(firstSubmenu); // 打开一个菜单
    15. myMenu.collapseMenu(firstSubmenu); // 关闭一个菜单
    16. myMenu.toggleMenu(firstSubmenu); // 当菜单关闭时打开,当菜单打开时关闭
    17.  
    18. myMenu.expandAll(); // 打开所有菜单
    19. myMenu.collapseAll(); // 关闭所有菜单