jQuery récupère l'emplacement d'un élément par rapport à la fenêtre

168

Étant donné un ID HTML DOM, comment obtenir la position d'un élément par rapport à la fenêtre dans JavaScript / JQuery? Ce n'est pas la même chose que relative au document ni au parent offset puisque l'élément peut être à l'intérieur d'une iframe ou de certains autres éléments. J'ai besoin d'obtenir l'emplacement à l'écran du rectangle de l'élément (comme dans la position et la dimension) tel qu'il est actuellement affiché. Les valeurs négatives sont acceptables si l'élément est actuellement hors écran (a été défilé).

Ceci est pour une application iPad (WebKit / WebView). Chaque fois que l'utilisateur appuie sur un lien spécial dans un UIWebView, je suis censé ouvrir une vue popover qui affiche des informations supplémentaires sur le lien. La vue popover doit afficher une flèche qui pointe vers la partie de l'écran qui l'invoque.

adib
la source

Réponses:

264

Initialement, saisissez la position .offset de l'élément et calculez sa position relative par rapport à la fenêtre

Reportez - vous :
1. offset
2. scroll
3. scrollTop

Vous pouvez essayer ce violon

Suivre quelques lignes de code explique comment cela peut être résolu

lorsque l' événement .scroll est effectué, nous calculons la position relative de l'élément par rapport à l'objet window

$(window).scroll(function () {
    console.log(eTop - $(window).scrollTop());
});

lorsque le défilement est effectué dans le navigateur, nous appelons la fonction de gestionnaire d'événements ci-dessus

extrait de code


function log(txt) {
  $("#log").html("location : <b>" + txt + "</b> px")
}

$(function() {
  var eTop = $('#element').offset().top; //get the offset top of the element
  log(eTop - $(window).scrollTop()); //position of the ele w.r.t window

  $(window).scroll(function() { //when window is scrolled
    log(eTop - $(window).scrollTop());
  });
});
#element {
  margin: 140px;
  text-align: center;
  padding: 5px;
  width: 200px;
  height: 200px;
  border: 1px solid #0099f9;
  border-radius: 3px;
  background: #444;
  color: #0099d9;
  opacity: 0.6;
}
#log {
  position: fixed;
  top: 40px;
  left: 40px;
  color: #333;
}
#scroll {
  position: fixed;
  bottom: 10px;
  right: 10px;
  border: 1px solid #000;
  border-radius: 2px;
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="log"></div>

<div id="element">Hello
  <hr>World</div>
<div id="scroll">Scroll Down</div>

jterry
la source
1
Merci pour le script. Cela semble fonctionner sur le bureau mais ne fonctionne pas sur l'iPad. Il semble que $ (window) .scrollTop () et $ (window) .scrollLeft () ne sont pas mis à jour dans l'iPad. Vous pouvez essayer ma version via jsbin.com/ogiwu4/5
adib
2
Ils ne sont pas mis à jour sur l'iPad car la fenêtre elle-même ne défile pas - l'utilisateur fait défiler la fenêtre. C'est le cas pour un site Web de base de toute façon, pas sûr de celui qui cible les appareils mobiles, qui a probablement plus d'options là-bas.
eselk
Cela devrait échouer lorsqu'un élément se trouve dans un autre élément déroulant, e. g. <div>. Vous ne considérez que le défilement du document, mais pas l'autre élément de défilement.
ygoe
71

Essayez la boîte englobante. C'est simple:

var leftPos  = $("#element")[0].getBoundingClientRect().left   + $(window)['scrollLeft']();
var rightPos = $("#element")[0].getBoundingClientRect().right  + $(window)['scrollLeft']();
var topPos   = $("#element")[0].getBoundingClientRect().top    + $(window)['scrollTop']();
var bottomPos= $("#element")[0].getBoundingClientRect().bottom + $(window)['scrollTop']();
prograhammer
la source
7
getBoundingClientRect () est la réponse à ce problème. Merci prograhammer.
Vlad Lego
1
cela a bien fonctionné. J'ai juste dû inclure du code pour corriger mon scroll, en plus de votre scrollLetf et scrollTop: topPos = topPos - $ (window) .scrollTop (); leftPos = leftPos - $ (fenêtre) .scrollLeft (); rightPos = rightPos - $ (fenêtre) .scrollTop (); bottomPos = bottomPos - $ (fenêtre) .scrollLeft ();
César
1
le jour où les gens vont apprendre à conclure les choses dans une belle méthode utile
mmm
@Noldorin Le support sur IE / Edge me semble bon: caniuse.com/#feat=getboundingclientrect
prograhammer
1
@prograhammer Mon mal, tu as raison. J'ai lu ceci sur un site Web et j'ai pris sa parole au pied de la lettre ... il s'avère que c'était faux (ou du moins ne fonctionne pas sur l'ancien IE).
Noldorin
6
function getWindowRelativeOffset(parentWindow, elem) {
        var offset = {
            left : 0,
            top : 0
        };
        // relative to the target field's document
        offset.left = elem.getBoundingClientRect().left;
        offset.top = elem.getBoundingClientRect().top;
        // now we will calculate according to the current document, this current
        // document might be same as the document of target field or it may be
        // parent of the document of the target field
        var childWindow = elem.document.frames.window;
        while (childWindow != parentWindow) {
            offset.left = offset.left + childWindow.frameElement.getBoundingClientRect().left;
            offset.top = offset.top + childWindow.frameElement.getBoundingClientRect().top;
            childWindow = childWindow.parent;
        }
        return offset;
    };

tu peux l'appeler comme ça

getWindowRelativeOffset(top, inputElement);

Je me concentre pour IE uniquement selon mes besoins, mais la même chose peut être faite pour d'autres navigateurs

Imran Ansari
la source
4

Cela ressemble plus à une info-bulle pour le lien sélectionné. Il existe de nombreuses info-bulles jQuery, essayez jQuery qTip . Il a beaucoup d'options et il est facile de changer les styles.

Sinon, si vous souhaitez le faire vous-même, vous pouvez utiliser jQuery .position(). Plus d'infos .position()sur http://api.jquery.com/position/

$("#element").position(); renverra la position actuelle d'un élément par rapport au parent offset.

Il existe également le jQuery .offset (); qui renverra la position par rapport au document.

jhanifen
la source
2
Ce n'est pas vraiment une info-bulle, mais d'ouvrir un widget d'interface utilisateur natif pour ajouter des annotations.
adib
1
    function trbl(e, relative) {
            var r = $(e).get(0).getBoundingClientRect(); relative = $(relative);

            return {
                    t : r.top    + relative['scrollTop'] (),
                    r : r.right  + relative['scrollLeft'](),
                    b : r.bottom + relative['scrollTop'] (),
                    l : r.left   + relative['scrollLeft']() 

            }
    }

    // Example
    trbl(e, window);
mmm
la source
1

Essayez ceci pour obtenir l'emplacement d'un élément par rapport à la fenêtre.

        $("button").click(function(){
            var offset = $("#simplebox").offset();
            alert("Current position of the box is: (left: " + offset.left + ", top: " + offset.top + ")");
        });
    #simplebox{
        width:150px;
        height:100px;
        background: #FBBC09;
        margin: 150px 100px;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Get Box Position</button>
    <p><strong>Note:</strong> Play with the value of margin property to see how the jQuery offest() method works.</p>
    <div id="simplebox"></div>

Voir plus @ Obtenir la position d'un élément par rapport au document avec jQuery

Ketan Savaliya
la source