jQuery - 使我的类递归

时间:2012-10-28 02:52:59

标签: javascript jquery class recursion this

我要做的是制作一个多级菜单。菜单可以包含用户想要的子菜单。我只想显示最开始的菜单,但在用户点击一个项目后,我希望菜单向下滑动并显示该项目的子菜单。然后,用户可以单击其中一个项目以展开下一个子菜单,依此类推。

因此,在进入第三个子菜单后,处理子级别的动画变得有点粘。我决定重新开始为我的菜单创建一个类来处理逻辑。我是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中,slideDown div,然后fadeIn ul。这就是我的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会丢失。所以我不知道我能做些什么来完成这项工作。有人可以向我解释一下吗?

3 个答案:

答案 0 :(得分:1)

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

所以,你对“迷失”的“这个”背景是正确的。就像保持在线一样,你几乎就在那里。你想要做的是,在变量中传递“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'));​​​

我没有测试过这段代码,但我相信它应该对你有用。希望它有所帮助!

答案 1 :(得分: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));
});
}

答案 2 :(得分:0)

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