如何获取元素的“固定”位置?

18

我想要获取一个元素相对于窗口的位置(固定位置)。

这是我目前已经得到的:

(function ($) {
    $.fn.fixedPosition = function () {
        var offset = this.offset();
        var $doc = $(document);
        return {
            'x': offset.left - $doc.scrollLeft(),
            'y': offset.top - $doc.scrollTop()
        };
    };
})(jQuery);

$('#thumbnails img').click(function () {
    var pos = $(this).fixedPosition();
    console.log(pos);
});

但是当我点击缩略图时,它似乎偏移了大约10个像素左右。也就是说,即使照片的顶部边缘距离我的浏览器窗口顶部约5个像素,它仍会为y给出负值。


我在JSFiddle上复制了你的代码http://jsfiddle.net/gbsandeep/qZa5z/。至少对于HTML元素(input),它显示正确的值。你能否检查一下图片? - Sandeep G B
@SandeepGB:http://jsfiddle.net/qZa5z/1/ 看起来也可以用于图片... - mpen
为什么不使用CSS属性position:fixed? - Charles Jourdan
@CharlesJourdan:我正在将一个相对定位的元素动画转换为固定定位。 - mpen
3个回答

7

6

更新:

现在的解决方案依赖于JSizes和一些辅助方法:

function Point(x, y) {
    return {
        'x': x,
        'y': y,
        'left': x,
        'top': y
    };
}

$.fn.outerOffset = function () {
    /// <summary>Returns an element's offset relative to its outer size; i.e., the sum of its left and top margin, padding, and border.</summary>
    /// <returns type="Object">Outer offset</returns>
    var margin = this.margin();
    var padding = this.padding();
    var border = this.border();
    return Point(
        margin.left + padding.left + border.left,
        margin.top + padding.top + border.top
    );
};


$.fn.fixedPosition = function () {
    /// <summary>Returns the "fixed" position of the element; i.e., the position relative to the browser window.</summary>
    /// <returns type="Object">Object with 'x' and 'y' properties.</returns>
    var offset = this.offset();
    var $doc = $(document);
    var bodyOffset = $(document.body).outerOffset();
    return Point(offset.left - $doc.scrollLeft() + bodyOffset.left, offset.top - $doc.scrollTop() + bodyOffset.top);
};

Arghhh!在Firefox中,$(document.body).position() 报告为 -20 而不是 -10!那多出来的10是从哪里来的? - mpen
为什么要逆流而上呢?只需从body中删除所有填充、边距和边框即可。如果您需要在页面顶部添加一条黑色条纹,只需使用带有背景的div即可。:) 在这种情况下,.offset()应该是跨浏览器准确的。 - Matthew Blancarte
@MatthewBlancarte:我想我可以这样做,只是我不喜欢它在某些情况下不能正常工作的想法,但我想我并没有真正计划将其发布为库。 - mpen
1
我完全同意,它不自动考虑body属性确实很烦人。一定要喜欢跨浏览器DOM问题。 :/ - Matthew Blancarte

2
您的代码看起来很好,应该按照您的期望工作。
话虽如此,.offset() 中存在一个“陷阱”,它不会考虑到应用于DOM body的任何padding、margin或border。它查找元素相对于文档的偏移量,而不是窗口。
来自文档的说明:
备注:jQuery不支持获取隐藏元素的偏移坐标或计算在body元素上设置的边框、边距或内边距。
一些CSS应该能解决奇怪的结果: http://api.jquery.com/offset/
body { margin: 0; padding: 0; border: none; }

我已将边距和内边距设置为0,但是我的网站仍然存在问题。我正在尝试在fiddle中重现此问题,但目前还没有任何运气。 - mpen
这是链接:http://jsfiddle.net/xGy4N/ 在CSS中有些不同...但我不确定是什么。 - mpen
那是黑色的10像素border-top。 :) - Matthew Blancarte
糟糕!我甚至没有注意到我有一个边框。难道没有任何补偿的方法吗? - mpen
你有两个选择。如果这是一个你为自己的东西编写的一次性方法,只需从你的fixedPosition方法中减去10即可。如果你想要分发或共享这个方法,你应该编写一个方法来处理任何可能会影响偏移量的css值。 - Matthew Blancarte
是的,但我想知道有没有简单的方法来确定它偏差了多少,但我已经弄清楚了 :-) - mpen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接