Question

Quelle est la bonne façon d'obtenir la position d'un élément sur la page par rapport à la fenêtre (plutôt que le document). fonction jQuery.offset semblait prometteur:

  

Obtenir les coordonnées courantes du premier élément, ou de définir la   les coordonnées de chaque élément, dans l'ensemble des éléments appariés, par rapport   au document.

Mais c'est par rapport au document. Y at-il une méthode équivalente qui renvoie les décalages par rapport à la fenêtre?

Était-ce utile?

La solution

Regardez dans le plug-in Dimensions, en particulier scrollTop() / scrollLeft(). Informations peuvent être trouvées à l'adresse http://api.jquery.com/scrollTop .

Autres conseils

La meilleure façon de déterminer la taille et la position d'un élément est d'appeler son getBoundingClientRect () Méthode de . Cette méthode retourne les positions d'élément dans les coordonnées de fenêtre. Il prévoit pas d'arguments et retourne un objet propriétés gauche, droite, haut et bas . Les propriétés haut et à gauche donnent X et Y les coordonnées du coin supérieur gauche de l'élément et les propriétés de droite et du bas donner les coordonnées du coin inférieur droit.

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

pris en charge partout.

Voici deux fonctions pour obtenir la hauteur de la page et les montants de défilement (x, y) sans l'utilisation du plug-in (dimensions) pléthorique:

// 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
}

jQuery.offset doit être combiné avec scrollTop et href="http://api.jquery.com/scrollLeft/" rel="noreferrer"> scrollLeft comme le montre cette schéma:

décalage défilement de la fenêtre et de l'élément

Démo:

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>

Voici une fonction qui calcule la position actuelle d'un élément dans la fenêtre:

/**
 * 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))
    ];
}

Les valeurs de rendement sont calculés comme suit:

Utilisation:

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

Démo:

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>

Je trouve que la réponse par cballou ne fonctionnait plus dans Firefox au janvier 2014. Plus précisément, if (self.pageYOffset) n'a pas déclenché si le client avait droit défiler, mais pas vers le bas - parce que 0 est un numéro de Falsey. Ce passé inaperçu pendant un certain temps parce que Firefox a soutenu document.body.scrollLeft / Top, mais cela ne fonctionne plus pour moi (sur Firefox 26,0).

Voici ma solution modifiée:

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];
};

Testé et travailler dans FF26, 31 Chrome, IE11. Presque certainement travaille sur les anciennes versions de tous.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top