Öğenin DOM'da görünür olup olmadığını kontrol edin


377

Bir öğenin saf JS'de (jQuery yok) görünür olup olmadığını kontrol edebilmemin herhangi bir yolu var mı?

Örneğin, bu sayfada: Performans Bisikletleri , Anlaşmaların (üst menüde) üzerine gelirseniz, bir anlaşma penceresi görünür, ancak başlangıçta gösterilmez. HTML'de ama görünür değil.

Peki, bir DOM öğesi göz önüne alındığında, görünür olup olmadığını nasıl kontrol edebilirim? Denedim:

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

ama işe yaramıyor gibi görünüyor. Hangi özellikleri kontrol etmem gerektiğini merak ediyorum. Aklıma geliyor:

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

Eksik olabileceğim başkaları var mı?


1
Ekranı kullanmaz, görünürlüğü kullanır, bu nedenle görünürlüğü kontrol edin (gizli veya görünür). örn:document.getElementById('snDealsPanel').style.visibility
PSL

PSL. Bunu daha genel yapmak istersem, hangi özellikleri kontrol etmeliyim: görünürlük, görüntüleme ...?
Hommer Smith

Kendi şekilde jenerik yapabilirsiniz ama söylüyorum, bu öğeyi incelemek görünürlük kullanır.
PSL

İşte bu soru için kodum (jquery yok) stackoverflow.com/a/22969337/2274995
Aleko

Bağlantı koptu, bu da sorunuzun anlaşılmasını kolaylaştırıyor. Lütfen yeniden çerçevelendirin.
yogihosting

Yanıtlar:


617

Göre bu MDN belgelerinde , bir elementin offsetParentözelliği dönecektir nullo ya da ebeveynlerden herhangi görüntüleme stili özelliği aracılığıyla gizli anda meydana gelir. Sadece öğenin sabit olmadığından emin olun. position: fixed;Sayfanızda hiç öğe yoksa bunu kontrol etmek için bir komut dosyası şöyle görünebilir:

// Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
    return (el.offsetParent === null)
}

Eğer Öte yandan, do bu arama yakalanmak olabilir pozisyon sabit unsurları var, ne yazık ki (ve yavaş yavaş) kullanımına sahip olacak window.getComputedStyle(). Bu durumda işlev şöyle olabilir:

// Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
    var style = window.getComputedStyle(el);
    return (style.display === 'none')
}

Seçenek # 2, muhtemelen daha fazla durumdan sorumlu olduğu için biraz daha basittir, ancak bahse girerim, çok daha yavaştır, bu yüzden bu işlemi birçok kez tekrarlamanız gerekiyorsa, muhtemelen en iyi şekilde önlemek için.


Vay canına şaka yapmıyorum. Imo, ikinci yöntemi evrensel bir çözüm olarak kullanmak için hiçbir neden olmamalıdır; hiçbir sayfada, yaratıcısının açıkça farkında olmadığı sabit öğeler bulunmamalı ve yalnızca tüm öğeler üzerinde offsetParent yöntemini çalıştırdıktan sonra getComputedStyle () yöntemini kullanarak bu öğeleri elle kontrol edebilirsiniz.
AlexZ

6
Ayrıca FYI, sadece el.offsetParentsabit olmayan elemanlar için IE9 üzerinde çalışmadığını keşfetti . Ya da öyle görünüyor, neyse. (Yine de IE11 için Tamam.) Sonuçta ile gitti getComputedStyle.
Nick

1
@AlexZ OffsetParent'ın bugünün tarayıcılarında gerçekten bir yeniden akış yapıp yapmadığından emin değilim, ama evet birkaç yıl önce, eskiden, raporlardan anladığım şey bu. JsPerf öğesinin yalnızca yürütme hızından bahsettiğini, ancak yeniden akışın ekranla ilgili olduğunu unutmayın. Ve yeniden akışlar kullanıcı arayüzünü zayıflatır. Şahsen ben bir sayfada muhtemelen 5/6 kez denilen bir rutin için hız gitmeyeceğim.
Ethan

2
heyhat! getComputedStyledüzgün çalışmıyor: plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview Bununla birlikte offsetParent- belki de ikisinin bir kombinasyonu kullanılmalıdır?
Guy Mograbi

2
ie9 + ie10 için offsetParent = gövde öğesinin görünmeyen öğeler olup olmadığını kontrol edebilirsiniz.
SuperUberDuper

99

Diğer tüm çözümler benim için bir durum için kırıldı ..

Kazanan cevabı şu adreste bulabilirsiniz:

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

Sonunda, en iyi çözüm olduğuna karar verdim $(elem).is(':visible')- ancak bu saf bir javascript değil. jquery ..

bu yüzden kaynaklarına baktım ve ne istediğimi buldum

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

Bu kaynak: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js


11
Bu dönecektir truebelirtilen elemanıvisibility:hidden
Yuval A.

9
@YuvalA .: Evet, çünkü eleman hala görülebilir. Bir öğeyi ayarlamak visibility:hiddenartık içerik göstermez, ancak yine de öğenin genişliğini ve yüksekliğini alır!
Jacob van Lingen

4
@Michael, jQuery koduna kolayca göz atabilir ve herhangi bir modern IDE kullanıyorsanız (değilse deneyin) jQuery veya başka bir lib kullanırken doğru kod parçalarına atlayabilirsiniz. Açık kaynaklı projelerin kod tabanlarına göz atarken çok şey öğrenebilirsiniz.
Lukas Liesis

53

Kullanıcı tarafından görülebilir olarak ilgileniyorsanız:

function isVisible(elem) {
    if (!(elem instanceof Element)) throw Error('DomUtil: elem is not an 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;
}

Test edildi ( mocha terminolojisi kullanılarak):

describe.only('visibility', function () {
    let div, visible, notVisible, inViewport, leftOfViewport, rightOfViewport, aboveViewport,
        belowViewport, notDisplayed, zeroOpacity, zIndex1, zIndex2;
    before(() => {
        div = document.createElement('div');
        document.querySelector('body').appendChild(div);
        div.appendChild(visible = document.createElement('div'));
        visible.style       = 'border: 1px solid black; margin: 5px; display: inline-block;';
        visible.textContent = 'visible';
        div.appendChild(inViewport = visible.cloneNode(false));
        inViewport.textContent = 'inViewport';
        div.appendChild(notDisplayed = visible.cloneNode(false));
        notDisplayed.style.display = 'none';
        notDisplayed.textContent   = 'notDisplayed';
        div.appendChild(notVisible = visible.cloneNode(false));
        notVisible.style.visibility = 'hidden';
        notVisible.textContent      = 'notVisible';
        div.appendChild(leftOfViewport = visible.cloneNode(false));
        leftOfViewport.style.position = 'absolute';
        leftOfViewport.style.right = '100000px';
        leftOfViewport.textContent = 'leftOfViewport';
        div.appendChild(rightOfViewport = leftOfViewport.cloneNode(false));
        rightOfViewport.style.right       = '0';
        rightOfViewport.style.left       = '100000px';
        rightOfViewport.textContent = 'rightOfViewport';
        div.appendChild(aboveViewport = leftOfViewport.cloneNode(false));
        aboveViewport.style.right       = '0';
        aboveViewport.style.bottom       = '100000px';
        aboveViewport.textContent = 'aboveViewport';
        div.appendChild(belowViewport = leftOfViewport.cloneNode(false));
        belowViewport.style.right       = '0';
        belowViewport.style.top       = '100000px';
        belowViewport.textContent = 'belowViewport';
        div.appendChild(zeroOpacity = visible.cloneNode(false));
        zeroOpacity.textContent   = 'zeroOpacity';
        zeroOpacity.style.opacity = '0';
        div.appendChild(zIndex1 = visible.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(visible)).to.be.true;
        expect(isVisible(inViewport)).to.be.true;
        expect(isVisible(zIndex2)).to.be.true;
    });
    it('isVisible = false', () => {
        expect(isVisible(notDisplayed)).to.be.false;
        expect(isVisible(notVisible)).to.be.false;
        expect(isVisible(document.createElement('div'))).to.be.false;
        expect(isVisible(zIndex1)).to.be.false;
        expect(isVisible(zeroOpacity)).to.be.false;
        expect(isVisible(leftOfViewport)).to.be.false;
        expect(isVisible(rightOfViewport)).to.be.false;
        expect(isVisible(aboveViewport)).to.be.false;
        expect(isVisible(belowViewport)).to.be.false;
    });
});

elem görünüm alanının dışında konumlandırılmışsa, bir kenar durumu "! (! pointContainer) false döndürürse" ile yakalanabilir; İlk noktayı kontrol etmekKonteyner
Jerry Deng

Kullanıcının görüp göremeyeceğini kontrol etmek isterseniz, bir scrollIntoViewhak mı kullanmanız gerekir ?! Bu oldukça pahalı. Başka bir akıllı yol var mı?
Kim Kern

36

Bu yardımcı olabilir: Öğeyi en soldaki konuma getirerek gizleyin ve sonra offsetLeft özelliğini kontrol edin. JQuery kullanmak istiyorsanız,: visible selector öğesini kontrol edebilir ve öğenin görünürlük durumunu alabilirsiniz.

HTML:

<div id="myDiv">Hello</div>

CSS:

<!-- for javaScript-->
#myDiv{
   position:absolute;
   left : -2000px;
}

<!-- for jQuery -->
#myDiv{
    visibility:hidden;
}

javaScript:

var myStyle = document.getElementById("myDiv").offsetLeft;

if(myStyle < 0){
     alert("Div is hidden!!");
}

jQuery:

if(  $("#MyElement").is(":visible") == true )
{  
     alert("Div is visible!!");        
}

jsFiddle


12
OP bir jQuery yanıtı istemez.
Stephen Quan

Daha sonra düzenlendi sanırım. Ben cevap zaman iş parçacığında bahsedilmedi.
Md. Ashaduzzaman

2
@StephenQuan, yanıtı hem jQuery hem de javaScript çözümüyle güncelledim.
Md. Ashaduzzaman

6
jQuery örneği için, uyarı "Div görünür mü?"
Andrei Bazanov

Bir elemanın tamamen offsetLeft değeri 0'dan küçük olduğu için tamamen gizli olduğu sonucuna varmak istemiyorum: 0'dan küçük piksel sayısı azsa ve sağ kısmı görünürse ne olur? (Bunun aptalca bir tasarım gibi göründüğüne katılıyorum, ancak bu günlerde web tasarımcılarıyla asla bilemezsiniz.) Muhtemelen offsetLeft'e genişlik eklemek ve sonucun hala 0'dan küçük olup olmadığını görmek daha iyidir.
Silas S. Brown

31

JQuery ile aynı kodu kullanın:

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

Yani, bir fonksiyonda:

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

Win / IE10, Linux / Firefox.45, Linux / Chrome.52'de bir cazibe gibi çalışır ...

JQuery olmadan jQuery için çok teşekkürler!


Güzel ama taşma tarafından gizlenen öğeleri kapsamaz.
Alph.Dev

güzel ama ne neden !! (çift olumsuzlama)?
Sunil Garg

3
Sonucu boole olarak zorlamak için. Olarak e.offsetWidthbir tam sayı olduğu, !e.offsetWidthdöner falsehalinde e.offsetWidth(eleman görünür) sıfırdan yüksektir. Yani !olduğu gibi başka bir tane eklemek!!e.offsetWidth dönecektir trueeğer e.offsetWidthsıfırdan yüksektir. Bu kestirme return e.offsetWidth > 0 ? true : falseveya açık bir şekilde return e.offsetWidth > 0.
Yvan

16

Yukarıdaki birkaç cevabı birleştirerek:

function isVisible (ele) {
    var style = window.getComputedStyle(ele);
    return  style.width !== "0" &&
    style.height !== "0" &&
    style.opacity !== "0" &&
    style.display!=='none' &&
    style.visibility!== 'hidden';
}

AlexZ'in dediği gibi, ne aradığınızı daha spesifik olarak biliyorsanız, diğer seçeneklerin bazılarından daha yavaş olabilir, ancak bu, öğelerin gizlenmesinin tüm ana yollarını yakalamalıdır.

Ancak, sizin için görünür olanın ne olduğuna da bağlıdır. Örneğin, bir div'in yüksekliği 0 piksel olarak ayarlanabilir, ancak taşma özelliklerine bağlı olarak içerik hala görünür. Veya bir div'in içeriği arka planla aynı renkte yapılabilir, böylece kullanıcılar tarafından görülemez, ancak yine de sayfada oluşturulur. Veya bir div ekranın dışına taşınabilir veya diğer div'ların arkasına gizlenebilir veya içeriği görünmeyebilir, ancak kenarlık hala görülebilir. Belli bir dereceye kadar "görünür" öznel bir terimdir.


1
Güzel, ama style.opacity, style.height ve style.width bir dize döndürür, böylece çalışmaz! ==
Maslow

Bir öğenin stil aracılığıyla gizlenmesinin başka bir yolu, renginin arka plan rengiyle eşleşebilmesi veya z-endeksinin diğer öğelerden daha düşük olabilmesidir.
nu everest

buna eklemek display:noneharika olurdu. Uygun bir çalışma çözümü!
Gijo Varghese

7

Bir konum 'sabit' elemanları olduğunda, bazı kenar durumlarını görmezden gelmeye istekli ise AlexZ'nin getComputedStyle () çözümüne kıyasla daha performanslı bir çözümüm var (yorumları kontrol edin):

function isVisible(el) {
    /* offsetParent would be null if display 'none' is set.
       However Chrome, IE and MS Edge returns offsetParent as null for elements
       with CSS position 'fixed'. So check whether the dimensions are zero.

       This check would be inaccurate if position is 'fixed' AND dimensions were
       intentionally set to zero. But..it is good enough for most cases.*/
    if (!el.offsetParent && el.offsetWidth === 0 && el.offsetHeight === 0) {
        return false;
    }
    return true;
}

Yan not: Kesin olarak, "görünürlük" ilk önce tanımlanmalıdır. Benim durumumda, tüm DOM yöntemlerini / özelliklerini sorunsuz olarak çalıştırabildiğim sürece (opaklık 0 olsa veya CSS görünürlük özelliği 'gizli' vb. Olsa bile) görünen bir öğeyi düşünüyoruz.


6

Öğe düzenli olarak görünürse (display: block ve visibillity: visible), ancak bazı üst kapsayıcılar gizlenmişse, bunu kontrol etmek için clientWidth ve clientHeight'ı kullanabiliriz .

function isVisible (ele) {
  return  ele.clientWidth !== 0 &&
    ele.clientHeight !== 0 &&
    ele.style.opacity !== 0 &&
    ele.style.visibility !== 'hidden';
}

Plunker (buraya tıklayın)


ele.style.visibility !== 'hidden'burada gereksizdir. Bu durumda, clientWidth ve clientHeight 0 olur.
subdavis

5

Görünürlüğü tespit etmenin temel yollarını topluyorsak, unutmama izin ver:

opacity > 0.01; // probably more like .1 to actually be visible, but YMMV

Ve özniteliklerin nasıl elde edileceği konusunda:

element.getAttribute(attributename);

Yani, örneğinizde:

document.getElementById('snDealsPanel').getAttribute('visibility');

Ama ne? Burada işe yaramıyor. Daha yakından bakın ve görünürlük öğenin bir özelliği olarak değil, styleözelliği kullanarak güncellendiğini göreceksiniz . Bu, yaptığınız şeyi yapmaya çalışmakla ilgili birçok problemden biridir. Diğerleri arasında: Görünürlüğünün, görüntüsünün ve opaklığının hepsinin doğru değerlere sahip olması nedeniyle, bir öğede gerçekten görülecek bir şey olduğunu garanti edemezsiniz. Hala içerikten yoksun olabilir veya yükseklik ve genişlikten yoksun olabilir. Başka bir nesne onu gizleyebilir. Daha fazla ayrıntı için, hızlı bir Google arama ortaya bu ve hatta problem çözme denemek için bir kütüphane içerir. (YMMV)

Bu sorunun olası kopyaları olan aşağıdakilere göz atın, güçlü John Resig'in bazı fikirleri de dahil olmak üzere mükemmel cevaplarla. Ancak, özel kullanım durumunuz standart olandan biraz farklıdır, bu yüzden işaretlemekten kaçınacağım:

(DÜZENLEME: OP YAZDIRMA SAYFALARINI YARATMADIĞINI DEMEKTEDİR, AŞAĞIDAKİ GEÇERLİ DEĞİLDİR) Daha iyi bir seçenek? Elemanların görünürlüğünü model özelliklerine bağlayın ve her zaman görünürlük, Angular'ın ng-show ile yaptığı gibi bu modele bağlı olmasını sağlayın. Bunu istediğiniz herhangi bir aracı kullanarak yapabilirsiniz: Açısal, düz JS, her neyse. Daha da iyisi, DOM uygulamasını zaman içinde değiştirebilirsiniz, ancak DOM yerine durumu her zaman modelden okuyabilirsiniz. DOM'dan gerçeğinizi okumak Kötü. Ve yavaş. Modeli kontrol etmek ve DOM durumunun modeli yansıttığından emin olmak için uygulamanıza güvenmek çok daha iyidir. (Ve bu varsayımı onaylamak için otomatik test kullanın.)


Siteleri ayrıştırıyorum, bu kendi sitem için değil ... :)
Hommer Smith

4

Kabul edilen cevap benim için işe yaramadı. Yıl 2020 cevabı :

1) (elem.offsetParent! == null) yöntemi Firefox'ta iyi çalışıyor, ancak Chrome'da çalışmıyor. Chrome "konumu: sabit;" sayfada göründüğünde bile öğe bile offsetParent döndürme "null" yapar.

Demo:

//different results in Chrome and Firefox
console.log(document.querySelector('#hidden1').offsetParent); //null Chrome & Firefox
console.log(document.querySelector('#fixed1').offsetParent); //null in Chrome, not null in Firefox
    <div id="hidden1" style="display:none;"></div>
    <div id="fixed1" style="position:fixed;"></div>

bu adam megatest https://stackoverflow.com/a/11639664/4481831 (farklılıkları görmek için birden fazla tarayıcı ile çalıştırın) görebilirsiniz.

2) (getComputedStyle (elem) .display! == 'none') çalışmaz, çünkü ebeveyn display özelliğinden biri none olarak ayarlandığından öğe görünmez olabilir, getComputedStyle bunu yakalamaz.

Demo:

var child1 = document.querySelector('#child1');
console.log(getComputedStyle(child1).display);
//child will show "block" instead of "none"
<div id="parent1" style="display:none;">
  <div id="child1" style="display:block"></div>
</div>

3) (elem.clientHeight! == 0) . Bu yöntem sabit konumdan etkilenmez ve ayrıca öğe ebeveynlerinin görünüp görünmediğini kontrol eder. Ancak css düzeni olmayan basit öğelerle ilgili sorunları var, daha fazla bilgi için buraya bakın

Demo:

console.log(document.querySelector('#div1').clientHeight); //not zero
console.log(document.querySelector('#span1').clientHeight); //zero
<div id="div1">test1 div</div>
<span id="span1">test2 span</span>

4) Önceki 3 yöntemin problemlerini aşmış gibi görünen (elem.getClientRects (). Uzunluk! == 0) . Ancak, sayfada gizlemek için CSS hileleri ("display: none" dışında) kullanan öğelerle ilgili sorunları var.

console.log(document.querySelector('#notvisible1').getClientRects().length);
console.log(document.querySelector('#notvisible1').clientHeight);
console.log(document.querySelector('#notvisible2').getClientRects().length);
console.log(document.querySelector('#notvisible2').clientHeight);
console.log(document.querySelector('#notvisible3').getClientRects().length);
console.log(document.querySelector('#notvisible3').clientHeight);
<div id="notvisible1" style="height:0; overflow:hidden; background-color:red;">not visible 1</div>

<div id="notvisible2" style="visibility:hidden; background-color:yellow;">not visible 2</div>

<div id="notvisible3" style="opacity:0; background-color:blue;">not visible 3</div>

SONUÇ: Size gösterdiğim şey, hiçbir yöntemin mükemmel olmadığıdır. Uygun bir görünürlük kontrolü yapmak için son 3 yöntemin bir kombinasyonunu kullanmalısınız.


3

Sadece referans için getBoundingClientRect()belirli durumlarda çalışabileceğine dikkat edilmelidir .

Örneğin, öğenin kullanılarak gizlendiğini gösteren basit bir kontrol display: noneşöyle görünebilir:

var box = element.getBoundingClientRect();
var visible = box.width && box.height;

Bu aynı zamanda kullanışlıdır çünkü sıfır genişlik, sıfır yükseklik ve position: fixedkasaları da kapsar . Bununla birlikte, gizli olan opacity: 0veya olmayan öğeleri bildirmez visibility: hidden(ancak ikisi de bildirmez offsetParent).


Benim için en iyi cevap ... basit ve etkili. Ve 3 yıl sonra tek bir upvote yok! “Kalabalık bilgeliği” nin değerini göstermeye devam ediyor. Benim versiyon: var isVisible = el => (r => r.width && r.height)(el.getBoundingClientRect());. Sonra şu şekilde elementlerin diziler filtreleyebilirsiniz: $$(sel).filter(isVisible).
7vujy0f0hy

Bunu en basit çözüm geliştirici
Marian07

Bu kullanıcı tarafından görülebilir olduğunda çalışmaz .... eğer uzaklaşırsanız gerçek kalır
Ray Foss

3

Yani bulduğum en uygun yöntem:

function visible(elm) {
  if(!elm.offsetHeight && !elm.offsetWidth) { return false; }
  if(getComputedStyle(elm).visibility === 'hidden') { return false; }
  return true;
}

Bu şu gerçekler üzerine kuruludur:

  • Bir display: noneöğenin (yuvalanmış bile olsa) genişliği veya yüksekliği yoktur.
  • visiblityolduğu hidden, hatta iç içe elemanları.

Bu nedenle offsetParent, hangi üst öğenin sahip olduğunu test etmek için DOM ağacında test etmeye veya döngüye girmeye gerek yoktur visibility: hidden. Bu IE 9'da bile çalışmalıdır.

opacity: 0Daraltılmış öğelerin (genişliğe sahip, ancak yüksekliği olmayan - veya tam tersi) gerçekten görünüp görünmediğini tartışabilirsiniz . Ama sonra tekrar söylenenler gizli değil.


3

Ohad Navon'un cevabına küçük bir katkı.

Elemanın merkezi başka bir elemana aitse onu bulamayacağız.

Bu nedenle, öğenin noktalarından birinin görünür olduğundan emin olmak için

function isElementVisible(elem) {
    if (!(elem instanceof Element)) throw Error('DomUtil: elem is not an element.');
    const style = getComputedStyle(elem);
    if (style.display === 'none') return false;
    if (style.visibility !== 'visible') return false;
    if (style.opacity === 0) return false;
    if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height +
        elem.getBoundingClientRect().width === 0) {
        return false;
    }
    var elementPoints = {
        'center': {
            x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
            y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
        },
        'top-left': {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().top
        },
        'top-right': {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().top
        },
        'bottom-left': {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().bottom
        },
        'bottom-right': {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().bottom
        }
    }

    for(index in elementPoints) {
        var point = elementPoints[index];
        if (point.x < 0) return false;
        if (point.x > (document.documentElement.clientWidth || window.innerWidth)) return false;
        if (point.y < 0) return false;
        if (point.y > (document.documentElement.clientHeight || window.innerHeight)) return false;
        let pointContainer = document.elementFromPoint(point.x, point.y);
        if (pointContainer !== null) {
            do {
                if (pointContainer === elem) return true;
            } while (pointContainer = pointContainer.parentNode);
        }
    }
    return false;
}

3

Yukarıdaki @Guy Messika'nın cevabını iyileştirmek, 'X <0 merkez noktası yanlışsa eleman sağ tarafın görünüme girebilmesi nedeniyle yanlış ise kırıp yanlış döndürmek. İşte bir düzeltme:

private isVisible(elem) {
    const style = getComputedStyle(elem);

    if (style.display === 'none') return false;
    if (style.visibility !== 'visible') return false;
    if ((style.opacity as any) === 0) return false;

    if (
        elem.offsetWidth +
        elem.offsetHeight +
        elem.getBoundingClientRect().height +
        elem.getBoundingClientRect().width === 0
    ) return false;

    const elementPoints = {
        center: {
            x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
            y: elem.getBoundingClientRect().top + elem.offsetHeight / 2,
        },
        topLeft: {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().top,
        },
        topRight: {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().top,
        },
        bottomLeft: {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().bottom,
        },
        bottomRight: {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().bottom,
        },
    };

    const docWidth = document.documentElement.clientWidth || window.innerWidth;
    const docHeight = document.documentElement.clientHeight || window.innerHeight;

    if (elementPoints.topLeft.x > docWidth) return false;
    if (elementPoints.topLeft.y > docHeight) return false;
    if (elementPoints.bottomRight.x < 0) return false;
    if (elementPoints.bottomRight.y < 0) return false;

    for (let index in elementPoints) {
        const point = elementPoints[index];
        let pointContainer = document.elementFromPoint(point.x, point.y);
        if (pointContainer !== null) {
            do {
                if (pointContainer === elem) return true;
            } while (pointContainer = pointContainer.parentNode);
        }
    }
    return false;
}

2

Http://code.jquery.com/jquery-1.11.1.js adresindeki jQuery kodu bir isHidden parametresine sahiptir

var isHidden = function( elem, el ) {
    // isHidden might be called from jQuery#filter function;
    // in that case, element will be second argument
    elem = el || elem;
    return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
};

Görünüşe göre sahip belgesi ile ilgili ekstra bir kontrol var

Bunun gerçekten aşağıdaki durumları yakalayıp yakalamadığını merak ediyorum:

  1. ZIndex tabanlı diğer öğelerin arkasına gizlenmiş öğeler
  2. Şeffaflık dolu öğeler görünmez kılar
  3. Ekran dışında konumlandırılan öğeler (örn. Sol: -1000 piksel)
  4. Görünürlüğü olan öğeler: gizli
  5. Ekranlı elemanlar: yok
  6. Görünür metin veya alt öğe içermeyen öğeler
  7. Yüksekliği veya genişliği 0 olarak ayarlanmış öğeler

0

İşte birkaç benzer öğe arasında sadece görünür bulmak ve "sınıf" özniteliğinin değerini jQuery olmadan döndürmek için yazdım kod:

  // Build a NodeList:
  var nl = document.querySelectorAll('.myCssSelector');

  // convert it to array:
  var myArray = [];for(var i = nl.length; i--; myArray.unshift(nl[i]));

  // now find the visible (= with offsetWidth more than 0) item:
  for (i =0; i < myArray.length; i++){
    var curEl = myArray[i];
    if (curEl.offsetWidth !== 0){
      return curEl.getAttribute("class");
    }
  }

0

Ben de öyle yaptım:

HTML ve CSS: Öğeyi varsayılan olarak gizli yaptı

<html>
<body>

<button onclick="myFunction()">Click Me</button>

<p id="demo" style ="visibility: hidden;">Hello World</p> 

</body>
</html> 

JavaScript: Görünürlüğün gizli olup olmadığını kontrol etmek için bir kod eklendi:

<script>
function myFunction() {
   if ( document.getElementById("demo").style.visibility === "hidden"){
   document.getElementById("demo").style.visibility = "visible";
   }
   else document.getElementById("demo").style.visibility = "hidden";
}
</script>

-1

Bu, görünürlük dahil tüm css özellikleri için bunu belirlemenin bir yoludur:

html:

<div id="element">div content</div>

css:

#element
{
visibility:hidden;
}

javascript:

var element = document.getElementById('element');
 if(element.style.visibility == 'hidden'){
alert('hidden');
}
else
{
alert('visible');
}

Herhangi bir css özelliği için çalışır ve çok yönlü ve güvenilirdir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.