2016-09-02 19 views
-3

ブロックを表示するページがあります。それらは4列4列、合計16ブロックです。
しかし、ページの一番下に達すると、ページの下部に達するたびに16個のブロックを追加するAJAX関数があります。.each()AJAX関数の問題

私はこのコードで徐々にこれらの要素にクラスを追加し、これを行うために、(私は0から1への不透明度を変更する)これらのブロックのための負荷のアニメーションをしたい:

列1の場合:
.colnum1

.colnum2は列2のブロックに相当):カラム2について

$('.colnum1').each(function(u){ 
    setTimeout(function(){ 
    $('.colnum1').eq(u).addClass('selected'); 
    }, 1200 * u); 
}); 

)をカラム1におけるブロックに対応します

これはすべて最初の16個の要素に最適です。

しかし、次の16要素をロードすると、アニメーションが表示される前に(アニメーションonloadが発生する前に)遅延します。
この遅延が何に対応しているのかわかりました...
jQueryの.each()関数が再び実行されると、新しい要素の前に既に存在する要素がスローされます...しかし、望まれていません。

私は、すでに読み込まれた要素を先に投げていないように関数を書き直そうとしました。このコードでは

:(.selectedonloadアニメーションを追加クラスである)

$('.colnum1:not(.selected)').each(function(u){ 
    setTimeout(function(){ 
    $('.colnum1:not(.selected)').eq(u).addClass('selected'); 
    }, 1200 * u); 
}); 

しかし、いくつかの理由で、それはいくつかなどをスキップし...すべての要素にクラス.selectedを追加されていません

私が知りたいこと新しい16要素を取得したときに、.each関数は、以前の既存の要素のすべてを最初にスローしないようにするにはどうすればよいですか?

+0

なぜあなたはsetTimeoutメソッドを使用しています?なぜあなたはそれぞれを使っていますか? –

+0

@ KevinBすべての16要素が同時に表示されるわけではないので、それらは見栄えの良いフローです。 – Jackymamouth

+0

あなたはすべてのコンテンツをロードしています。ユーザーはスクロールしますが、アニメーションを表示してそれらを表示するように強制しますか?それは、いけてないねえ。 –

答えて

0

すべての要素を選択できなかったのは、ハンドラを呼び出すたびに用語$('.colnum1:not(.selected)')を再評価したためです。

この手順をステップバイステップで進めてください。私たちは最初のコラムにのみ注意を払っています。

最初に、$('.colnum1:not(.selected)')が評価されます。これには、最初の列の4つのブロックがすべて含まれています。次に、これらのブロックを反復処理し、setTimeoutを4回呼び出します。ここまでは順調ですね。

次に、初めてハンドラを呼び出します。それは$('.colnum1:not(.selected)')を再度評価し、jQueryオブジェクトは再び4つのブロックすべてから構成されます。最初のものを選択し(u=0)、selectedクラスを追加します。

1200ミリ秒後に、ハンドラを再度呼び出します。しかし、今回は、のjQueryオブジェクト$('.colnum1:not(.selected)')は別のです。 .selectedフィルタのため、最初のブロックは含まれなくなりました。そして今度はu=1となるので、$('.colnum1:not(.selected)').eq(u)は、この新しい短縮リストの2番目の要素、つまり列の3番目のブロックです。明らかに、あなたは第2のものを望んでいました。

  • あなたは.eq(0).eq(u)を変更することができます:

    は、この問題を解決するには、いくつかの方法があります。私はこれをとても好きではありません。

  • $('.colnum1:not(.selected)')をループの前の変数に保存してから、CSSセレクタを再度評価する代わりに、その変数をハンドラ内で使用することができます。 jQueryオブジェクトは、セレクタともはや一致しなくても、同じ4つの要素を表し続けます。
  • ハンドラは、現在のHTML要素を引数として受け取ります。 jQueryオブジェクトではなく、生のDOM要素です。しかし、$を呼び出してjQueryオブジェクトにしてから、新しいjQueryオブジェクトを使用することができます。同様に、 $('.colnum1').each(function(u, block){ setTimeout(function(){ $(block).addClass('selected'); }, 1200 * u); });
  • また、前述のアプローチのマイナーな変形として、ハンドラはthisキーワードでDOM要素も受け取ります。したがって、block引数を使用する代わりに、setTimeoutの直前にvar block = this;と書いてください。 (単に$(this)$(block)を交換しても動作しない場合があります - 。私はthisの値がsetTimeoutハンドラ内にあるかわからないんだけどそれも、私が知っているすべてのために、ブラウザに依存するかもしれません。)