获取页面元素相对于视口(而不是文档)的位置的正确方法是什么? jQuery.offset
功能似乎有希望的:使用jquery获取元素相对于视口的位置
获取所述第一元件的当前坐标,或设置的每个元件的坐标 ,在匹配的元素,相对于 到文档的。
但这是相对于文件。是否有一个等价的方法返回相对于视口的偏移量?
获取页面元素相对于视口(而不是文档)的位置的正确方法是什么? jQuery.offset
功能似乎有希望的:使用jquery获取元素相对于视口的位置
获取所述第一元件的当前坐标,或设置的每个元件的坐标 ,在匹配的元素,相对于 到文档的。
但这是相对于文件。是否有一个等价的方法返回相对于视口的偏移量?
调查Dimensions插件,具体为scrollTop()
/scrollLeft()
。信息可在http://api.jquery.com/scrollTop找到。
我不想使用其他插件,但$(window).scrollTop()正是我需要的!谢谢! – 2009-10-14 16:28:41
尺寸插件现在是jQuery核心的一部分。 ViewPort插件也很有用:http://www.appelsiini.net/projects/viewport – StriplingWarrior 2011-06-03 18:38:45
这应该在不使用插件的情况下完成。 – landed 2016-06-23 13:38:39
这里有两个函数来获取页面的高度和滚动量(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
}
最简单的方法来确定的大小和位置一个元素就是调用它的 getBoundingClientRect()方法。此方法返回视口坐标中的元素位置。它预计不存在任何参数并返回 属性左侧,右侧,顶部和底部的对象。左侧属性和顶部属性给出了元素左上角的X和Y坐标,右下角的属性 给出了右下角的坐标。
element.getBoundingClientRect(); // Get position in viewport coordinates
无处不支持。
这是令人难以置信的这种方法是由IE5添加...当一些东西好,很好! – 2013-03-09 08:51:36
这显然是问题的最佳答案。 – 6124j50n 2013-10-07 02:40:08
这看起来不错,但它并没有考虑用户在移动Safari 7上的放大。 – MyNameIsKo 2014-02-05 16:47:45
我发现,通过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工作。几乎可以肯定,它们都适用于所有版本的旧版本。
jQuery.offset
需要与scrollTop
和scrollLeft
进行组合,如该图所示:
演示:
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>
这对我来说很好,但我用它来确定工具提示是否超出界限,所以我修改了包含底部和右侧值:http:// jsfiddle.net/EY6Rk/21/ – Jordan 2015-03-25 14:02:51
这是绝对的,无论如何,都是正确的答案。所有其他人都有问题取决于鼠标/滚动增量配置,浏览器,obj位置等。 – 2017-05-30 14:13:59
下面是计算一个函数元素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>
注意:请参阅@Igor G的答案... – 2013-10-26 20:54:09
对于DA,您应该真正将Igor G的答案设置为接受状态,这是一种挽救生命! – 2015-08-16 12:02:19