Wie kann ich überprüfen, ob ein Element wirklich sichtbar mit JavaScript ist? [Duplikat]

StackOverflow https://stackoverflow.com/questions/704758

  •  22-08-2019
  •  | 
  •  

Frage

    

Diese Frage bereits eine Antwort hier:

    
            
  •              Überprüfen Sie, ob Element sichtbar in DOM ist                                      18 Antworten                          
  •     
    

In JavaScript, wie würden Sie überprüfen, ob ein Element tatsächlich sichtbar ist?

Ich habe nicht nur meine die visibility Überprüfung und display Attribute. Ich meine, die Überprüfung, dass das Element nicht

ist
  • visibility: hidden oder display: none
  • unter einem anderen Element
  • gescrollt den Rand des Bildschirms aus

Aus technischen Gründen kann ich keine Skripte enthalten. Ich kann jedoch verwenden Prototype wie es bereits auf der Seite ist.

War es hilfreich?

Lösung

Für den Punkt 2.

Ich sehe, dass niemand zu verwenden document.elementFromPoint(x,y) vorgeschlagen hat, für mich ist es der schnellste Weg, um zu testen, ob ein Element verschachtelt ist oder von einem anderen versteckt. Sie können die Versätze des anvisierten Element an die Funktion übergeben.

Hier ist PPK Testseite auf elementFromPoint .

Andere Tipps

Ich weiß nicht, wie viel davon in älteren oder nicht-so-modernen Browsern unterstützt wird, aber ich bin mit so etwas wie diesem (ohne neeed für alle Bibliotheken):

function visible(element) {
  if (element.offsetWidth === 0 || element.offsetHeight === 0) return false;
  var height = document.documentElement.clientHeight,
      rects = element.getClientRects(),
      on_top = function(r) {
        var x = (r.left + r.right)/2, y = (r.top + r.bottom)/2;
        return document.elementFromPoint(x, y) === element;
      };
  for (var i = 0, l = rects.length; i < l; i++) {
    var r = rects[i],
        in_viewport = r.top > 0 ? r.top <= height : (r.bottom > 0 && r.bottom <= height);
    if (in_viewport && on_top(r)) return true;
  }
  return false;
}

Es wird überprüft, dass das Element hat eine Fläche> 0 und dann überprüft, ob ein Teil des Elements innerhalb des Ansichtsfensters ist und dass es nicht „unter“ einem anderen Elemente verborgen ist (eigentlich nur ich auf einem einzigen Punkt in der Mitte überprüfen des Elements, so dass es nicht 100% sicher - aber man konnte nur das Skript ändern, über alle Punkte des Elements itterate, wenn Sie wirklich ...) benötigt

.

Update

Modifizierte on_top Funktion, die jedes Pixel überprüfen:

on_top = function(r) {
  for (var x = Math.floor(r.left), x_max = Math.ceil(r.right); x <= x_max; x++)
  for (var y = Math.floor(r.top), y_max = Math.ceil(r.bottom); y <= y_max; y++) {
    if (document.elementFromPoint(x, y) === element) return true;
  }
  return false;
};

Sie wissen nicht, über die Leistung:)

Wie jkl wies darauf hin, die Sichtbarkeit oder die Anzeige des Elements Überprüfung ist nicht genug. Sie haben seine Vorfahren zu überprüfen. Selen tut dies, wenn es Sichtbarkeit auf ein Element überprüft.

Überprüfen Sie die Methode Selenium.prototype.isVisible in der Selen-api.js Datei aus.

http://svn.openqa.org/svn/selenium-on-rails/selenium-on-rails/selenium-core/scripts/selenium-api.js

Interessante Frage.

Das wäre mein Ansatz.

  1. Zuerst prüfen Sie, dass element.style.visibility! == 'versteckt' && element.style.display! == 'none'
  2. Dann testen Sie mit document.elementFromPoint (element.offsetLeft, element.offsetTop), wenn das zurückgegebene Element ist das Element Ich erwarte, dass diese schwierig zu erkennen, ob ein Element ein anderes vollständig überlappt.
  3. Schließlich testen, ob offsetTop und offsetleft im Ansichtsfenster Mitnahmen Scroll-Offsets berücksichtigt befinden.

Hoffe, es hilft.

Das ist, was ich bisher haben. Es umfasst sowohl 1 und 3. Ich bin aber immer noch mit 2 zu kämpfen, da ich mit Prototype nicht so vertraut bin (ich bin mehr ein jQuery-Typ Manns).

function isVisible( elem ) {
    var $elem = $(elem);

    // First check if elem is hidden through css as this is not very costly:
    if ($elem.getStyle('display') == 'none' || $elem.getStyle('visibility') == 'hidden' ) {
        //elem is set through CSS stylesheet or inline to invisible
        return false;
    }

    //Now check for the elem being outside of the viewport
    var $elemOffset = $elem.viewportOffset();
    if ($elemOffset.left < 0 || $elemOffset.top < 0) {
        //elem is left of or above viewport
        return false;
    }
    var vp = document.viewport.getDimensions();
    if ($elemOffset.left > vp.width || $elemOffset.top > vp.height) {
        //elem is below or right of vp
        return false;
    }

    //Now check for elements positioned on top:
    //TODO: Build check for this using Prototype...
    //Neither of these was true, so the elem was visible:
    return true;
}

Prototype Elementbibliothek ist eine der mächtigsten Abfrage Bibliotheken in Bezug auf die Methoden. Ich empfehle Ihnen, die API zu überprüfen.

Ein paar Hinweise:

  1. Sichtbarkeit Überprüfung kann ein Schmerz sein, aber man kann die Element.getStyle() Methode und Element.visible() Methoden in eine benutzerdefinierte Funktion kombiniert verwenden. Mit getStyle() können Sie den aktuellen berechneten Stil überprüfen.

  2. Ich weiß nicht genau, was Sie mit „unter“ meine :) Wenn Sie gemeint durch einen bestimmten Vorfahren, zum Beispiel hat ein Wrapper div, können Sie Element.up(cssRule) verwenden:

    var child = $("myparagraph");
    if(!child.up("mywrapper")){
      // I lost my mom!
    }
    else {
      // I found my mom!
    }
    

    Wenn Sie die Geschwister des Kindes Element überprüfen möchten, können Sie das tun auch:

    var child = $("myparagraph");
    if(!child.previous("mywrapper")){
      // I lost my bro!
    } 
    else {
      // I found my bro!
    }
    
  3. Auch hier können Element lib Ihnen helfen, wenn ich das richtig verstehe, was du meinst :) Sie die tatsächliche überprüfen Dimensionen des Darstellungs und die Ihres Elements versetzt so können Sie berechnen, wenn Ihr Element "off screen" ist.

Viel Glück!

Ich klebte einen Testfall für PrototypeJS unter http://gist.github.com/117125 . Es scheint in Ihrem Fall können wir einfach nicht in getStyle() vertrauen. Für die Zuverlässigkeit der isMyElementReallyVisible Funktion maximiert wird, sollten Sie kombinieren die folgenden:

  • Überprüfen des berechneten Stil (Dojo hat eine schöne Implementierung , die Sie ausleihen können)
  • Überprüfen der viewportoffset (Prototyp native Methode)
  • Überprüfen der z-Index für die "unterhalb" Problem (unter Internet Explorer kann es fehlerhaft sein)

Eine Möglichkeit, es zu tun ist:

isVisible(elm) {
    while(elm.tagName != 'BODY') {
        if(!$(elm).visible()) return false;
        elm = elm.parentNode;
    }
    return true;
}

Credits: https: // GitHub. com / atetlaw / Wirklich-Easy-Feld-Validierung / Blob / Master / validation.js # L178

Fang-Maus-Drag-and-Ansichtsfenster Ereignisse (onmouseup, onresize, onscroll).

Wenn ein Schleppenden macht einen Vergleich der gezogene Element Grenze mit allen „Elementen von Interesse“ (dh Elemente mit Klasse „dont_hide“ oder eine Reihe von ids). Machen Sie dasselbe mit window.onscroll und window.onresize. Markieren Sie alle Elemente versteckt mit einem speziellen Attribut oder Klassenname oder einfach nur ausführen, was Aktion, die Sie wollen auf der Stelle.

Die versteckten Tests sind recht einfach. Für „völlig versteckt“ wollen Sie wissen, ob alle Ecken entweder innerhalb der schleppten Artikel Grenze oder außerhalb des Ansichtsfenster sind. Für teilweise verstecken Sie suchen für eine einzelne Ecke den gleichen Test entsprechen.

Ich glaube nicht, das Element der eigenen Sichtbarkeit und Anzeigeeigenschaften Kontrolle ist gut genug für Anforderung # 1, auch wenn Sie current / getComputedStyle verwenden. Sie müssen auch die Vorfahren des Elements überprüfen. Wenn ein Vorfahre verborgen ist, so ist das Element.

Ich würde es hassen, Sie jQuery zu umleiten (wie oft der Fall ist), jQuery 1.3 0,2 dies kein Problem mehr .

Überprüfen Sie Elemente offset Eigenschaft. Wenn es mehr als 0 ist, ist es sichtbar. Hinweis: dieser Ansatz nicht eine Situation abdeckt, wenn die Sicht: versteckt Stil gesetzt. Aber dieser Stil ist etwas seltsam sowieso.

Hier ist ein Beispielskript und Testfall. Deckt positionierte Elemente, die Sichtbarkeit: versteckt, Anzeige: keine. Haben Sie nicht z-Index testen, annehmen, dass es funktioniert.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <title></title>
    <style type="text/css">
    div {
      width: 200px;
      border: 1px solid red;
    }
    p {
      border: 2px solid green;
    }
    .r {
      border: 1px solid #BB3333;
      background: #EE9999;
      position: relative;
      top: -50px;
      height: 2em;
    }
    .of {
      overflow: hidden;
      height: 2em;
      word-wrap: none; 
    }
    .of p {
      width: 100%;
    }

    .of pre {
      display: inline;
    }
    .iv {
      visibility: hidden;
    }
    .dn {
      display: none;
    }
    </style>
    <script src="http://www.prototypejs.org/assets/2008/9/29/prototype-1.6.0.3.js"></script>
    <script>
      function isVisible(elem){
        if (Element.getStyle(elem, 'visibility') == 'hidden' || Element.getStyle(elem, 'display') == 'none') {
          return false;
        }
        var topx, topy, botx, boty;
        var offset = Element.positionedOffset(elem);
        topx = offset.left;
        topy = offset.top;
        botx = Element.getWidth(elem) + topx;
        boty = Element.getHeight(elem) + topy;
        var v = false;
        for (var x = topx; x <= botx; x++) {
          for(var y = topy; y <= boty; y++) {
            if (document.elementFromPoint(x,y) == elem) {
              // item is visible
              v = true;
              break;
            }
          }
          if (v == true) {
            break;
          }
        }
        return v;
      }

      window.onload=function() {
        var es = Element.descendants('body');
        for (var i = 0; i < es.length; i++ ) {
          if (!isVisible(es[i])) {
            alert(es[i].tagName);
          }
        }
      }
    </script>
  </head>
  <body id='body'>
    <div class="s"><p>This is text</p><p>More text</p></div>
    <div class="r">This is relative</div>
    <div class="of"><p>This is too wide...</p><pre>hidden</pre>
    <div class="iv">This is invisible</div>
    <div class="dn">This is display none</div>
  </body>
</html>
/**
 * Checks display and visibility of elements and it's parents
 * @param  DomElement  el
 * @param  boolean isDeep Watch parents? Default is true
 * @return {Boolean}
 *
 * @author Oleksandr Knyga <oleksandrknyga@gmail.com>
 */
function isVisible(el, isDeep) {
    var elIsVisible = true;

    if("undefined" === typeof isDeep) {
        isDeep = true;
    }

    elIsVisible = elIsVisible && el.offsetWidth > 0 && el.offsetHeight > 0;

    if(isDeep && elIsVisible) {

        while('BODY' != el.tagName && elIsVisible) {
            elIsVisible = elIsVisible && 'hidden' != window.getComputedStyle(el).visibility;
            el = el.parentElement;
        }
    }

    return elIsVisible;
}

Sie können die client oder client Eigenschaften verwenden

function isViewable(element){
  return (element.clientHeight > 0);
}

Versuchen element.getBoundingClientRect(). Es wird ein Objekt mit Eigenschaften

zurückkehren
  • unten
  • oben
  • rechts
  • links
  • Breite - Browser abhängig
  • Höhe - Browser abhängig
Überprüfen

, dass die Breite und Höhe des Elements BoundingClientRect nicht Null ist, die den Wert von versteckten oder nicht sichtbaren Elementen sind. Sind die Werte größer als Null sollte das Element im Körper sichtbar sein. Prüfen Sie dann, ob die bottom Eigenschaft ist weniger als screen.height was bedeuten würde, dass das Element das Ansichtsfenster wird withing. (Technisch Sie würde auch für den oberen Rand des Browserfensters zu berücksichtigen haben, einschließlich der searchbar, Knöpfe, usw.)

Die Antwort auf den ersten Punkt ist ganz einfach, wenn Sie noch in der Lage sind Prototyp (PrototypeJS) zu verwenden:

$('HtmlElementID').visible(); returns: true|false

Hier ist ein Teil der Antwort, die Sie sagt, ob ein Element in der Ansicht ist. Unter Umständen müssen Sie prüfen, ob es nichts oben drauf ist elementFromPoint verwenden, aber es ist ein bisschen länger.

function isInViewport(element) {
  var rect = element.getBoundingClientRect();
  var windowHeight = window.innerHeight || document.documentElement.clientHeight;
  var windowWidth = window.innerWidth || document.documentElement.clientWidth;

  return rect.bottom > 0 && rect.top < windowHeight && rect.right > 0 && rect.left < windowWidth;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top