jQueryでスクロール位置によってコンテンツを表示させています。  
その中で、表示後にその中の画像の位置を変更してアニメーションさせている部分があるのですが、スクロールごとに何度も動いてしまいます(1回だけで止めたい)

```

    $(window).scroll(function() {
        var scroll = $(window).scrollTop();
        var windowHeight = $(window).height();
        $('#box1').each(function() {
            var boxPos = $(this).offset().top;
            if(scroll > boxPos - windowHeight + 300){
                $(this).find('.transparence').animate({
                    'opacity': '1'
                }, 600);
                $(this).find('.textarea').delay(400).animate({
                    'opacity': '1',
                }, 600, function() {
                    $('#moveimg01').delay('200').animate({
                        'left': '270px',
                        'bottom': '20px'
                    }, 300, function() {
                        $('#moveimg01').animate({
                            'left': '250px',
                            'bottom': '0'
                        }, 200);
                    });
                });
            }
        });
        $('#box2').each(function() {
            var boxPos = $(this).offset().top;
            if(scroll > boxPos - windowHeight + 300){
                $(this).find('.transparence').animate({
                    'opacity': '1'
                }, 600, function() {
                    $('#moveimg02').delay(200).animate({
                        'right': '-20px',
                        'top': '40px'
                    }, 300, function() {
                        $('#moveimg02').animate({
                            'right': '0',
                            'top': '60px'
                        }, 200);
                    });
                });
                $(this).find('.textarea').delay(400).animate({
                    'opacity': '1',
                }, 600);
            }
        }); ・・・続く
    
```

この最後の

```

    $('#moveimg01').animate({
      'left': '250px',
      'bottom': '0'
    }, 200);
    
```

の部分でそれぞれ止めたいのですが、スクロールするたびに何度も動いてしまいます。  
この部分で止める方法、もっとほかの書き方などありますでしょうか。
CC BY-SA 3.0
2015-10-25T17:19:47.690
18063
2015-10-30T13:17:10.510
12964
question
jquery
jQueryでのスクロールイベント中にanimateを止めたい
画面内の要素位置をスクロールするたびに記録しておき  
($(anim要素).offset().top + $(anim要素).outerHeight()) -
$(window).scrollTop()がマイナス値 -> プラス値になったとき  
または  
$(anim要素).offset().top - ($(window).scrollTop() + $(window).height())がプラス値 ->  
マイナス値になったとき  
にアニメーションさせればいいんでないでしょうか。

前の要素位置は$(anim要素).data('before', beforePos);で要素ごとにセットしておけばいいかと
CC BY-SA 3.0
2015-10-26T03:26:04.090
18075
2015-10-26T03:26:04.090
12894
18063
answer
JSで各要素の状態を保持しておく方法もあると思いますが、  
自分がよくとる方法は、htmlのclassで状態を管理してJSで判別するやり方です。

`#moveimg01`要素に`.toAnimate`等のクラスをつけておいて、

```

    $('#box1').hasClass('toAnimate').each(function() {
        var boxPos = $(this).offset().top;
        if(scroll > boxPos - windowHeight + 300){
            $('#box1').removeClass('toAnimate') // ここでクラスを消します
            // ... 省略 ...
                }, 300, function() {
                    $('#moveimg01').animate({
                        'left': '250px',
                        'bottom': '0'
                    }, 200);
                });
            });
        }
    });
    
```

などと記述すれば、一度アニメーションした後はアニメーションしなくなるかと思います。

```

    $('#box1.toAnimate').each(
    
```

でもよいですね。

似たやり方で、動いた要素に`.isAnimated`などのクラスを付与して、  
クラスを持っていたら処理をさせない、というやり方もあるかと思います。

* * *

質問とは関係ないですがコードに気になった点があったので書きます。

  1. `$('#box1').each(...`など同IDのを持つ要素は存在しないはずなのに `.each()`を使っている

=> この部分 each() である必要ありますか？確認してみてください。

  2. `$('#moveimg01')`など同要素を複数回取得している

=> 取得回数（要素の検索回数）が多くなる = 処理が遅くなる ですので、

```     var $target = $('#moveimg01');

    $target.delay('200').animate({
        // ... 省略 ...
    }, 300, function() {
        $target.animate({
            // ... 省略 ...
        }, 200);
    });
    
```

みたいに書くといいですよ。
CC BY-SA 3.0
2015-10-30T12:01:54.287
18249
2015-10-30T13:17:10.510
2015-10-30T13:17:10.510
8872
8872
18063
answer