11

質問のタイトルは、私の特定のケースの背後にある究極の質問であると私が考えるものを表しています。

私の場合: クリック ハンドラー内で、ビジー関数が開始される直前に画像を表示 (「読み込み」アニメーション) したいと考えています。次に、関数が完了したら、再び非表示にしたいと思います。予想に反して、画像が表示されないことに気付きました。これは、ブラウザーが再描画を行う前に、ハンドラーが終了するのを待っているためだと思います (これにはパフォーマンス上の理由があると確信しています)。

コード(このフィドルでも:http://jsfiddle.net/JLmh4/2/

html:

<img id="kitty" src="http://placekitten.com/50/50" style="display:none">
<div><a href="#" id="enlace">click to see the cat</a> </div>

js:

$(document).ready(function(){
    $('#enlace').click(function(){
        var kitty = $('#kitty');
        kitty.css('display','block');

        // see: http://unixpapa.com/js/sleep.html
        function sleepStupidly(usec)
        {
            var endtime= new Date().getTime() + usec;
            while (new Date().getTime() < endtime)
                ;
        }

        // simulates bussy proccess, calling some function...

        sleepStupidly(4000);

        // when this triggers the img style do refresh!
        // but not before
        alert('now you do see it');

        kitty.css('display','none');
    });
});

alert関数の直後に呼び出しを追加しsleepStupidlyて、その休憩の瞬間にブラウザーが再描画を行うが、その前ではないことを示します。「表示」を「ブロック」に設定した直後に再描画されることを無邪気に期待していました。

記録のために、このコードで画像を表示および非表示にする代わりに、html タグを追加するか、css クラスを交換することも試みました。同じ結果です。

すべての調査の結果、必要なのはブラウザに強制的に再描画させ、それまで他のすべてを停止させる機能であると思います。

出来ますか?クロスブラウザの方法で可能ですか?多分見つけられなかったいくつかのプラグイン...?

「jquery css callback」のようなもの(この質問のように:JQueryでは、新しいcssルールを設定した後にコールバック関数を取得することは可能ですか?)がうまくいくと思いました...しかし、それは存在しません。

また、同じイベントの異なるハンドラーでの表示、関数呼び出し、および非表示を分離しようとしましたが、何もしませんでした。setTimeoutまた、関数の実行を遅らせるためにa を追加します (ここで推奨されているように: JavaScript で DOM の更新を強制する)。

ありがとう、それが他の人にも役立つことを願っています。

ハビエル

編集(私の好みの答えを設定した後):

window.setTimeout 戦略を選択した理由をさらに説明するために。私の実際の使用例では、ブラウザーにページを再描画するのに十分な時間を与えるために、約 1000 ミリ秒 (フィドルの例の 50 ミリ秒よりもはるかに長い) を与える必要があることに気付きました。これは、DOM ツリーがより深い (実際、不必要に深い) ためであると私は信じています。setTimeout let アプローチを使用すると、それが可能になります。

4

5 に答える 5

7

JQueryshowhideコールバックを使用します (または、fadeIn/fadeOut などを表示する他の方法)。

http://jsfiddle.net/JLmh4/3/

$(document).ready(function () {
    $('#enlace').click(function () {
        var kitty = $('#kitty');


        // see: http://unixpapa.com/js/sleep.html
        function sleepStupidly(usec) {
            var endtime = new Date().getTime() + usec;
            while (new Date().getTime() < endtime);
        }

        kitty.show(function () {

            // simulates bussy proccess, calling some function...
            sleepStupidly(4000);

            // when this triggers the img style do refresh!
            // but not before
            alert('now you do see it');

            kitty.hide();
        });
    });
});
于 2013-06-01T18:17:56.807 に答える
5

window.setTimeout()遅い関数を実行するために、目立たない短い遅延で使用します。

$(document).ready(function() {
    $('#enlace').click(function() {
        showImage();

        window.setTimeout(function() {
            sleepStupidly(4000);
            alert('now you do see it');
            hideImage();
        }, 50);
    });
});

ライブデモ

于 2013-06-01T18:33:46.667 に答える
4

再描画を強制するには、offsetHeight または getComputedStyle() を使用できます。

var foo = window.getComputedStyle(el, null);

また

var bar = el.offsetHeight;

「el」はDOM要素です

于 2016-08-05T19:21:24.900 に答える