0

我想做的是制作一个多级菜单。菜单可以有用户想要的尽可能多的子菜单。我只想显示最顶层的菜单,但是在用户单击一个项目后,我希望菜单向下滑动并显示该项目的子菜单。然后用户可以单击这些项目之一以展开下一个子菜单,依此类推。

所以在我进入第三个子菜单后,处理子关卡的动画变得有点棘手。我决定重新开始,为我的菜单创建一个类来处理逻辑。我是 JavaScript 类的新手,但这是我目前所拥有的:

function Menu(ul, parent){
  $ul = $(ul);
  this.lis = [];
  this.parent = parent || false;

  $ul.children('li').each(function(i, li){
    this.lis.push(new Li(li, this));
  });
}

function Li(li, menu){
  $li = $(li);

  if($li.children('div').length)
    this.submenu = new Menu($($li.children('div')[0]).children('ul')[0], menu);
  else
    this.submenu = false;
}

var m = new ​Menu($('#menu'));​​​

我用于此子菜单的动画也不是典型slideDown的。我让菜单向下滑动,然后子菜单淡入。所以在我的 HTML 中,我只是将子菜单包装在 div、slideDowndiv 和fadeInul 中。所以这就是我的 HTML 的样子(请记住,任何级别上都可以有任意数量的项目,也可以有任意数量的级别):

<ul>
  <li>
    Menu Item 1
    <div>
      <ul>
        <li>
          Submenu Item 1
        </li>
        <li>
          Submenu Item 2
          <div>
            <ul>
              <li>Sub-Submenu Item 1</li>
              <li>Sub-Submenu Item 2</li>
            </ul>
          </div>
        </li>
        <li>
          Submenu Item 3
        </li>
      </ul>
    </div>
  </li>
  <li>Menu Item 2</li>
</ul>

我想写一个类,这样一个<li>项目就可以知道它在菜单中的位置。因此,当我不得不使用动画关闭菜单并打开另一部分时,我可以只使用简单的类调用,而不是自己跟踪代码。显然我刚刚开始编写这段代码,但我无法通过这部分,因为我不知道如何。

发生的事情是Menu Item 1被添加到this.lis, 然后Submenu Item 1,但第 2 项不会被添加并且我得到错误Uncaught TypeError: Cannot call method 'push' of undefined所以似乎因为我正在创建新的 Menu 对象,所以它this会丢失。所以我不知道我能做些什么来完成这项工作。有人可以向我解释一下吗?

4

3 回答 3

1

我花了一点时间来理解这个问题,但我相信我已经弄清楚了。

因此,您对“this”上下文丢失的看法是正确的。就使事情保持一致而言,您几乎就在那里。您想要做的是在变量内部传递“this”上下文,允许下一次传递在其上下文中正确使用“this”关键字(我希望这是有道理的)......

在这里,也许更容易向您展示:

function Menu(ul, parent){
    var myMenu = this;
    $ul = $(ul);
    myMenu.lis = [];
    myMenu.parent = parent || false;

    $ul.children('li').each(function(i, li){
        // the "this" keyword in this function context is not the same as the one above
        // which is why you want to use a variable to carry it down from above

        // $(this) will actually reference your "li" element
        myMenu.lis.push(new Li(this, myMenu));
    });
}

function Li(li, menu){
    $li = $(li);

    if($li.children('div').length){
        this.submenu = new Menu($($li.children('div')[0]).children('ul')[0], menu);
    } else {
        this.submenu = false;
    }
}

var m = new ​Menu($('#menu'));​​​

我还没有测试过这段代码,但我很有信心它应该适合你。希望能帮助到你!

于 2012-10-28T03:12:21.810 回答
0
function Menu(ul, parent){
$ul = $(ul);
this.lis = [];
this.parent = parent || false;

$ul.children('li').each(function(i, li){
  this.lis.push(new Li(li, this));
});
}

for-each 循环中的“this”有错误的上下文,你想要类似的东西

function Menu(ul, parent){
$ul = $(ul);
this.lis = [];
this.parent = parent || false;
var that = this/
$ul.children('li').each(function(i, li){
  that.lis.push(new Li(li, that));
});
}
于 2012-10-28T03:24:43.190 回答
0

为什么不使用 jquery 切换或 slideToggle?你可以在这里看到文档:jquery .toggle() & jquery .slideToggle()

于 2012-10-28T03:39:10.483 回答