1

我尝试“绝对化”以前的相关 DOM 元素,每次尝试时,都会发生一个奇怪的“跳跃”,我只是不知道我做错了什么或如何解决这个问题。

好的,可以在这里找到 JS_fiddle 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)
        });

​ 好的,好吧,两秒钟后,当我想将元素设置为其绝对等价物时,有一个....跳转?!?我不知道为什么。我试过$(element).position()而不是offset(),没有成功。

更新:澄清 - h1 停留在原处,h2 进行跳跃。我在 mac os x lion 上测试了最新的 google chrome,firefox 最新的。

我的目标是将元素(通过绝对 jquery 插件)设置为它们的真实(不跳跃)等效 css-absolute 位置,怎么做?谢谢,我真的很感激,谢谢你的时间。

更新 2:heureka,我已经确定了问题(仍然缺少解决方案)!问题:DOM 太快了。这个脚本做了什么:它获取 h1 元素,说:把它从相对上下文(正常渲染流程)中取出并将其设置为“绝对”,此时浏览器重排发生 - 因为 H1 不再在那里,一切都在上升。发生跳跃。这太快了,我们看不到。现在 jquery 函数转到 h2 并说“绝对”,但此时 h2 元素已经有了“新”的相对定位,跳跃确实发生了。这就是不是每个人都看到它的原因,这是一个赛车条件. 如果浏览器要缓慢触发重排,则 DOM 仍保留旧值。好的,怎么办:我们必须收集所有元素的位置值(将它们保存在某个地方),然后,在收集完所有位置值之后,我们一个接一个地更新一个元素。不太确定如何在 jquery 插件的上下文中执行此操作,但我会处理它(今晚,现在重新开始工作)。

更新3:下面的答案是这个问题的正确答案。多谢。这没有解决的一件事(因为我没有要求它)是其他元素的问题,这可能取决于相对定位的元素然后做一些回流舞(因为突然绝对化的元素丢失了),这个小 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() 的元素,获取偏移量并应用它。当它请求 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 回答