javascript - div - innerhtml jquery ejemplos
Recuperar la posiciĆ³n(X, Y) de un elemento HTML (24)
Obtener la posición de div con respecto a la izquierda y la parte superior
var elm = $(''#div_id''); //get the div
var posY_top = elm.offset().top; //get the position from top
var posX_left = elm.offset().left; //get the position from left
Quiero saber cómo obtener la posición X e Y de elementos HTML como img
y div
en JavaScript.
¿Qué tal algo como esto? Al pasar el ID del elemento y devolverá la izquierda o la parte superior, también podemos combinarlos:
1) encontrar a la izquierda
function findLeft(element) {
var rec = document.getElementById(element).getBoundingClientRect();
return rec.left + window.scrollX;
} //call it like findLeft(''#header'');
2) encontrar top
function findTop(element) {
var rec = document.getElementById(element).getBoundingClientRect();
return rec.top + window.scrollY;
} //call it like findTop(''#header'');
o 3) encontrar a la izquierda y arriba juntos
function findTopLeft(element) {
var rec = document.getElementById(element).getBoundingClientRect();
return {top: rec.top + window.scrollY, left: rec.left + window.scrollX};
} //call it like findTopLeft(''#header'');
Dado que los diferentes navegadores están representando borde, relleno, margen y etc. de manera diferente. Escribí una pequeña función para recuperar las posiciones superior e izquierda de un elemento específico en cada elemento raíz que desee en una dimensión precisa:
function getTop(root, offset) {
var rootRect = root.getBoundingClientRect();
var offsetRect = offset.getBoundingClientRect();
return offsetRect.top - rootRect.top;
}
Para recuperar la posición izquierda debes devolver:
return offsetRect.left - rootRect.left;
Después de mucha investigación y pruebas esto parece funcionar
function getPosition(e) {
var isNotFirefox = (navigator.userAgent.toLowerCase().indexOf(''firefox'') == -1);
var x = 0, y = 0;
while (e) {
x += e.offsetLeft - e.scrollLeft + (isNotFirefox ? e.clientLeft : 0);
y += e.offsetTop - e.scrollTop + (isNotFirefox ? e.clientTop : 0);
e = e.offsetParent;
}
return { x: x + window.scrollX, y: y + window.scrollY };
}
Diferencia entre pequeño y pequeño.
function getPosition( el ) {
var x = 0;
var y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
x += el.offsetLeft - el.scrollLeft;
y += el.offsetTop - el.scrollTop;
el = el.offsetParent;
}
return { top: y, left: x };
}
Mira un ejemplo de coordenadas: http://javascript.info/tutorial/coordinates
El enfoque correcto es usar element.getBoundingClientRect()
:
var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);
Internet Explorer ha admitido esto desde que es probable que te importe y finalmente se estandarizó en las vistas de CSSOM . Todos los otros navegadores lo adoptaron hace mucho tiempo .
Algunos navegadores también devuelven las propiedades de alto y ancho, aunque esto no es estándar. Si le preocupa la compatibilidad anterior con el navegador, verifique las revisiones de esta respuesta para una implementación degradante optimizada.
Los valores devueltos por element.getBoundingClientRect()
son relativos a la ventana element.getBoundingClientRect()
. Si lo necesita en relación con otro elemento, simplemente reste un rectángulo del otro:
var bodyRect = document.body.getBoundingClientRect(),
elemRect = element.getBoundingClientRect(),
offset = elemRect.top - bodyRect.top;
alert(''Element is '' + offset + '' vertical pixels from <body>'');
El enfoque más limpio que he encontrado es una versión simplificada de la técnica utilizada por la offset
de jQuery. Similar a algunas de las otras respuestas, comienza con getBoundingClientRect
; luego utiliza la window
y el elemento de documentElement
para ajustar la posición de desplazamiento, así como elementos como el margen en el body
(a menudo el valor predeterminado).
var rect = el.getBoundingClientRect();
var docEl = document.documentElement;
var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;
var els = document.getElementsByTagName("div");
var docEl = document.documentElement;
for (var i = 0; i < els.length; i++) {
var rect = els[i].getBoundingClientRect();
var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;
els[i].innerHTML = "<b>" + rectLeft + ", " + rectTop + "</b>";
}
div {
width: 100px;
height: 100px;
background-color: red;
border: 1px solid black;
}
#rel {
position: relative;
left: 10px;
top: 10px;
}
#abs {
position: absolute;
top: 250px;
left: 250px;
}
<div id="rel"></div>
<div id="abs"></div>
<div></div>
Es posible que le sirvan mejor utilizando un marco de JavaScript, que tiene funciones para devolver dicha información (¡y mucho más!) De una manera independiente del navegador. Aquí hay algunos:
Con estos marcos, podrías hacer algo como: $(''id-of-img'').top
para obtener la coordenada y píxel de la imagen.
Este es el mejor código que he logrado crear (también funciona en iframes, a diferencia de jQuery''s offset ()). Parece que el webkit tiene un poco de un comportamiento diferente.
Basado en el comentario de meouw:
function getOffset( el ) {
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
// chrome/safari
if ($.browser.webkit) {
el = el.parentNode;
} else {
// firefox/IE
el = el.offsetParent;
}
}
return { top: _y, left: _x };
}
Esto funcionó para mí (modificado de la respuesta más votada):
function getOffset(el) {
const rect = el.getBoundingClientRect();
return {
left: rect.left + window.scrollX,
top: rect.top + window.scrollY
};
}
Usando esto podemos llamar
getOffset(element).left
o
getOffset(element).top
Las bibliotecas hacen todo lo posible para obtener compensaciones precisas para un elemento.
Aquí hay una función simple que hace el trabajo en todas las circunstancias que he probado.
function getOffset( el ) {
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
el = el.offsetParent;
}
return { top: _y, left: _x };
}
var x = getOffset( document.getElementById(''yourElId'') ).left;
Lo hice así, por lo que era compatible con los navegadores antiguos.
// For really old browser''s or incompatible ones
function getOffsetSum(elem) {
var top = 0,
left = 0,
bottom = 0,
right = 0
var width = elem.offsetWidth;
var height = elem.offsetHeight;
while (elem) {
top += elem.offsetTop;
left += elem.offsetLeft;
elem = elem.offsetParent;
}
right = left + width;
bottom = top + height;
return {
top: top,
left: left,
bottom: bottom,
right: right,
}
}
function getOffsetRect(elem) {
var box = elem.getBoundingClientRect();
var body = document.body;
var docElem = document.documentElement;
var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
var clientTop = docElem.clientTop;
var clientLeft = docElem.clientLeft;
var top = box.top + scrollTop - clientTop;
var left = box.left + scrollLeft - clientLeft;
var bottom = top + (box.bottom - box.top);
var right = left + (box.right - box.left);
return {
top: Math.round(top),
left: Math.round(left),
bottom: Math.round(bottom),
right: Math.round(right),
}
}
function getOffset(elem) {
if (elem) {
if (elem.getBoundingClientRect) {
return getOffsetRect(elem);
} else { // old browser
return getOffsetSum(elem);
}
} else
return null;
}
Más sobre coordenadas en JavaScript aquí: http://javascript.info/tutorial/coordinates
Los elementos HTML en la mayoría de los navegadores tendrán: -
offsetLeft
offsetTop
Estos especifican la posición del elemento relativo a su padre más cercano que tiene diseño. A este padre a menudo se puede acceder desde la propiedad offsetParent.
IE y FF3 tienen
clientLeft
clientTop
Estas propiedades son menos comunes, especifican una posición de elementos con su área de cliente principal (el área rellenada es parte del área de cliente pero el borde y el margen no lo son).
Para recuperar la posición relativa a la página de manera eficiente y sin usar una función recursiva: (también incluye IE)
var element = document.getElementById(''elementId''); //replace elementId with your element''s Id.
var rect = element.getBoundingClientRect();
var elementLeft,elementTop; //x and y
var scrollTop = document.documentElement.scrollTop?
document.documentElement.scrollTop:document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft?
document.documentElement.scrollLeft:document.body.scrollLeft;
elementTop = rect.top+scrollTop;
elementLeft = rect.left+scrollLeft;
Puede agregar dos propiedades a Element.prototype
para obtener la parte superior / izquierda de cualquier elemento.
Object.defineProperty( Element.prototype, ''documentOffsetTop'', {
get: function () {
return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 );
}
} );
Object.defineProperty( Element.prototype, ''documentOffsetLeft'', {
get: function () {
return this.offsetLeft + ( this.offsetParent ? this.offsetParent.documentOffsetLeft : 0 );
}
} );
Esto se llama así:
var x = document.getElementById( ''myDiv'' ).documentOffsetLeft;
Aquí hay una demostración que compara los resultados con jQuery offset().top
y .left
: http://jsfiddle.net/ThinkingStiff/3G7EZ/
Si bien es muy probable que esto se pierda al final de tantas respuestas, las mejores soluciones aquí no funcionaron para mí.
Por lo que pude ver, ninguna de las otras respuestas me habría ayudado.
Situacion
En una página HTML5 tenía un menú que era un elemento de navegación dentro de un encabezado (no el encabezado EL sino un encabezado en otro elemento).
Quería que la navegación se mantuviera en la parte superior una vez que el usuario se desplazara hacia ella, pero antes de esto, el encabezado estaba en una posición absoluta (para que pudiera superponer algo más).
Las soluciones anteriores nunca activaron un cambio porque .offsetTop no iba a cambiar ya que este era un elemento posicionado absoluto. Además, la propiedad .scrollTop era simplemente la parte superior del elemento más superior ... es decir, 0 y siempre sería 0.
Cualquier prueba que realicé utilizando estos dos (y lo mismo con los resultados de getBoundingClientRect) no me diría si la parte superior de la barra de navegación alguna vez se desplazó hasta la parte superior de la página visible (nuevamente, como se informó en la consola, simplemente mantuvieron los mismos números mientras se desplazaban) ocurrió).
Solución
La solución para mí fue utilizar
window.visualViewport.pageTop
El valor de la propiedad pageTop refleja la sección visible de la pantalla, por lo que me permite rastrear dónde se encuentra un elemento en referencia a los límites del área visible.
Probablemente no sea necesario decirlo, en cualquier momento en el que tenga que ver con el desplazamiento, espero usar esta solución para responder de manera programática al movimiento de los elementos que se están desplazando.
Espero que ayude a alguien más.
NOTA IMPORTANTE: Esto parece funcionar en Chrome y Opera actualmente y definitivamente no en Firefox (6-2018) ... hasta que Firefox admita visualViewport. Recomiendo NO usar este método (y espero que lo hagan pronto ... hace mucho más sentido que el resto).
ACTUALIZAR:
Sólo una nota con respecto a esta solución.
Si bien todavía encuentro lo que descubrí que es muy valioso para situaciones en las que "... responda de manera programática al movimiento de elementos que se están desplazando". es aplicable. La mejor solución para el problema que tuve fue usar CSS para establecer la posición: pegado en el elemento. Si usa el adhesivo, puede hacer que un elemento permanezca en la parte superior sin usar javascript (NOTA: hay veces que esto no funcionará tan eficazmente como cambiar el elemento a fijo, pero para la mayoría de los usos, el enfoque pegajoso probablemente sea superior)
ACTUALIZACIÓN01:
Así que me di cuenta de que para una página diferente tenía un requisito en el que necesitaba detectar la posición de un elemento en una configuración de desplazamiento ligeramente compleja (paralaje más elementos que se desplazan como parte de un mensaje). Me di cuenta en ese escenario que lo siguiente proporcionaba el valor que utilicé para determinar cuándo hacer algo:
let bodyElement = document.getElementsByTagName(''body'')[0];
let elementToTrack = bodyElement.querySelector(''.trackme'');
trackedObjPos = elementToTrack.getBoundingClientRect().top;
if(trackedObjPos > 264)
{
bodyElement.style.cssText = '''';
}
Espero que esta respuesta sea más útil ahora.
Si está utilizando jQuery, esta podría ser una solución simple:
<script>
var el = $("#element");
var position = el.position();
console.log( "left: " + position.left + ", top: " + position.top );
</script>
Si la página incluye, al menos, cualquier "DIV", la función dada por meouw arroja el valor "Y" más allá de los límites de la página actual. Para encontrar la posición exacta, necesita manejar tanto offsetParent''s como parentNode''s.
Pruebe el código que se proporciona a continuación (se comprueba para FF2):
var getAbsPosition = function(el){
var el2 = el;
var curtop = 0;
var curleft = 0;
if (document.getElementById || document.all) {
do {
curleft += el.offsetLeft-el.scrollLeft;
curtop += el.offsetTop-el.scrollTop;
el = el.offsetParent;
el2 = el2.parentNode;
while (el2 != el) {
curleft -= el2.scrollLeft;
curtop -= el2.scrollTop;
el2 = el2.parentNode;
}
} while (el.offsetParent);
} else if (document.layers) {
curtop += el.y;
curleft += el.x;
}
return [curtop, curleft];
};
Si quieres hacerlo solo en javascript . Que aquí están los trazadores de líneas . Es más simple y fácil de usar getBoundingClientRect ()
window.scrollX + document.querySelector(''#elementId'').getBoundingClientRect().left // X
window.scrollY + document.querySelector(''#elementId'').getBoundingClientRect().top // Y
La primera línea devolverá offsetLeft decir X en relación con el documento
Y la segunda línea devolverá offsetTop decir Y en relación con el documento
element.getBoundingClientRect() es una función javascript que devuelve la posición del elemento en relación con la ventana element.getBoundingClientRect() .
Si usa jQuery, el complemento de dimensiones es excelente y le permite especificar exactamente lo que desea.
p.ej
Posición relativa, posición absoluta, posición absoluta sin relleno, con relleno ...
Sigue, digamos que hay mucho que puedes hacer con eso.
Además, la ventaja de usar jQuery es su tamaño de archivo ligero y su fácil uso, no volverá a JavaScript sin él después.
Solo pensé que también tiraría esto por ahí.
No he podido probarlo en navegadores antiguos, pero funciona en la última versión 3. :)
Element.prototype.getOffsetTop = function() {
return ( this.parentElement )? this.offsetTop + this.parentElement.getOffsetTop(): this.offsetTop;
};
Element.prototype.getOffsetLeft = function() {
return ( this.parentElement )? this.offsetLeft + this.parentElement.getOffsetLeft(): this.offsetLeft;
};
Element.prototype.getOffset = function() {
return {''left'':this.getOffsetLeft(),''top'':this.getOffsetTop()};
};
Tomé la respuesta de @ meouw, la agregué en el clientLeft que permite el borde y luego creé tres versiones:
getAbsoluteOffsetFromBody - similar a @ meouw''s, obtiene la posición absoluta con respecto al cuerpo o elemento html del documento (según el modo de peculiaridades)
getAbsoluteOffsetFromGivenElement: devuelve la posición absoluta relativa al elemento dado (relativeEl). Tenga en cuenta que el elemento dado debe contener el elemento el, o se comportará de la misma manera que getAbsoluteOffsetFromBody. Esto es útil si tiene dos elementos contenidos en otro elemento (conocido) (opcionalmente, varios nodos en el árbol de nodos) y desea que estén en la misma posición.
getAbsoluteOffsetFromRelative: devuelve la posición absoluta en relación con el primer elemento padre con position: relative. Esto es similar a getAbsoluteOffsetFromGivenElement, por el mismo motivo, pero solo irá tan lejos como el primer elemento coincidente.
getAbsoluteOffsetFromBody = function( el )
{ // finds the offset of el from the body or html element
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
{
_x += el.offsetLeft - el.scrollLeft + el.clientLeft;
_y += el.offsetTop - el.scrollTop + el.clientTop;
el = el.offsetParent;
}
return { top: _y, left: _x };
}
getAbsoluteOffsetFromGivenElement = function( el, relativeEl )
{ // finds the offset of el from relativeEl
var _x = 0;
var _y = 0;
while( el && el != relativeEl && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
{
_x += el.offsetLeft - el.scrollLeft + el.clientLeft;
_y += el.offsetTop - el.scrollTop + el.clientTop;
el = el.offsetParent;
}
return { top: _y, left: _x };
}
getAbsoluteOffsetFromRelative = function( el )
{ // finds the offset of el from the first parent with position: relative
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
{
_x += el.offsetLeft - el.scrollLeft + el.clientLeft;
_y += el.offsetTop - el.scrollTop + el.clientTop;
el = el.offsetParent;
if (el != null)
{
if (getComputedStyle !== ''undefined'')
valString = getComputedStyle(el, null).getPropertyValue(''position'');
else
valString = el.currentStyle[''position''];
if (valString === "relative")
el = null;
}
}
return { top: _y, left: _x };
}
Si aún tiene problemas, especialmente en relación con el desplazamiento, puede intentar visitar http://www.greywyvern.com/?post=331 : noté al menos una pieza de código cuestionable en getStyle que debería estar bien suponiendo que los navegadores se comporten , pero no he probado el resto en absoluto.
Usé con éxito la solución de Andy E para posicionar un modo bootstrap 2 dependiendo del enlace en la fila de la tabla en el que un usuario hace clic. La página es una página de Tapestry 5 y javascript se importa a continuación en la clase de página java.
javascript:
function setLinkPosition(clientId){
var bodyRect = document.body.getBoundingClientRect(),
elemRect = clientId.getBoundingClientRect(),
offset = elemRect.top - bodyRect.top;
offset = offset + 20;
$(''#serviceLineModal'').css("top", offset);
}
Mi código modal:
<div id="serviceLineModal" class="modal hide fade add-absolute-position" data-backdrop="static"
tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="top:50%;">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
<h3 id="myModalLabel">Modal header</h3>
</div>
<div class="modal-body">
<t:zone t:id="modalZone" id="modalZone">
<p>You selected service line number: ${serviceLineNumberSelected}</p>
</t:zone>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<!-- <button class="btn btn-primary">Save changes</button> -->
</div>
El enlace en el bucle:
<t:loop source="servicesToDisplay" value="service" encoder="encoder">
<tr style="border-right: 1px solid black;">
<td style="white-space:nowrap;" class="add-padding-left-and-right no-border">
<a t:type="eventLink" t:event="serviceLineNumberSelected" t:context="service.serviceLineNumber"
t:zone="pageZone" t:clientId="modalLink${service.serviceLineNumber}"
onmouseover="setLinkPosition(this);">
<i class="icon-chevron-down"></i> <!-- ${service.serviceLineNumber} -->
</a>
</td>
Y el código java en la clase de la página:
void onServiceLineNumberSelected(String number){
checkForNullSession();
serviceLineNumberSelected = number;
addOpenServiceLineDialogCommand();
ajaxResponseRenderer.addRender(modalZone);
}
protected void addOpenServiceLineDialogCommand() {
ajaxResponseRenderer.addCallback(new JavaScriptCallback() {
@Override
public void run(JavaScriptSupport javascriptSupport) {
javascriptSupport.addScript("$(''#serviceLineModal'').modal(''show'');");
}
});
}
Espero que esto ayude a alguien, este post ayudó.
jQuery .offset() obtendrá las coordenadas actuales del primer elemento, o establecerá las coordenadas de cada elemento, en el conjunto de elementos emparejados, en relación con el documento.