0

私がやろうとしているのは、マルチレベルのメニューを作ることです。メニューには、ユーザーが必要とする数のサブメニューを含めることができます。最初は一番上のメニューのみを表示したいのですが、ユーザーが 1 つの項目をクリックした後、メニューを下にスライドさせてその項目のサブメニューを表示したいと考えています。次に、ユーザーはそれらの項目の 1 つをクリックして、次のサブメニューを展開することができます。

そのため、3 番目のサブメニューに到達した後、サブレベルのアニメーションを処理するのがややこしくなりました。最初からやり直して、ロジックを処理するメニューのクラスを作成することにしました。私は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が追加されますが、項目 2 が追加されず、エラーが発生するため、新しい Menu オブジェクトを作成しているため、追跡が失われているようです。そのため、この作業を行うために何ができるかわかりません。誰か説明してくれませんか?this.lisSubmenu Item 1Uncaught TypeError: Cannot call method 'push' of undefinedthis

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のトグルやスライドのトグルを使わないのですか?? ここでドキュメントを見ることができます: jquery .toggle( ) & jquery .slideToggle()

于 2012-10-28T03:39:10.483 に答える