1

iphone 5 の jQuery animate() 関数にかなり奇妙な問題があります。シナリオ:

要素の touchend イベントにイベント ハンドラーをアタッチし、アニメーションを開始します。通常、これはかなりうまく機能します。しかし、この要素を 1 回スワイプしてページをスクロールするとすぐに、アニメーション機能は (今後のすべてのジェスチャーで) アニメーション化されなくなります。イベントが発生し、ハンドラーが呼び出されますが、animate は何もしません。私はjQueryモバイルイベントで試しましたが、現在はoldscool element.attachaddEventListenerで両方とも同じ結果になりました。面白いことは次のとおりです。

  1. touchstart にアタッチすると、スクロールの前後に機能します (ただし、touchend イベントが必要です!)
  2. たとえばトグルなど、アニメーション化しないことを行うと、それも機能します。

小さなデモンストレーション ページ:

<!DOCTYPE html>
<html>
<head>
    <title>Testpage</title>
    <meta content="width=device-width, initial-scale=1.0, user-scalable=yes" name="viewport">
    <script src="/3rdParty/scripts/jquery/jquery-1.8.3.js" type="text/javascript"></script>
    <style>
        body { padding: 10px;}
        #mover { position: relative; width: 100px; background-color: red; color: #fff; padding: 5px; }
        #hider { width: 100%; overflow: hidden; }
        #touchme {  border:1px solid #808080; margin-bottom:10px;line-height: 50px; text-align:center;}
    </style>
    <script>
        $(document).ready(function(){
            var elem = document.getElementById('touchme');
            elem.addEventListener('touchend', positionHandlerEnd, false );
            elem.addEventListener('mouseup', positionHandlerEnd, false );
        });
    </script>
    <script>
        function positionHandlerEnd(e) {
            $('#mover').animate({left: '+=40px'});
            e.preventDefault();
            return;
        }

    </script>
</head>
<body>
<div id="touchme">Touch me</div>
<div id="hider"><div id="mover">This moves</div></div>
<div> dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate</div>
<div> dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate</div>
<div> dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate</div>
</body>
</html>

ここで何が起こっているのか、何か考えはありますか? または回避策はありますか?

4

3 に答える 3

3

同じ問題に苦しんでいたときに、Safari の「setTimeout バグ」に出くわしました。Safari (IOS6 未満) では、スクロール時にアニメーションやタイマーが実行されないようです。これがスクロールのアニメーションに影響を与える理由はわかりませんが、この男が問題を解決する小さなスクリプトを書いてくれました。必ずチェックしてください:

https://gist.github.com/3755461

他のブラウザーでエラーが発生するかどうかは 100% わかりませんが (まだエラーは発生していません)、1 日を節約できました。共有できることをうれしく思います。

于 2013-01-20T20:07:49.973 に答える
0

I can't duplicate the problem with your code, but I'm having a similar problem right now.

I have an overlay button that runs an animation on left position of an image, just for testing if .animate works.

I also have a touchend eventListener that calls a function which uses .animate to snap the img to a specific position after a touch.

The .animate function no longer works after safari has frozen the DOM to scroll, but everything else does, like .css for instance. Also, if the touchend listener function does not call .animate, the .animate function continues to work when pressing the overlay button after scroll.

I've gone thru the motions of simplifying my code, and still this problem persists. It's irrelevant if i use the js addEventListener or the jquery .bind. So I started slowly picking thru jquery code adding log statements (printing to a div in the page) and noticed that the jQuery.now() function stops returning the current date after scroll, which essentially runs a js function : new Date(). I'm wondering if it has something to do with safari freezing the DOM but I can't seem to find anything more. This does not appear to be happening on android.

What is weird to me at the moment while i look for answers is that in another js file, working in the same page, i can get the date after scroll.

I'm seeing that if the function called on the touchend event does not do an animation, the animate call on this button continues to work. Otherwise it does not.

The following url has a touchend event function that does NOT run .animate :

http://selfconstruc.tv/code/jquery-touchmove/test1.html

The following url has a touchend event function that DOES run .animate :

http://selfconstruc.tv/code/jquery-touchmove/test2.html

于 2013-01-20T08:30:16.730 に答える
0

私はちょうど解決策を見つけました。ちょっとしたハックの私見ですが、私にとってはうまくいきました。touchend イベント関数で、アニメーションを実行する別の関数を呼び出す setTimeout を実行します。
$("div").bind("touchend",TouchEnd); function TouchEnd (e) { タイムアウト = setTimeout(runanimation, 10); }

touchend / scroll後にjquery animate関数がサファリで動作しなくなる問題を回避するには、十分な遅延です。

于 2013-01-21T18:34:11.727 に答える