638 Stimmen

Überprüfen, ob ein Element im DOM sichtbar ist

Gibt es eine Möglichkeit, in reinem JS (ohne jQuery) zu überprüfen, ob ein Element sichtbar ist?

Also, gegeben ein DOM-Element, wie kann ich überprüfen, ob es sichtbar ist oder nicht? Ich habe es versucht:

window.getComputedStyle(my_element)['display']);

aber es scheint nicht zu funktionieren. Ich frage mich, welche Attribute ich überprüfen sollte. Mir kommen folgende Attribute in den Sinn:

display !== 'none'
visibility !== 'hidden'

Gibt es noch andere, die mir entgehen könnten?

963voto

AlexZ Punkte 11125

Gemäß dieser MDN-Dokumentation wird die Eigenschaft eines Elements offsetParent null zurückgeben, wann immer es oder einer seiner Eltern über die Anzeige-Eigenschaft versteckt ist. Stellen Sie einfach sicher, dass das Element nicht fixiert ist. Ein Skript zur Überprüfung könnte wie folgt aussehen, wenn Sie keine Elemente mit position: fixed; auf Ihrer Seite haben:

// Wo el das DOM-Element ist, das Sie auf Sichtbarkeit testen möchten
function isHidden(el) {
    return (el.offsetParent === null)
}

Andererseits, wenn Sie fest positionierte Elemente haben, die in dieser Suche erfasst werden könnten, müssen Sie leider (und langsam) window.getComputedStyle() verwenden. Die Funktion könnte in diesem Fall wie folgt sein:

// Wo el das DOM-Element ist, das Sie auf Sichtbarkeit testen möchten
function isHidden(el) {
    var style = window.getComputedStyle(el);
    return (style.display === 'none')
}

Option #2 ist wahrscheinlich etwas geradliniger, da sie mehr Randfälle berücksichtigt, aber ich wette, dass sie auch deutlich langsamer ist, also wenn Sie diese Operation häufig wiederholen müssen, ist es wahrscheinlich am besten, sie zu vermeiden.

172voto

guy mograbi Punkte 24995

Alle anderen Lösungen brachen in bestimmten Situationen für mich zusammen..

Sieh dir die gewinnende Antwort an, die hier zusammenbricht:

http://plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview

Schließlich entschied ich, dass die beste Lösung $(elem).is(':visible') war - jedoch ist das kein reines JavaScript. Es ist jQuery..

also schaute ich mir deren Quelle an und fand, was ich wollte

jQuery.expr.filters.visible = function( elem ) {
    return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};

Das ist die Quelle: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js

114voto

Ohad Navon Punkte 1491

Wenn Sie daran interessiert sind, vom Benutzer sichtbar zu sein:

function isVisible(elem) {
    if (!(elem instanceof Element)) throw Error('DomUtil: elem ist kein Element.');
    const style = getComputedStyle(elem);
    if (style.display === 'none') return false;
    if (style.visibility !== 'visible') return false;
    if (style.opacity < 0.1) return false;
    if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height +
        elem.getBoundingClientRect().width === 0) {
        return false;
    }
    const elemCenter   = {
        x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
        y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
    };
    if (elemCenter.x < 0) return false;
    if (elemCenter.x > (document.documentElement.clientWidth || window.innerWidth)) return false;
    if (elemCenter.y < 0) return false;
    if (elemCenter.y > (document.documentElement.clientHeight || window.innerHeight)) return false;
    let pointContainer = document.elementFromPoint(elemCenter.x, elemCenter.y);
    do {
        if (pointContainer === elem) return true;
    } while (pointContainer = pointContainer.parentNode);
    return false;
}

Geprüft auf (mit Mocha Terminologie):

describe.only('Sichtbarkeit', function () {
    let div, sichtbar, nichtSichtbar, imViewport, linksVomViewport, rechtsVomViewport, überViewport,
        unterViewport, nichtAngezeigt, nullOpazität, zIndex1, zIndex2;
    before(() => {
        div = document.createElement('div');
        document.querySelector('body').appendChild(div);
        div.appendChild(sichtbar = document.createElement('div'));
        sichtbar.style       = 'border: 1px solid black; margin: 5px; display: inline-block;';
        sichtbar.textContent = 'sichtbar';
        div.appendChild(imViewport = sichtbar.cloneNode(false));
        imViewport.textContent = 'imViewport';
        div.appendChild(nichtAngezeigt = sichtbar.cloneNode(false));
        nichtAngezeigt.style.display = 'none';
        nichtAngezeigt.textContent   = 'nichtAngezeigt';
        div.appendChild(nichtSichtbar = sichtbar.cloneNode(false));
        nichtSichtbar.style.visibility = 'hidden';
        nichtSichtbar.textContent      = 'nichtSichtbar';
        div.appendChild(linksVomViewport = sichtbar.cloneNode(false));
        linksVomViewport.style.position = 'absolute';
        linksVomViewport.style.right = '100000px';
        linksVomViewport.textContent = 'linksVomViewport';
        div.appendChild(rechtsVomViewport = linksVomViewport.cloneNode(false));
        rechtsVomViewport.style.right       = '0';
        rechtsVomViewport.style.left       = '100000px';
        rechtsVomViewport.textContent = 'rechtsVomViewport';
        div.appendChild(überViewport = linksVomViewport.cloneNode(false));
        überViewport.style.right       = '0';
        überViewport.style.bottom       = '100000px';
        überViewport.textContent = 'überViewport';
        div.appendChild(unterViewport = linksVomViewport.cloneNode(false));
        unterViewport.style.right       = '0';
        unterViewport.style.top       = '100000px';
        unterViewport.textContent = 'unterViewport';
        div.appendChild(nullOpazität = sichtbar.cloneNode(false));
        nullOpazität.textContent   = 'nullOpazität';
        nullOpazität.style.opacity = '0';
        div.appendChild(zIndex1 = sichtbar.cloneNode(false));
        zIndex1.textContent = 'zIndex1';
        zIndex1.style.position = 'absolute';
        zIndex1.style.left = zIndex1.style.top = zIndex1.style.width = zIndex1.style.height = '100px';
        zIndex1.style.zIndex = '1';
        div.appendChild(zIndex2 = zIndex1.cloneNode(false));
        zIndex2.textContent = 'zIndex2';
        zIndex2.style.left = zIndex2.style.top = '90px';
        zIndex2.style.width = zIndex2.style.height = '120px';
        zIndex2.style.backgroundColor = 'red';
        zIndex2.style.zIndex = '2';
    });
    after(() => {
        div.parentNode.removeChild(div);
    });
    it('isVisible = true', () => {
        expect(isVisible(div)).to.be.true;
        expect(isVisible(sichtbar)).to.be.true;
        expect(isVisible(imViewport)).to.be.true;
        expect(isVisible(zIndex2)).to.be.true;
    });
    it('isVisible = false', () => {
        expect(isVisible(nichtAngezeigt)).to.be.false;
        expect(isVisible(nichtSichtbar)).to.be.false;
        expect(isVisible(document.createElement('div'))).to.be.false;
        expect(isVisible(zIndex1)).to.be.false;
        expect(isVisible(nullOpazität)).to.be.false;
        expect(isVisible(linksVomViewport)).to.be.false;
        expect(isVisible(rechtsVomViewport)).to.be.false;
        expect(isVisible(überViewport)).to.be.false;
        expect(isVisible(unterViewport)).to.be.false;
    });
});

70voto

Mahozad Punkte 10508

Chrome 105 (und Edge und Opera) und Firefox 106 haben Element.checkVisibility() eingeführt, das true zurückgibt, wenn das Element sichtbar ist, und ansonsten false.

Die Funktion überprüft verschiedene Faktoren, die ein Element unsichtbar machen würden, wie display:none, visibility, content-visibility und opacity:

let element = document.getElementById("myIcon");
let isVisible = element.checkVisibility({
    checkOpacity: true,      // Überprüfen Sie auch die CSS-Opacity-Eigenschaft
    checkVisibilityCSS: true // Überprüfen Sie auch die CSS-Sichtbarkeitseigenschaft
});

Anmerkung: checkVisibility() wurde zuvor isVisible() genannt. Siehe diese GitHub-Ausgabe.
Siehe Entwurf der checkVisibility()-Spezifikation hier.

62voto

Yvan Punkte 2339

Verwenden Sie den gleichen Code wie jQuery:

jQuery.expr.pseudos.visible = function( elem ) {
    return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};

Also, in einer Funktion:

function isVisible(e) {
    return !!( e.offsetWidth || e.offsetHeight || e.getClientRects().length );
}

Funktioniert wie ein Zauber in meinem Win/IE10, Linux/Firefox.45, Linux/Chrome.52...

Vielen Dank an jQuery ohne jQuery!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X