Apakah ada cara bahwa saya dapat memeriksa apakah sebuah elemen yang terlihat di JS murni (tanpa jQuery) ?
Jadi, misalnya, di halaman ini: Kinerja Sepeda, jika anda membawa lebih dari Penawaran (pada menu bagian atas), jendela penawaran muncul, tapi di awal itu tidak ditampilkan. Hal ini di HTML tapi itu tidak terlihat.
Jadi, mengingat elemen DOM, bagaimana saya dapat periksa jika itu terlihat atau tidak? Saya mencoba:
window.getComputedStyle(my_element)['display']);
tapi itu doesn't tampaknya akan bekerja. Aku bertanya-tanya atribut mana yang harus saya periksa. Datang ke pikiran saya:
display !== 'none'
visibility !== 'hidden'
Setiap orang lain bahwa saya bisa hilang?
Menurut ini MDN dokumentasi, elemen's offsetParent
properti akan kembali null
setiap kali, atau setiap orang tua, tersembunyi melalui gaya tampilan properti. Hanya pastikan bahwa elemen isn't tetap. Script 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 ** memiliki posisi tetap unsur-unsur yang mungkin terjebak dalam pencarian ini, anda akan sedih (dan perlahan-lahan) harus menggunakan jendela.getComputedStyle()
. Fungsi dalam hal ini 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 ini mungkin sedikit lebih mudah karena menyumbang lebih edge kasus, tapi aku yakin yang bergerak lebih lambat, terlalu, jadi jika anda harus mengulangi operasi ini berkali-kali, terbaik kepada mungkin menghindari itu.
Semua solusi lainnya pecah untuk beberapa situasi untuk saya..
Melihat pemenang menjawab melanggar di:
http://plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview
Akhirnya, saya memutuskan bahwa solusi yang terbaik adalah $(elem).adalah(':terlihat')
- namun, ini bukan murni javascript. itu adalah jquery..
jadi saya mengintip di sumber mereka dan menemukan apa yang saya inginkan
jQuery.expr.filters.visible = function( elem ) {
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};
Ini adalah sumber: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js
Jika anda're tertarik pada 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 mocha terminologi):
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;
});
});
Ini mungkin dapat membantu : Menyembunyikan elemen dengan posisi ini jauh di paling kiri posisi dan kemudian memeriksa offsetLeft properti. Jika anda ingin menggunakan jQuery anda hanya dapat memeriksa :terlihat pemilih dan mendapatkan visibilitas negara dari 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 hidden!!");
}
Menggunakan kode yang sama seperti jQuery tidak:
jQuery.expr.pseudos.visible = function( elem ) {
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};
Jadi, dalam sebuah fungsi:
function isVisible(e) {
return !!( e.offsetWidth || e.offsetHeight || e.getClientRects().length );
}
Bekerja seperti pesona pada saya Menang/IE10, Linux/Firefox.45, Linux/Chrome.52...
Banyak terima kasih untuk jQuery tanpa jQuery!
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 AlexZ mengatakan, ini mungkin lebih lambat dari beberapa pilihan lain jika anda tahu lebih khusus apa yang anda'kembali mencari, tapi ini harus menangkap semua cara utama unsur-unsur yang tersembunyi.
Tapi, itu juga tergantung apa yang dianggap sebagai terlihat untuk anda. Hanya untuk contoh, sebuah div's ketinggian dapat diatur untuk 0px tapi isi masih terlihat tergantung pada overflow dan offline. Atau div's isi dapat dibuat dengan warna yang sama sebagai latar belakang sehingga tidak terlihat oleh pengguna tetapi masih diberikan pada halaman. Atau div yang bisa dipindahkan dari layar atau tersembunyi di balik lain divs, atau's isi bisa menjadi non-terlihat tapi perbatasan masih terlihat. Untuk batas tertentu "terlihat" adalah istilah subjektif.
Jika elemen ini biasa terlihat (display:block dan visibillity:terlihat), tetapi beberapa orang tua wadah tersembunyi, 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';
}
I've punya lebih tampak larutan dibandingkan dengan AlexZ's getComputedStyle() solusi ketika seseorang memiliki posisi 'tetap' elemen, jika seseorang bersedia untuk mengabaikan beberapa kasus tepi (lihat 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: sebenarnya, "visibilitas" perlu didefinisikan terlebih dahulu. Dalam kasus saya, saya mempertimbangkan unsur terlihat selama aku bisa menjalankan semua DOM metode/sifat-sifat itu tanpa masalah (bahkan jika opacity adalah 0 atau CSS visibility properti 'tersembunyi' dll).
Jika kita're hanya mengumpulkan dasar cara mendeteksi visibilitas, biar tidak lupa:
opacity > 0.01; // probably more like .1 to actually be visible, but YMMV
Dan bagaimana untuk mendapatkan atribut:
element.getAttribute(attributename);
Jadi, dalam contoh anda:
document.getElementById('snDealsPanel').getAttribute('visibility');
Tapi apa? Itu doesn't bekerja di sini. Lihat lebih dekat dan anda'll menemukan bahwa visibilitas sedang diperbarui bukan sebagai atribut pada elemen, tetapi menggunakan gaya
properti. Ini adalah salah satu dari banyak masalah dengan mencoba untuk melakukan apa yang anda're lakukan. Antara lain: anda dapat't menjamin bahwa tidak's benar-benar sesuatu untuk melihat dalam elemen, hanya karena visibilitas, tampilan, dan opacity semua memiliki nilai yang benar. Mungkin masih kurangnya konten, atau mungkin kurangnya ketinggian dan lebar. Objek lain yang mungkin tidak jelas itu. Untuk lebih detail, cepat pencarian Google mengungkapkan ini, dan bahkan termasuk perpustakaan untuk mencoba memecahkan masalah. (YMMV)
Simak berikut ini, yang mungkin duplikat dari pertanyaan ini dengan jawaban yang sangat baik, termasuk beberapa wawasan dari perkasa John Resig. Namun, khusus anda gunakan-hal yang sedikit berbeda dari yang standar, jadi saya'll menahan diri dari lesu:
(EDIT: OP MENGATAKAN IA'S MENGGORES HALAMAN, TIDAK MENCIPTAKAN MEREKA, JADI DI BAWAH INI ISN'T BERLAKU) Pilihan yang lebih baik? Mengikat visibilitas elemen untuk memodelkan sifat dan selalu membuat visibilitas bergantung pada model itu, banyak Sudut dengan ng-show. Anda dapat melakukannya dengan menggunakan alat apapun yang anda inginkan: Sudut, polos JS, apa pun. Lebih baik lagi, anda dapat mengubah DOM implementasi dari waktu ke waktu, tetapi anda'll selalu dapat membaca keadaan dari model tersebut, bukan DOM. Membaca kebenaran dari DOM yang Buruk. Dan lambat. Jauh lebih baik untuk memeriksa model, dan kepercayaan dalam implementasi untuk memastikan bahwa DOM negara sesuai dengan model. (Dan menggunakan pengujian otomatis untuk mengkonfirmasi bahwa asumsi.)
Hanya untuk referensi itu harus dicatat bahwa getBoundingClientRect()
dapat bekerja dalam kasus-kasus tertentu.
Misalnya, sebuah cek sederhana bahwa elemen tersembunyi menggunakan display: none
bisa terlihat seperti ini:
var box = element.getBoundingClientRect();
var visible = box.width && box.height;
Ini juga berguna karena hal ini juga mencakup lebar-nol, nol-tinggi dan posisi: tetap
kasus. Namun, hal itu tidak akan melaporkan unsur-unsur tersembunyi dengan opacity: 0
atau visibility: hidden
(tapi tidak akan offsetParent
).
Jadi apa yang saya temukan adalah yang paling layak metode:
function visible(elm) {
if(!elm.offsetHeight && !elm.offsetWidth) { return false; }
if(getComputedStyle(elm).visibility === 'hidden') { return false; }
return true;
}
Ini adalah membangun fakta-fakta ini:
Display: none
elemen (bahkan bersarang satu) doesn't memiliki lebar maupun tinggi.visiblity
adalah tersembunyi
bahkan untuk bersarang elemen.Sehingga tidak perlu untuk testing offsetParent
atau perulangan dalam DOM tree untuk menguji mana orang tua telah visibility: hidden
. Ini harus bekerja bahkan di IE 9.
Anda bisa berpendapat jika opacity: 0
dan runtuh elemen (memiliki lebar tapi tidak tinggi atau visa versa) adalah benar-benar tidak terlihat baik. Tapi kemudian lagi-lagi mereka tidak per mengatakan tersembunyi.
Sedikit tambahan untuk ohad navon's jawaban.
Jika pusat dari elemen termasuk unsur lain kita tidak't menemukan itu.
Jadi untuk memastikan bahwa salah satu poin dari unsur ini ditemukan untuk menjadi 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;
}
Peningkatan pada @Orang Messika's jawaban atas, melanggar dan mengembalikan false jika titik pusat' X < 0 adalah salah sebagai elemen sisi kanan dapat masuk ke tampilan. berikut ini's a fix:
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;
}
Kode jQuery dari http://code.jquery.com/jquery-1.11.1.js memiliki isHidden param
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 pemilik dokumen
Aku bertanya-tanya apakah ini benar-benar menangkap kasus-kasus berikut:
Ini mengembalikan true jika dan hanya jika elemen dan semua nenek moyang yang terlihat. Itu hanya terlihat pada display
dan `visibilitas'style sifat:
var isVisible = function(el){
// returns true iff el and all its ancestors are visible
return el.style.display !== 'none' && el.style.visibility !== 'hidden'
&& (el.parentElement? isVisible(el.parentElement): true)
};
Berikut ini's kode yang saya tulis untuk menemukan hanya terlihat di antara beberapa unsur yang sama, dan mengembalikan nilai dari "kelas" atribut 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");
}
}
Ini adalah apa yang saya lakukan:
HTML & CSS: Membuat elemen tersembunyi 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 visibilitas yang 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>
Ini adalah cara untuk menentukan 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 setiap properti css dan sangat serbaguna dan dapat diandalkan.