1

以前は相対的なDOM要素を「絶対化」しようとしましたが、試行するたびに「ジャンプ」が発生し、何が間違っているのか、またはこれを解決する方法がわかりません。

わかりました、JS_fidleはここhttp://jsfiddle.net/rhqy3/3/で見つけることができます

これはダミーのHTMLです

<html>
<body>
    <br><br><h1>one</h1><br><br><br><br>
    <h2>two</h2>
</body>
</html>​

これはjavascriptです(jqueryを使用)

jQuery.fn.absolutize = function()
{
  return this.each(function()
  {
    var element = jQuery(this);
    if (element.css('position') == 'absolute')
    {
      return element;
    }
    alert('now a jump happens, that should not happen')
    element.css("position", "absolute");
    element.css(element.offset());
    return element;

  });
}


$(document).ready(function() {
            window.setTimeout(function(){$("h1, h2").absolutize()}, 2000)
        });

わかりました、まあ、2秒後、要素を完全に同等のものに設定したいとき、....ジャンプがありますか?!?理由はわかりません。$(element).position()代わりに試しましたがoffset()、うまくいきませんでした。

更新:説明-h1はそのままで、h2がジャンプします。私は最新のグーグルクローム、マックOSXライオンの最新のFirefoxにテストインしました。

私の目標は、要素(absolutize jqueryプラグインを参照)を実際の(ジャンプではない)同等のcss-absolute位置に設定することです。どうすればよいですか?thx、私は本当に感謝しています、あなたの時間のためのthx。

アップデート2:heureka、問題を特定しました(まだ解決策がありません)!問題:DOMが速すぎます。このスクリプトは何をしますか:h1要素を取得します:これを相対コンテキスト(通常のレンダリングフロー)から取り出して「絶対」に設定します。この瞬間にブラウザのリフローが発生します-H1はもう存在しないためそこで、すべてが上に移動します。ジャンプが発生します。これは非常に速いので、私たちはそれを見ることができません。これで、jquery関数はh2に移動し、「絶対」と表示されますが、この瞬間、h2要素にはすでに「新しい」相対位置があり、ジャンプはすでに発生しています。それが誰もがそれを見るわけではない理由です、それは競合状態です。ブラウザがリフローのトリガーを遅くする場合でも、DOMは古い値を保持します。わかりました、どうすればよいですか:すべての要素の位置値を収集する(どこかに保存する)必要があります。次に、すべての位置値が収集された後、要素を次々に更新します。jqueryプラグインのコンテキストでこれを行う方法はよくわかりませんが、私はそれに到達します(今夜、仕事に戻ります)。

アップデート3:その下の答えはこの問題に対する正しい答えです。ありがとう。これが解決しないことの1つは(私がそれを求めなかったため)、相対的な位置にある要素に依存する可能性のある他の要素がリフローダンスを行うという問題です(突然絶対化された要素が失われたため)、これ小さなjqueryプラグインはこのhttps://gist.github.com/4051578を解決します。これは、jquery.bodysnatch.jsと呼ばれるjqueryプラグインです。目的は、「元の要素を非表示にしてサイレンシングしながら、要素を絶対位置のクローンに置き換えるjqueryプラグインです。 " 楽しんで。

4

3 に答える 3

3

どうぞ!

http://jsfiddle.net/rhqy3/9/

    (function($){
        $.fn.absolutize = function() {
            var elems = [];
            this.each(function() {
                var element = $(this);

                if (element.css('position') == 'absolute') return;

                var offset = element.offset();
                elems.push({
                    el: element,
                    newRules: {
                        position: 'absolute',
                        top: offset.top,
                        left: offset.left
                    }
                });
            });

            $.each(elems, function(i, obj){
                obj.el.css( obj.newRules );
            });
        };

        $(document).ready(function() {
            window.setTimeout(function(){
                $("h1, h2").absolutize()
            }, 2000);
        });

    })(jQuery);​

問題は、absolutize()に渡された各要素を一度に1つずつ処理し、オフセットを取得して適用することでした。h2のオフセットを要求するまでに、h1はすでにドキュメントのフローから削除されていました。

これをコーディングするためのより良い方法があるかもしれませんが、アイデアは、各位置を変更する前に要素のオフセットをキャッシュすることです。

于 2012-11-09T15:11:42.320 に答える
0

作成する前に、現在の要素の座標を取得する必要がありますabsolute

element.css(element.offset());
element.css("position", "absolute");

フィドル: http: //jsfiddle.net/BYcdn/

于 2012-11-09T11:00:27.473 に答える
0

これを試して:

jQuery.fn.absolutize = function(){

     return this.each(function(){

        var element = $(this);
        element.css("top",element.position().top);
        element.css("left",element.position().left);
        //alert(element.position().top);
        element.css("position", "absolute");

        if (element.css('position') == 'absolute'){
            return element;
        }

  });
}


$(document).ready(function() {
  window.setTimeout(function(){$("h1, h2").absolutize()}, 2000)
});

</ p>

于 2012-11-09T11:24:00.743 に答える