2009-10-14 106 views
99

获取页面元素相对于视口(而不是文档)的位置的正确方法是什么? jQuery.offset功能似乎有希望的:使用jquery获取元素相对于视口的位置

获取所述第一元件的当前坐标,或设置的每个元件的坐标 ,在匹配的元素,相对于 到文档的。

但这是相对于文件。是否有一个等价的方法返回相对于视口的偏移量?

+5

注意:请参阅@Igor G的答案... – 2013-10-26 20:54:09

+3

对于DA,您应该真正将Igor G的答案设置为接受状态,这是一种挽救生命! – 2015-08-16 12:02:19

回答

24

调查Dimensions插件,具体为scrollTop()/scrollLeft()。信息可在http://api.jquery.com/scrollTop找到。

+8

我不想使用其他插件,但$(window).scrollTop()正是我需要的!谢谢! – 2009-10-14 16:28:41

+15

尺寸插件现在是jQuery核心的一部分。 ViewPort插件也很有用:http://www.appelsiini.net/projects/viewport – StriplingWarrior 2011-06-03 18:38:45

+0

这应该在不使用插件的情况下完成。 – landed 2016-06-23 13:38:39

38

这里有两个函数来获取页面的高度和滚动量(X,Y)不使用(臃肿)尺寸的插件:

// getPageScroll() by quirksmode.com 
function getPageScroll() { 
    var xScroll, yScroll; 
    if (self.pageYOffset) { 
     yScroll = self.pageYOffset; 
     xScroll = self.pageXOffset; 
    } else if (document.documentElement && document.documentElement.scrollTop) { 
     yScroll = document.documentElement.scrollTop; 
     xScroll = document.documentElement.scrollLeft; 
    } else if (document.body) {// all other Explorers 
     yScroll = document.body.scrollTop; 
     xScroll = document.body.scrollLeft; 
    } 
    return new Array(xScroll,yScroll) 
} 

// Adapted from getPageSize() by quirksmode.com 
function getPageHeight() { 
    var windowHeight 
    if (self.innerHeight) { // all except Explorer 
     windowHeight = self.innerHeight; 
    } else if (document.documentElement && document.documentElement.clientHeight) { 
     windowHeight = document.documentElement.clientHeight; 
    } else if (document.body) { // other Explorers 
     windowHeight = document.body.clientHeight; 
    } 
    return windowHeight 
} 
+0

谢谢,cballou。再加上那个武器! – 2009-10-14 16:29:35

+0

这太棒了。很有用。 – Jimmy 2010-10-18 15:25:39

+0

出于好奇,为什么你在这种情况下使用“自我”属性而不是窗口? – dkugappi 2012-01-28 16:40:17

250

最简单的方法来确定的大小和位置一个元素就是调用它的 getBoundingClientRect()方法。此方法返回视口坐标中的元素位置。它预计不存在任何参数并返回 属性左侧,右侧,顶部底部的对象。左侧属性和顶部属性给出了元素左上角的X和Y坐标,右下角的属性 给出了右下角的坐标。

element.getBoundingClientRect(); // Get position in viewport coordinates

无处不支持。

+13

这是令人难以置信的这种方法是由IE5添加...当一些东西好,很好! – 2013-03-09 08:51:36

+36

这显然是问题的最佳答案。 – 6124j50n 2013-10-07 02:40:08

+0

这看起来不错,但它并没有考虑用户在移动Safari 7上的放大。 – MyNameIsKo 2014-02-05 16:47:45

0

我发现,通过cballou答案是不再在Firefox工作作为2014年一月的具体,如果客户端已滚动权if (self.pageYOffset)没有触发,但不下来 - 因为0是falsey数。由于Firefox支持document.body.scrollLeft/Top,但这已不再适用于我(Firefox 26.0)。

这里是我修改的方案:

var getPageScroll = function(document_el, window_el) { 
    var xScroll = 0, yScroll = 0; 
    if (window_el.pageYOffset !== undefined) { 
    yScroll = window_el.pageYOffset; 
    xScroll = window_el.pageXOffset; 
    } else if (document_el.documentElement !== undefined && document_el.documentElement.scrollTop) { 
    yScroll = document_el.documentElement.scrollTop; 
    xScroll = document_el.documentElement.scrollLeft; 
    } else if (document_el.body !== undefined) {// all other Explorers 
    yScroll = document_el.body.scrollTop; 
    xScroll = document_el.body.scrollLeft; 
    } 
    return [xScroll,yScroll]; 
}; 

测试和FF26,铬31,IE11工作。几乎可以肯定,它们都适用于所有版本的旧版本。

16

jQuery.offset需要与scrollTopscrollLeft进行组合,如该图所示:

viewport scroll and element offset

演示:

function getViewportOffset($e) { 
 
    var $window = $(window), 
 
    scrollLeft = $window.scrollLeft(), 
 
    scrollTop = $window.scrollTop(), 
 
    offset = $e.offset(), 
 
    rect1 = { x1: scrollLeft, y1: scrollTop, x2: scrollLeft + $window.width(), y2: scrollTop + $window.height() }, 
 
    rect2 = { x1: offset.left, y1: offset.top, x2: offset.left + $e.width(), y2: offset.top + $e.height() }; 
 
    return { 
 
    left: offset.left - scrollLeft, 
 
    top: offset.top - scrollTop, 
 
    insideViewport: rect1.x1 < rect2.x2 && rect1.x2 > rect2.x1 && rect1.y1 < rect2.y2 && rect1.y2 > rect2.y1 
 
    }; 
 
} 
 
$(window).on("load scroll resize", function() { 
 
    var viewportOffset = getViewportOffset($("#element")); 
 
    $("#log").text("left: " + viewportOffset.left + ", top: " + viewportOffset.top + ", insideViewport: " + viewportOffset.insideViewport); 
 
});
body { margin: 0; padding: 0; width: 1600px; height: 2048px; background-color: #CCCCCC; } 
 
#element { width: 384px; height: 384px; margin-top: 1088px; margin-left: 768px; background-color: #99CCFF; } 
 
#log { position: fixed; left: 0; top: 0; font: medium monospace; background-color: #EEE8AA; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 

 
<!-- scroll right and bottom to locate the blue square --> 
 
<div id="element"></div> 
 
<div id="log"></div>

+0

这对我来说很好,但我用它来确定工具提示是否超出界限,所以我修改了包含底部和右侧值:http:// jsfiddle.net/EY6Rk/21/ – Jordan 2015-03-25 14:02:51

+0

这是绝对的,无论如何,都是正确的答案。所有其他人都有问题取决于鼠标/滚动增量配置,浏览器,obj位置等。 – 2017-05-30 14:13:59

2

下面是计算一个函数元素w的当前位置ithin视:

/** 
* Calculates the position of a given element within the viewport 
* 
* @param {string} obj jQuery object of the dom element to be monitored 
* @return {array} An array containing both X and Y positions as a number 
* ranging from 0 (under/right of viewport) to 1 (above/left of viewport) 
*/ 
function visibility(obj) { 
    var winw = jQuery(window).width(), winh = jQuery(window).height(), 
     elw = obj.width(), elh = obj.height(), 
     o = obj[0].getBoundingClientRect(), 
     x1 = o.left - winw, x2 = o.left + elw, 
     y1 = o.top - winh, y2 = o.top + elh; 

    return [ 
     Math.max(0, Math.min((0 - x1)/(x2 - x1), 1)), 
     Math.max(0, Math.min((0 - y1)/(y2 - y1), 1)) 
    ]; 
} 

返回值的计算如下:

用法:

visibility($('#example')); // returns [0.3742887830933581, 0.6103752759381899] 

演示:

function visibility(obj) {var winw = jQuery(window).width(),winh = jQuery(window).height(),elw = obj.width(), 
 
    elh = obj.height(), o = obj[0].getBoundingClientRect(),x1 = o.left - winw, x2 = o.left + elw, y1 = o.top - winh, y2 = o.top + elh; return [Math.max(0, Math.min((0 - x1)/(x2 - x1), 1)),Math.max(0, Math.min((0 - y1)/(y2 - y1), 1))]; 
 
} 
 
setInterval(function() { 
 
    res = visibility($('#block')); 
 
    $('#x').text(Math.round(res[0] * 100) + '%'); 
 
    $('#y').text(Math.round(res[1] * 100) + '%'); 
 
}, 100);
#block { width: 100px; height: 100px; border: 1px solid red; background: yellow; top: 50%; left: 50%; position: relative; 
 
} #container { background: #EFF0F1; height: 950px; width: 1800px; margin-top: -40%; margin-left: -40%; overflow: scroll; position: relative; 
 
} #res { position: fixed; top: 0; z-index: 2; font-family: Verdana; background: #c0c0c0; line-height: .1em; padding: 0 .5em; font-size: 12px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="res"> 
 
    <p>X: <span id="x"></span></p> 
 
    <p>Y: <span id="y"></span></p> 
 
</div> 
 
<div id="container"><div id="block"></div></div>

相关问题