Periksa apakah elemen terlihat di DOM

378

Apakah ada cara saya dapat memeriksa apakah suatu elemen terlihat di JS murni (tanpa jQuery)?

Jadi, misalnya, di halaman ini: Performance Bikes , jika Anda mengarahkan kursor pada Transaksi (pada menu atas), jendela transaksi muncul, tetapi pada awalnya tidak ditampilkan. Itu dalam HTML tetapi tidak terlihat.

Jadi, mengingat elemen DOM, bagaimana saya bisa mengecek apakah itu terlihat atau tidak? Saya mencoba:

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

tapi sepertinya tidak berhasil. Saya ingin tahu atribut mana yang harus saya periksa. Itu muncul di benak saya:

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

Adakah orang lain yang mungkin saya lewatkan?

Hommer Smith
sumber
1
Itu tidak menggunakan tampilan, itu menggunakan visibilitas jadi periksa visibilitas (tersembunyi atau terlihat). mis:document.getElementById('snDealsPanel').style.visibility
PSL
PSL. Jika saya ingin melakukan ini secara lebih umum, atribut mana yang harus saya periksa: visibilitas, tampilan ...?
Hommer Smith
Anda dapat membuatnya generik dengan cara Anda sendiri tetapi apa yang saya katakan adalah menggunakan visibilitas memeriksa elemen.
PSL
Ini kode saya (tidak ada jquery) untuk pertanyaan ini stackoverflow.com/a/22969337/2274995
Aleko
Tautan terputus yang membuat pertanyaan Anda tidak mudah dimengerti. Mohon membingkai ulang itu.
yogihosting

Jawaban:

619

Menurut dokumentasi MDN ini , offsetParentproperti elemen akan kembali nullkapan pun, atau salah satu dari orang tuanya, disembunyikan melalui properti gaya tampilan. Pastikan saja bahwa elemen tersebut tidak diperbaiki. Sebuah skrip untuk memeriksa ini, jika Anda tidak memiliki position: fixed;elemen pada halaman Anda, mungkin terlihat seperti:

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

Di sisi lain, jika Anda tidak memiliki elemen posisi tetap yang mungkin terjebak dalam pencarian ini, Anda akan sedih (dan perlahan-lahan) harus digunakan window.getComputedStyle(). Fungsi dalam kasus itu mungkin:

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

Opsi # 2 mungkin sedikit lebih mudah karena ia menyumbang lebih banyak kasus tepi, tapi saya bertaruh itu jauh lebih lambat juga, jadi jika Anda harus mengulangi operasi ini berkali-kali, mungkin yang terbaik untuk menghindarinya.

AlexZ
sumber
Wow tidak bercanda. Seharusnya tidak ada alasan untuk menggunakan metode kedua sebagai solusi universal; tidak ada halaman yang harus memiliki elemen-elemen tetap yang pembuatnya tidak sadari secara eksplisit, dan orang hanya dapat memeriksa mereka secara manual menggunakan metode getComputedStyle () setelah menjalankan metode offsetParent pada semua elemen terlebih dahulu.
AlexZ
6
Juga FYI, baru saja menemukan bahwa el.offsetParenttidak berfungsi pada IE9 untuk elemen yang tidak tetap. Atau begitulah tampaknya. (OK untuk IE11, meskipun.) Jadi pergi dengan getComputedStylesetelah semua.
Nick
1
@AlexZ Saya tidak yakin apakah offsetParent benar-benar melakukan reflow di browser hari ini, tapi ya beberapa tahun lalu, dulu, itu yang saya pahami dari laporan. Perhatikan bahwa jsPerf hanya menyebutkan kecepatan eksekusi, sementara reflow adalah tentang tampilan. Dan reflow memang membuat UI miskin. Saya pribadi tidak akan menggunakan kecepatan untuk rutinitas yang mungkin disebut 5/6 kali dalam satu halaman.
Ethan
2
Sayang! getComputedStyletidak bekerja dengan benar: plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview Namun demikian, apakah offsetParent- mungkin kombinasi dari keduanya harus digunakan?
guy mograbi
2
untuk ie9 + ie10 Anda dapat memeriksa apakah offsetParent = body untuk elemen yang tidak terlihat.
SuperUberDuper
99

Semua solusi lain bangkrut untuk beberapa situasi bagi saya ..

Lihat pemecahan jawaban yang menang di:

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

Akhirnya, saya memutuskan bahwa solusi terbaik adalah $(elem).is(':visible')- namun, ini bukan javascript murni. itu jquery ..

jadi saya mengintip sumber mereka dan menemukan apa yang saya inginkan

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

Ini adalah sumbernya: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js

orang mograbi
sumber
11
Ini akan kembali trueuntuk elemen denganvisibility:hidden
Yuval A.
9
@ YuvalA .: Ya karena elemennya masih terlihat. Mengatur elemen agar visibility:hiddentidak menampilkan konten lagi, tetapi masih membutuhkan lebar dan tinggi elemen!
Jacob van Lingen
4
@Michael Anda dapat dengan mudah menelusuri kode jQuery dan jika Anda menggunakan IDE modern (coba jika tidak), Anda dapat melompat untuk memperbaiki bagian kode saat menggunakan jQuery atau lib lainnya. Anda dapat belajar banyak saat menelusuri basis kode proyek sumber terbuka.
Lukas Liesis
53

Jika Anda tertarik terlihat oleh pengguna:

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

Diuji pada (menggunakan terminologi moka ):

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;
    });
});
Ohad Navon
sumber
kasing tepi jika elem diposisikan di luar viewport, dapat ditangkap oleh "if (! pointContainer) return false;" memeriksa pointContainer pertama
Jerry Deng
Jika Anda ingin memeriksa apakah pengguna dapat melihatnya, Anda harus menggunakan scrollIntoViewhak ?! Ini cukup mahal. Apakah ada cara pintar lain?
Kim Kern
36

Ini mungkin membantu: Sembunyikan elemen dengan memposisikannya pada posisi paling kiri dan kemudian memeriksa properti offsetLeft. Jika Anda ingin menggunakan jQuery, Anda cukup memeriksa pemilih : terlihat dan mendapatkan status visibilitas elemen.

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

Nyonya Ashaduzzaman
sumber
12
OP meminta jawaban no-jQuery.
Stephen Quan
Itu diedit kemudian saya kira. Ketika saya menjawab itu tidak disebutkan di utas.
Ny. Ashaduzzaman
2
@StephenQuan, saya telah memperbarui jawabannya dengan solusi jQuery dan javaScript.
Ny. Ashaduzzaman
6
untuk contoh jQuery, bukankah seharusnya lansiran mengatakan "Div terlihat?"
Andrei Bazanov
Saya tidak ingin menyimpulkan suatu elemen yang sepenuhnya disembunyikan hanya karena offsetLeft-nya kurang dari 0: bagaimana jika itu hanya sejumlah kecil piksel kurang dari 0 dan bagian kanannya terlihat? (Saya setuju ini akan tampak seperti desain yang konyol, tetapi Anda tidak pernah tahu dengan desainer web hari ini.) Mungkin lebih baik untuk menambahkan lebar ke offsetLeft dan melihat apakah hasilnya masih kurang dari 0. Untuk berjaga-jaga.
Silas S. Brown
31

Gunakan kode yang sama dengan jQuery:

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

Jadi, dalam suatu fungsi:

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

Bekerja seperti pesona di Win / IE10, Linux / Firefox.45, Linux / Chrome.52 saya ...

Banyak terima kasih kepada jQuery tanpa jQuery!

Yvan
sumber
Bagus tetapi tidak mencakup elemen yang disembunyikan oleh meluap.
Alph.Dev
bagus tapi apa kenapa !! (negasi ganda)?
Sunil Garg
3
Untuk memaksakan hasilnya sebagai boolean. Seperti e.offsetWidthbilangan bulat, !e.offsetWidthakan kembali falsejika e.offsetWidthlebih tinggi dari nol (elemen terlihat). Jadi menambahkan yang lain !sebagai !!e.offsetWidthakan kembali truejika e.offsetWidthlebih tinggi dari nol. Ini adalah singkatan return e.offsetWidth > 0 ? true : falseatau jelas return e.offsetWidth > 0.
Yvan
16

Menggabungkan beberapa jawaban di atas:

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

Seperti yang dikatakan AlexZ, ini mungkin lebih lambat daripada beberapa opsi Anda yang lain jika Anda tahu lebih spesifik apa yang Anda cari, tetapi ini harus menangkap semua cara utama elemen disembunyikan.

Tapi, itu juga tergantung apa yang dianggap terlihat oleh Anda. Sebagai contoh, ketinggian div dapat diatur ke 0px tetapi isinya masih terlihat tergantung pada properti overflow. Atau konten div bisa dibuat warna yang sama dengan latar belakang sehingga tidak terlihat oleh pengguna tetapi masih ditampilkan di halaman. Atau div bisa dipindahkan dari layar atau disembunyikan di balik div lain, atau isinya bisa tidak terlihat tetapi perbatasan masih terlihat. Sampai batas tertentu "terlihat" adalah istilah subyektif.

Matius
sumber
1
Bagus, tetapi style.opacity, style.height dan style.width mengembalikan string sehingga tidak akan bekerja dengan! ==
Maslow
Cara lain suatu elemen dapat disembunyikan melalui gaya adalah bahwa warnanya bisa cocok dengan warna latar belakang, atau indeks-znya bisa lebih rendah daripada elemen lainnya.
nu everest
menambah display:noneini akan bagus. Solusi kerja yang tepat!
Gijo Varghese
7

Saya punya solusi yang lebih performan dibandingkan dengan solusi getComputedStyle () AlexZ ketika seseorang memiliki posisi elemen 'tetap', jika seseorang mau mengabaikan beberapa kasus tepi (periksa komentar):

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

Catatan tambahan: Secara tegas, "visibilitas" perlu didefinisikan terlebih dahulu. Dalam kasus saya, saya mempertimbangkan elemen yang terlihat selama saya bisa menjalankan semua metode / properti DOM tanpa masalah (bahkan jika opacity 0 atau properti visibilitas CSS 'tersembunyi' dll).

Munawwar
sumber
6

Jika elemen terlihat biasa (tampilan: blok dan visibillity: terlihat), tetapi beberapa wadah induk disembunyikan, maka kita dapat menggunakan clientWidth dan clientHeight untuk memeriksa itu.

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

Plunker (klik di sini)

Vlada
sumber
ele.style.visibility !== 'hidden'berlebihan di sini. Jika demikian, clientWidth dan clientHeight akan menjadi 0.
subdavis
5

Jika kami hanya mengumpulkan cara dasar mendeteksi visibilitas, jangan lupa:

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

Dan bagaimana cara mendapatkan atribut:

element.getAttribute(attributename);

Jadi, dalam contoh Anda:

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

Tapi apa? Ini tidak berfungsi di sini. Lihatlah lebih dekat dan Anda akan menemukan bahwa visibilitas sedang diperbarui bukan sebagai atribut pada elemen, tetapi menggunakan styleproperti. Ini adalah salah satu dari banyak masalah dengan mencoba melakukan apa yang Anda lakukan. Antara lain: Anda tidak dapat menjamin bahwa sebenarnya ada sesuatu untuk dilihat dalam suatu elemen, hanya karena visibilitas, tampilan, dan opacity semuanya memiliki nilai yang benar. Mungkin masih kekurangan konten, atau mungkin memiliki tinggi dan lebar. Objek lain mungkin mengaburkannya. Untuk lebih detail, pencarian Google cepat mengungkapkan ini , dan bahkan menyertakan perpustakaan untuk mencoba memecahkan masalah. (YMMV)

Lihatlah yang berikut, yang merupakan duplikat yang mungkin dari pertanyaan ini, dengan jawaban yang sangat baik, termasuk beberapa wawasan dari John Resig yang perkasa. Namun, case-use khusus Anda sedikit berbeda dari yang standar, jadi saya akan menahan diri untuk tidak memberi tanda:

(EDIT: OP MENGATAKAN HAL-HAL YANG MENGHANCURKAN, TIDAK MENCIPTAKAN MEREKA, BEGITU DI BAWAH INI TIDAK BERLAKU) Pilihan yang lebih baik? Ikat visibilitas elemen untuk memodelkan properti dan selalu membuat visibilitas bergantung pada model itu, seperti halnya Angular dengan ng-show. Anda dapat melakukannya dengan menggunakan alat apa pun yang Anda inginkan: Angular, JS polos, apa pun. Lebih baik lagi, Anda dapat mengubah implementasi DOM dari waktu ke waktu, tetapi Anda akan selalu dapat membaca status dari model, alih-alih DOM. Membaca kebenaran Anda dari DOM itu Buruk. Dan lambat. Jauh lebih baik untuk memeriksa model, dan percaya pada implementasi Anda untuk memastikan bahwa keadaan DOM mencerminkan model. (Dan gunakan pengujian otomatis untuk mengonfirmasi asumsi itu.)

XML
sumber
Saya parsing situs, ini bukan untuk situs saya sendiri ... :)
Hommer Smith
4

Jawaban yang diterima tidak berhasil untuk saya. Tahun 2020 jawabannya :

1) Metode (elem.offsetParent! == null) berfungsi dengan baik di Firefox tetapi tidak di Chrome. Untuk Chrome "position: fixed;" juga akan membuat pengembalian offsetParent "null" bahkan elemen jika terlihat di halaman.

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>

Anda dapat melihat megatest orang ini https://stackoverflow.com/a/11639664/4481831 (jalankan dengan beberapa browser untuk melihat perbedaannya).

2) The (getComputedStyle (elem) .display! == 'tidak ada') tidak berfungsi karena elemen dapat tidak terlihat karena salah satu properti tampilan orang tua diatur ke tidak ada, getComputedStyle tidak akan menangkap itu.

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) The (elem.clientHeight! == 0) . Metode ini tidak dipengaruhi oleh posisi tetap dan juga memeriksa apakah elemen orangtua tidak terlihat. Tetapi memiliki masalah dengan elemen sederhana yang tidak memiliki tata letak css, lihat lebih lanjut di sini

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) The (elem.getClientRects (). Length! == 0) yang tampaknya mengatasi masalah dari 3 metode sebelumnya. Namun memiliki masalah dengan elemen yang menggunakan trik CSS (selain itu "display: none") untuk disembunyikan di halaman.

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>

KESIMPULAN: Jadi yang saya tunjukkan kepada Anda adalah bahwa tidak ada metode yang sempurna. Untuk membuat pemeriksaan visibilitas yang tepat, Anda harus menggunakan kombinasi dari 3 metode terakhir.

crisc82
sumber
3

Hanya untuk referensi perlu dicatat bahwa getBoundingClientRect()dapat bekerja dalam kasus-kasus tertentu.

Misalnya, pemeriksaan sederhana bahwa elemen yang disembunyikan menggunakan display: nonebisa terlihat seperti ini:

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

Ini juga berguna karena juga mencakup lebar nol, tinggi nol, dan position: fixedkasing. Namun, ia tidak akan melaporkan unsur-unsur yang disembunyikan dengan opacity: 0atau visibility: hidden(tetapi tidak akan offsetParent).

menjelmakan
sumber
Jawaban terbaik untuk saya ... sederhana dan efektif. Dan tidak ada satu pun upvote setelah 3 tahun! Terus menunjukkan nilai "kerumunan kebijaksanaan". Versi saya: var isVisible = el => (r => r.width && r.height)(el.getBoundingClientRect());. Kemudian saya dapat menyaring array dari elemen dengan cara berikut: $$(sel).filter(isVisible).
7vujy0f0hy
Saya menemukannya sebagai solusi pengembang yang
Marian07
Ini tidak berfungsi ketika terlihat oleh pengguna .... jika Anda menggulirnya pergi itu akan tetap benar
Ray Foss
3

Jadi apa yang saya temukan adalah metode yang paling layak:

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

Ini didasarkan pada fakta-fakta ini:

  • Sebuah display: noneelemen (bahkan yang bersarang) tidak memiliki lebar atau tinggi.
  • visiblityadalah hiddenbahkan untuk elemen bersarang.

Jadi tidak perlu untuk menguji offsetParentatau mengulang di pohon DOM untuk menguji yang orang tua miliki visibility: hidden. Ini harus bekerja bahkan di IE 9.

Anda bisa berargumen jika opacity: 0dan elemen yang runtuh (memiliki lebar tetapi tidak ada ketinggian - atau sebaliknya) juga tidak benar-benar terlihat. Tetapi sekali lagi mereka tidak per kata disembunyikan.

Tokimon
sumber
3

Sedikit tambahan untuk jawaban ohad navon.

Jika pusat elemen milik elemen lain, kami tidak akan menemukannya.

Jadi untuk memastikan bahwa salah satu titik elemen ditemukan terlihat

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;
}
Guy Messika
sumber
3

Meningkatkan pada jawaban @Guy Messika di atas , melanggar dan mengembalikan false jika titik pusat 'X adalah <0 salah karena elemen sisi kanan dapat masuk ke tampilan. inilah perbaikannya:

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;
}
Israel
sumber
2

Kode jQuery dari http://code.jquery.com/jquery-1.11.1.js memiliki param isHidden

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

Jadi sepertinya ada pemeriksaan tambahan terkait dengan dokumen pemilik

Saya ingin tahu apakah ini benar-benar menangkap kasus-kasus berikut:

  1. Elemen tersembunyi di balik elemen lain berdasarkan zIndex
  2. Elemen dengan transparansi penuh membuatnya tidak terlihat
  3. Elemen diposisikan di luar layar (yaitu kiri: -1000px)
  4. Elemen dengan visibilitas: disembunyikan
  5. Elemen dengan tampilan: tidak ada
  6. Elemen tanpa teks atau sub elemen yang terlihat
  7. Elemen dengan tinggi atau lebar diatur ke 0
Scott Izu
sumber
0

Inilah kode yang saya tulis untuk menemukan satu-satunya yang terlihat di antara beberapa elemen serupa, dan mengembalikan nilai atribut "class" tanpa jQuery:

  // 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");
    }
  }
not_specified
sumber
0

Inilah yang saya lakukan:

HTML & CSS: Membuat elemen disembunyikan secara default

<html>
<body>

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

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

</body>
</html> 

JavaScript: Menambahkan kode untuk memeriksa apakah visibilitasnya tersembunyi atau tidak:

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

Ini adalah cara untuk menentukannya untuk semua properti css termasuk visibilitas:

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');
}

Ia bekerja untuk properti css dan sangat fleksibel dan dapat diandalkan.

William Green
sumber