javascript - mostrar - Usar jquery para obtener la posición del elemento relativa a la ventana gráfica
scrolltop javascript ejemplos (6)
¿Cuál es la forma correcta de obtener la posición de un elemento en la página en relación con la ventana gráfica (en lugar del documento)? jQuery.offset
función jQuery.offset
parecía prometedora:
Obtenga las coordenadas actuales del primer elemento o establezca las coordenadas de cada elemento en el conjunto de elementos coincidentes, relativo al documento.
Pero eso es relativo al documento. ¿Hay un método equivalente que devuelva compensaciones en relación con la ventana gráfica?
Aquí hay dos funciones para obtener la altura de la página y las cantidades de desplazamiento (x, y) sin el uso del complemento (hinchado) de dimensiones:
// 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
}
Aquí hay una función que calcula la posición actual de un elemento dentro de la ventana gráfica:
/**
* 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))
];
}
Los valores de retorno se calculan de la siguiente manera:
Uso:
visibility($(''#example'')); // returns [0.3742887830933581, 0.6103752759381899]
Manifestación:
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>
Descubrí que la respuesta de cballou ya no funcionaba en Firefox a partir de enero de 2014. Específicamente, if (self.pageYOffset)
no se if (self.pageYOffset)
si el cliente se había desplazado hacia la derecha, pero no hacia abajo, porque 0
es un número falsey. Esto no se detectó por un tiempo porque Firefox era compatible con document.body.scrollLeft
/ Top
, pero esto ya no funciona para mí (en Firefox 26.0).
Aquí está mi solución modificada:
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];
};
Probado y trabajando en FF26, Chrome 31, IE11. Casi con certeza funciona en versiones anteriores de todos ellos.
La forma más fácil de determinar el tamaño y la posición de un elemento es llamar a su método getBoundingClientRect () . Este método devuelve las posiciones de los elementos en las coordenadas de las vistas. No espera argumentos y devuelve un objeto con propiedades izquierda, derecha, arriba y abajo . Las propiedades izquierda y superior dan las coordenadas X e Y de la esquina superior izquierda del elemento y las propiedades derecha e inferior dan las coordenadas de la esquina inferior derecha.
element.getBoundingClientRect(); // Get position in viewport coordinates
Compatible en todas partes.
Mire en el plugin Dimensions, específicamente scrollTop()
/ scrollLeft()
. La información se puede encontrar en http://api.jquery.com/scrollTop .
jQuery.offset
debe combinarse con scrollTop
y scrollLeft
como se muestra en este diagrama:
Manifestación:
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>