Tergantung apa yang Anda maksud dengan terlihat. Jika yang Anda maksud adalah saat ini ditampilkan pada halaman, diberi posisi gulir, Anda dapat menghitungnya berdasarkan elemen y offset dan posisi gulir saat ini.
roryf
18
Klarifikasi: Terlihat, seperti di dalam persegi panjang yang saat ini ditampilkan. Terlihat, seperti tidak disembunyikan atau ditampilkan: tidak ada? Terlihat, seperti tidak di belakang sesuatu yang lain di Z-order?
Adam Wright
6
seperti di dalam persegi panjang yang saat ini ditampilkan. Terima kasih. Diulang
benzaita
2
Perhatikan bahwa semua jawaban di sini akan memberi Anda positif palsu untuk item yang berada di luar area terlihat elemen induknya (eh dengan luapan tersembunyi) tetapi di dalam area viewport.
Pembaruan: Waktu berjalan terus dan begitu juga browser kami. Teknik ini tidak lagi direkomendasikan dan Anda harus menggunakan solusi Dan jika Anda tidak perlu mendukung versi Internet Explorer sebelum 7.
Solusi asli (sekarang kedaluwarsa):
Ini akan memeriksa apakah elemen tersebut sepenuhnya terlihat di viewport saat ini:
function elementInViewport(el){var top = el.offsetTop;var left = el.offsetLeft;var width = el.offsetWidth;var height = el.offsetHeight;while(el.offsetParent){
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;}return(
top >= window.pageYOffset &&
left >= window.pageXOffset &&(top + height)<=(window.pageYOffset + window.innerHeight)&&(left + width)<=(window.pageXOffset + window.innerWidth));}
Anda dapat memodifikasi ini hanya untuk menentukan apakah ada bagian elemen yang terlihat di viewport:
function elementInViewport2(el){var top = el.offsetTop;var left = el.offsetLeft;var width = el.offsetWidth;var height = el.offsetHeight;while(el.offsetParent){
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;}return(
top <(window.pageYOffset + window.innerHeight)&&
left <(window.pageXOffset + window.innerWidth)&&(top + height)> window.pageYOffset &&(left + width)> window.pageXOffset
);}
Fungsi asli yang diposting memiliki kesalahan. Diperlukan untuk menyimpan lebar / tinggi sebelum menetapkan ulang ...
Prestaul
15
Bagaimana jika elemen tersebut hidup dalam div yang dapat digulir dan digulir ke luar dari tampilan ??
amartynov
2
Harap tinjau versi terbaru dari skrip di bawah ini
Dan
1
Juga ingin tahu tentang pertanyaan @ amartynov. Adakah yang tahu bagaimana cara mengetahui apakah suatu elemen disembunyikan karena melimpahnya unsur leluhur? Bonus jika ini dapat dideteksi terlepas dari seberapa dalam sarangnya anak itu.
Eric Nguyen
1
@deadManN berulang melalui DOM sangat lambat. Itu alasan yang cukup, tetapi vendor peramban juga telah menciptakan getBoundingClientRectsecara spesifik tujuan menemukan koordinat elemen ... Mengapa kita tidak menggunakannya?
Solusi ini diuji pada Internet Explorer 7 (dan yang lebih baru), iOS 5 (dan yang lebih baru) Safari, Android 2.0 (Eclair) dan yang lebih baru, BlackBerry, Opera Mobile, dan Internet Explorer Mobile 9 .
function isElementInViewport (el){// Special bonus for those using jQueryif(typeof jQuery ==="function"&& el instanceof jQuery){
el = el[0];}var rect = el.getBoundingClientRect();return(
rect.top >=0&&
rect.left >=0&&
rect.bottom <=(window.innerHeight || document.documentElement.clientHeight)&&/* or $(window).height() */
rect.right <=(window.innerWidth || document.documentElement.clientWidth)/* or $(window).width() */);}
Cara Penggunaan:
Anda dapat yakin bahwa fungsi yang diberikan di atas mengembalikan jawaban yang benar pada saat dipanggil, tetapi bagaimana dengan visibilitas elemen pelacakan sebagai suatu peristiwa?
Tempatkan kode berikut di bagian bawah <body>tag Anda :
function onVisibilityChange(el, callback){var old_visible;returnfunction(){var visible = isElementInViewport(el);if(visible != old_visible){
old_visible = visible;if(typeof callback =='function'){
callback();}}}}var handler = onVisibilityChange(el,function(){/* Your code go here */});// jQuery
$(window).on('DOMContentLoaded load resize scroll', handler);/* // Non-jQuery
if (window.addEventListener) {
addEventListener('DOMContentLoaded', handler, false);
addEventListener('load', handler, false);
addEventListener('scroll', handler, false);
addEventListener('resize', handler, false);
} else if (window.attachEvent) {
attachEvent('onDOMContentLoaded', handler); // Internet Explorer 9+ :(
attachEvent('onload', handler);
attachEvent('onscroll', handler);
attachEvent('onresize', handler);
}
*/
Jika Anda melakukan modifikasi DOM, mereka dapat mengubah visibilitas elemen Anda tentu saja.
Panduan dan perangkap umum:
Mungkin Anda perlu melacak halaman zoom / cubit perangkat seluler? jQuery harus menangani zoom / pinch cross browser, jika tidak, pertama atau kedua tautan akan membantu Anda.
Jika Anda memodifikasi DOM , ini dapat memengaruhi visibilitas elemen. Anda harus mengambil kendali atas itu dan menelepon handler()secara manual. Sayangnya, kami tidak memiliki browser lintasonrepaint acara . Di sisi lain yang memungkinkan kami melakukan optimasi dan melakukan pengecekan ulang hanya pada modifikasi DOM yang dapat mengubah visibilitas elemen.
Never Ever menggunakannya di dalam jQuery $ (document) .ready () saja, karena tidak ada jaminan CSS telah diterapkan pada saat ini. Kode Anda dapat bekerja secara lokal dengan CSS Anda pada hard drive, tetapi sekali memakai server jauh itu akan gagal.
Setelah DOMContentLoadeddipecat, gaya diterapkan , tetapi gambar belum dimuat . Jadi, kita harus menambahkan window.onloadpendengar acara.
Kami belum dapat menangkap acara zoom / pinch.
Pilihan terakhir bisa berupa kode berikut:
/* TODO: this looks like a very bad code */
setInterval(handler,600);
Anda dapat menggunakan pageVisibiliy fitur hebat dari API HTML5 jika Anda peduli jika tab dengan halaman web Anda aktif dan terlihat.
Saya menggunakan solusi ini (berhati-hatilah terhadap kesalahan ketik "botom"). Ada juga sesuatu yang harus diperhatikan, ketika elemen yang kita pertimbangkan akan memiliki gambar di dalamnya. Chrome (setidaknya) harus menunggu gambar dimuat agar memiliki nilai tepat untuk boundingRectangle. Tampaknya Firefox tidak memiliki "masalah" ini
Claudio
4
Apakah itu berfungsi ketika Anda mengaktifkan scrolling di wadah di dalam tubuh. Misalnya tidak berfungsi di sini - agaase.github.io/webpages/demo/isonscreen2.html isElementInViewport (document.getElementById ("innerele")). innerele hadir di dalam wadah yang memiliki scrolling diaktifkan.
agaase
70
Perhitungan mengasumsikan bahwa elemen lebih kecil dari layar. Jika Anda memiliki elemen tinggi atau lebar, mungkin lebih akurat untuk digunakanreturn (rect.bottom >= 0 && rect.right >= 0 && rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth));
Roonaan
11
Kiat: Bagi mereka yang mencoba menerapkan ini dengan jQuery, hanya pengingat yang ramah untuk meneruskan objek HTML DOM (misalnya, isElementInViewport(document.getElementById('elem'))) dan bukan objek jQuery (misalnya, isElementInViewport($("#elem))). Setara jQuery adalah menambahkan[0] seperti: isElementInViewport($("#elem)[0]).
Jimin
11
el is not defined
M_Willett
176
Memperbarui
Di browser modern, Anda mungkin ingin memeriksa API Pengamat titik - temu yang memberikan manfaat berikut:
Performa yang lebih baik daripada mendengarkan acara gulir
Bekerja di iframe lintas domain
Dapat mengetahui apakah suatu elemen menghalangi / berpotongan lainnya
Intersection Observer sedang dalam perjalanan untuk menjadi standar penuh dan sudah didukung di Chrome 51+, Edge 15+ dan Firefox 55+ dan sedang dikembangkan untuk Safari. Tersedia juga polyfill .
Jawaban sebelumnya
Ada beberapa masalah dengan jawaban yang diberikan Dan yang mungkin membuatnya menjadi pendekatan yang tidak cocok untuk beberapa situasi. Beberapa masalah ini ditunjukkan dalam jawabannya di dekat bagian bawah, bahwa kodenya akan memberikan hasil positif palsu untuk elemen yang:
Tersembunyi oleh elemen lain di depan yang sedang diuji
Di luar area yang terlihat elemen induk atau leluhur
Elemen atau anak-anaknya disembunyikan dengan menggunakan clipproperti CSS
Inilah solusi untuk masalah-masalah tersebut, dengan hasil tes di bawah ini dan penjelasan dari beberapa bagian kode
function isElementVisible(el){var rect = el.getBoundingClientRect(),
vWidth = window.innerWidth || document.documentElement.clientWidth,
vHeight = window.innerHeight || document.documentElement.clientHeight,
efp =function(x, y){return document.elementFromPoint(x, y)};// Return false if it's not in the viewportif(rect.right <0|| rect.bottom <0|| rect.left > vWidth || rect.top > vHeight)returnfalse;// Return true if any of its four corners are visiblereturn(
el.contains(efp(rect.left, rect.top))|| el.contains(efp(rect.right, rect.top))|| el.contains(efp(rect.right, rect.bottom))|| el.contains(efp(rect.left, rect.bottom)));}
Namun metode ini bukan tanpa batasannya sendiri. Misalnya, elemen yang diuji dengan indeks-z lebih rendah daripada elemen lain di lokasi yang sama akan diidentifikasi sebagai disembunyikan bahkan jika elemen di depan tidak benar-benar menyembunyikan bagiannya. Namun, metode ini memiliki kegunaan dalam beberapa kasus yang tidak dicakup solusi Dan.
Keduanya element.getBoundingClientRect()dan document.elementFromPoint()merupakan bagian dari spesifikasi Draft Kerja CSSOM dan didukung di setidaknya IE 6 dan yang lebih baru dan sebagian besar browser desktop untuk waktu yang lama (meskipun, tidak sempurna). Lihat Quirksmode pada fungsi-fungsi ini untuk informasi lebih lanjut.
contains()digunakan untuk melihat apakah elemen yang dikembalikan oleh document.elementFromPoint()adalah simpul anak dari elemen yang kami uji untuk visibilitas. Ini juga mengembalikan true jika elemen yang dikembalikan adalah elemen yang sama. Ini hanya membuat pemeriksaan lebih kuat. Ini didukung di semua browser utama, Firefox 9.0 menjadi yang terakhir yang menambahkannya. Untuk dukungan Firefox yang lebih lama, periksa riwayat jawaban ini.
Jika Anda ingin menguji lebih banyak poin di sekitar elemen untuk visibilitas ― yaitu, untuk memastikan elemen tidak tercakup oleh lebih dari, katakanlah, 50% ― tidak perlu banyak untuk menyesuaikan bagian terakhir dari jawaban. Namun, perlu diketahui bahwa mungkin akan sangat lambat jika Anda memeriksa setiap piksel untuk memastikan itu 100% terlihat.
Apakah Anda bermaksud menggunakan doc.documentElement.clientWidth? Haruskah itu menjadi 'document.documentElement' sebagai gantinya? Pada catatan yang berbeda, ini adalah satu-satunya metode yang juga berfungsi untuk kasus penggunaan seperti menyembunyikan konten elemen untuk aksesibilitas menggunakan properti 'clip' CSS: snook.ca/archives/html_and_css/hiding-content-for-accessibility
Kevin Lamping
@ klamping: tangkapan yang bagus, terima kasih. Saya telah menyalinnya langsung dari kode tempat saya menggunakan docsebagai alias untuk document. Ya, saya suka menganggap ini sebagai solusi yang layak untuk kasus tepi.
Andy E
2
Bagi saya itu tidak berfungsi. Tetapi inViewport () pada jawaban sebelumnya berfungsi di FF.
Satya Prakash
9
Mungkin juga bermanfaat untuk memeriksa bahwa pusat elemen terlihat jika Anda memiliki sudut bundar atau transformasi yang diterapkan, karena sudut yang terikat mungkin tidak mengembalikan elemen yang diharapkan:element.contains(efp(rect.right - (rect.width / 2), rect.bottom - (rect.height / 2)))
Jared
2
Tidak bekerja pada input untuk saya (chrome canary 50). Tidak yakin mengapa, mungkin sudut bulat asli? Saya harus mengurangi sedikit coords untuk membuatnya berfungsi el.contains (efp (rect.left + 1, rect.top + 1)) || el.contains (efp (rect.right-1, rect.top + 1)) || el.contains (efp (rect.right-1, rect.bottom-1)) || el.contains (efp (rect.left + 1, rect.bottom-1))
Rayjax
65
Saya mencoba jawaban Dan . Namun , aljabar yang digunakan untuk menentukan batas berarti bahwa elemen tersebut harus berukuran ≤ ukuran viewport dan sepenuhnya berada di dalam viewport true, sehingga mudah mengarah ke negatif palsu. Jika Anda ingin menentukan apakah suatu elemen ada di viewport sama sekali, jawaban ryanve dekat, tetapi elemen yang diuji harus tumpang tindih dengan viewport, jadi coba ini:
function isElementInViewport(el){var rect = el.getBoundingClientRect();return rect.bottom >0&&
rect.right >0&&
rect.left <(window.innerWidth || document.documentElement.clientWidth)/* or $(window).width() */&&
rect.top <(window.innerHeight || document.documentElement.clientHeight)/* or $(window).height() */;}
Sebagai layanan publik:
Jawaban Dan dengan perhitungan yang benar (elemen dapat> jendela, terutama pada layar ponsel), dan pengujian jQuery yang benar, serta menambahkan isElementPartiallyInViewport:
By the way, perbedaan antara window.innerWidth dan document.documentElement.clientWidth adalah bahwa clientWidth / clientHeight tidak termasuk scrollbar, sedangkan window.innerWidth / Height tidak.
function isElementPartiallyInViewport(el){// Special bonus for those using jQueryif(typeof jQuery !=='undefined'&& el instanceof jQuery)
el = el[0];var rect = el.getBoundingClientRect();// DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }var windowHeight =(window.innerHeight || document.documentElement.clientHeight);var windowWidth =(window.innerWidth || document.documentElement.clientWidth);// http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlapvar vertInView =(rect.top <= windowHeight)&&((rect.top + rect.height)>=0);var horInView =(rect.left <= windowWidth)&&((rect.left + rect.width)>=0);return(vertInView && horInView);}// http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewportfunction isElementInViewport (el){// Special bonus for those using jQueryif(typeof jQuery !=='undefined'&& el instanceof jQuery)
el = el[0];var rect = el.getBoundingClientRect();var windowHeight =(window.innerHeight || document.documentElement.clientHeight);var windowWidth =(window.innerWidth || document.documentElement.clientWidth);return((rect.left >=0)&&(rect.top >=0)&&((rect.left + rect.width)<= windowWidth)&&((rect.top + rect.height)<= windowHeight));}function fnIsVis(ele){var inVpFull = isElementInViewport(ele);var inVpPartial = isElementPartiallyInViewport(ele);
console.clear();
console.log("Fully in viewport: "+ inVpFull);
console.log("Partially in viewport: "+ inVpPartial);}
Untuk isElementInViewport (e): Kode Anda bahkan tidak memuat gambar, Yang ini benar: fungsi isElementInViewport (e) {var t = e.getBoundingClientRect (); kembalikan t.top> = 0 && t.left> = 0 && t.bottom <= (window.innerHeight || document.documentElement.clientHeight) && t.right <= (window.innerWidth || document.documentElement.clientWidth) }
Arun chauhan
1
@Arun chauhan: Tidak ada kode saya yang memuat gambar, jadi mengapa harus demikian, dan rumusnya benar.
Stefan Steiger
1
@targumon: Alasannya adalah dukungan dari browser lama.
Stefan Steiger
1
@StefanSteiger menurut MDN didukung sejak IE9 sehingga praktis aman (setidaknya dalam kasus saya) hanya menggunakan window.innerHeight secara langsung. Terima kasih!
Solusi saya lebih serakah dan lebih cepat, ketika elemen memiliki piksel dalam viewport, itu akan kembali salah.
Eric Chen
1
Saya suka itu. Ringkas. Anda bisa menghapus spasi antara nama fungsi dan tanda kurung, dan antara tanda kurung dan tanda kurung, pada baris pertama. Tidak pernah menyukai ruang itu. Mungkin hanya editor Teks saya yang memberi kode warna semua yang masih membuatnya mudah dibaca. function aaa (arg) {pernyataan} Saya tahu itu tidak membuatnya mengeksekusi lebih cepat, termasuk dalam minifying.
YK
21
Saya merasa bermasalah bahwa tidak ada versi jQuery- sentris dari fungsi yang tersedia. Ketika saya menemukan solusi Dan, saya memata-matai kesempatan untuk menyediakan sesuatu untuk orang-orang yang suka memprogram dalam gaya jQuery OO. Sangat bagus dan tajam dan bekerja seperti pesona bagi saya.
Bada bing bada booming
$.fn.inView =function(){if(!this.length)returnfalse;var rect =this.get(0).getBoundingClientRect();return(
rect.top >=0&&
rect.left >=0&&
rect.bottom <=(window.innerHeight || document.documentElement.clientHeight)&&
rect.right <=(window.innerWidth || document.documentElement.clientWidth));};// Additional examples for other use cases// Is true false whether an array of elements are all in view
$.fn.allInView =function(){var all =[];this.forEach(function(){
all.push( $(this).inView());});return all.indexOf(false)===-1;};// Only the class elements in view
$('.some-class').filter(function(){return $(this).inView();});// Only the class elements not in view
$('.some-class').filter(function(){return!$(this).inView();});
Pemakaian
$(window).on('scroll',function(){if( $('footer').inView()){// Do cool stuff}});
Apakah kurung kurawal cukup untuk menutup pernyataan if?
calasyr
1
Saya tidak bisa membuatnya bekerja dengan banyak elemen dari kelas yang identik.
The Whiz of Oz
1
@TheWhizofOz saya telah memperbarui jawaban saya untuk memberikan contoh-contoh kasus penggunaan lain yang mungkin telah Anda kemukakan. semoga berhasil.
Solusi ini akan memerlukan polyfill karena Safari, Opera dan Internet Explorer belum mendukung ini (polyfill termasuk dalam solusi).
Dalam solusi ini, ada kotak di luar pandangan yang menjadi target (diamati). Ketika muncul, tombol di bagian atas di header disembunyikan. Ini ditampilkan setelah kotak meninggalkan tampilan.
const buttonToHide = document.querySelector('button');const hideWhenBoxInView =newIntersectionObserver((entries)=>{if(entries[0].intersectionRatio <=0){// If not in view
buttonToHide.style.display ="inherit";}else{
buttonToHide.style.display ="none";}});
hideWhenBoxInView.observe(document.getElementById('box'));
<scriptsrc="https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script><header><button>NAVIGATION BUTTON TO HIDE</button></header><divclass="wrapper"><divid="box"></div></div>
Implementasi yang baik, dan menurut tautan dalam jawaban ini, ia harus bekerja di safari dengan menambahkan <!DOCTYPE html>ke HTML
Alon Eitan
Perhatikan bahwa IntersectionObserverini adalah fitur eksperimental (yang dapat berubah di masa mendatang).
Karthik Chintala
2
@KarthikChintala - ini didukung di setiap browser kecuali IE - dan ada juga polyfill yang tersedia.
Randy Casburn
Tidak menjawab pertanyaan OP karena hanya mendeteksi perubahan : IntersectionObserverhanya mengaktifkan callback setelah perpindahan target relatif ke root.
Brandon Hill
Ketika memanggil observeacara dipecat segera memberi tahu Anda saat ini persimpangan elemen dilacak. Jadi, dalam beberapa cara - itu alamat.
Mesqalito
8
Semua jawaban yang saya temui di sini hanya memeriksa apakah elemen diposisikan di dalam viewport saat ini . Tetapi itu tidak berarti bahwa itu terlihat .
Bagaimana jika elemen yang diberikan ada di dalam div dengan konten yang meluap, dan itu tidak terlihat?
Untuk mengatasinya, Anda harus memeriksa apakah elemen tersebut terkandung oleh semua orang tua.
Solusi saya melakukan hal itu:
Ini juga memungkinkan Anda menentukan berapa banyak elemen yang harus terlihat.
Element.prototype.isVisible =function(percentX, percentY){var tolerance =0.01;//needed because the rects returned by getBoundingClientRect provide the position up to 10 decimalsif(percentX ==null){
percentX =100;}if(percentY ==null){
percentY =100;}var elementRect =this.getBoundingClientRect();var parentRects =[];var element =this;while(element.parentElement !=null){
parentRects.push(element.parentElement.getBoundingClientRect());
element = element.parentElement;}var visibleInAllParents = parentRects.every(function(parentRect){var visiblePixelX =Math.min(elementRect.right, parentRect.right)-Math.max(elementRect.left, parentRect.left);var visiblePixelY =Math.min(elementRect.bottom, parentRect.bottom)-Math.max(elementRect.top, parentRect.top);var visiblePercentageX = visiblePixelX / elementRect.width *100;var visiblePercentageY = visiblePixelY / elementRect.height *100;return visiblePercentageX + tolerance > percentX && visiblePercentageY + tolerance > percentY;});return visibleInAllParents;};
Solusi ini mengabaikan fakta bahwa elemen mungkin tidak terlihat karena fakta lain, seperti opacity: 0.
Saya telah menguji solusi ini di Chrome dan Internet Explorer 11.
Saya menemukan bahwa jawaban yang diterima di sini terlalu rumit untuk kebanyakan kasus penggunaan. Kode ini melakukan pekerjaan dengan baik (menggunakan jQuery) dan membedakan antara elemen yang sepenuhnya terlihat dan sebagian terlihat:
var element = $("#element");var topOfElement = element.offset().top;var bottomOfElement = element.offset().top + element.outerHeight(true);var $window = $(window);
$window.bind('scroll',function(){var scrollTopPosition = $window.scrollTop()+$window.height();var windowScrollTop = $window.scrollTop()if(windowScrollTop > topOfElement && windowScrollTop < bottomOfElement){// Element is partially visible (above viewable area)
console.log("Element is partially visible (above viewable area)");}elseif(windowScrollTop > bottomOfElement && windowScrollTop > topOfElement){// Element is hidden (above viewable area)
console.log("Element is hidden (above viewable area)");}elseif(scrollTopPosition < topOfElement && scrollTopPosition < bottomOfElement){// Element is hidden (below viewable area)
console.log("Element is hidden (below viewable area)");}elseif(scrollTopPosition < bottomOfElement && scrollTopPosition > topOfElement){// Element is partially visible (below viewable area)
console.log("Element is partially visible (below viewable area)");}else{// Element is completely visible
console.log("Element is completely visible");}});
Bagaimana hal ini berlaku di browser seluler? Kebanyakan dari mereka buggy mengenai viewport, dengan header mereka naik atau turun pada scroll, dan perilaku yang berbeda ketika keyboard muncul, tergantung apakah itu android atau ios, dll.
Kev
@Kev Seharusnya berfungsi dengan baik tergantung pada saat Anda memanggil metode ini. Jika Anda memanggilnya lalu mengubah ukuran jendela, hasilnya mungkin tidak lagi benar. Anda dapat menyebutnya di setiap acara ukuran tergantung pada jenis fungsi yang Anda inginkan. Jangan ragu untuk mengajukan pertanyaan terpisah tentang kasus penggunaan khusus Anda dan ping saya di sini.
leonheess
3
Saya pikir ini adalah cara yang lebih fungsional untuk melakukannya.
Jawaban Dan tidak bekerja dalam konteks rekursif.
Fungsi ini memecahkan masalah ketika elemen Anda berada di dalam div yang lain dapat digulir dengan menguji setiap level secara rekursif hingga tag HTML, dan berhenti pada false pertama.
/**
* fullVisible=true only returns true if the all object rect is visible
*/function isReallyVisible(el, fullVisible){if( el.tagName =="HTML")returntrue;var parentRect=el.parentNode.getBoundingClientRect();var rect = arguments[2]|| el.getBoundingClientRect();return(( fullVisible ? rect.top >= parentRect.top : rect.bottom > parentRect.top )&&( fullVisible ? rect.left >= parentRect.left : rect.right > parentRect.left )&&( fullVisible ? rect.bottom <= parentRect.bottom : rect.top < parentRect.bottom )&&( fullVisible ? rect.right <= parentRect.right : rect.left < parentRect.right )&&
isReallyVisible(el.parentNode, fullVisible, rect));};
Jawaban yang paling diterima tidak berfungsi saat memperbesar Google Chrome di Android. Dalam kombinasi dengan jawaban Dan , untuk menjelaskan Chrome di Android, visualViewport harus digunakan. Contoh berikut hanya mengambil pemeriksaan vertikal ke akun dan menggunakan jQuery untuk ketinggian jendela:
var visibleY =function(el){var top = el.getBoundingClientRect().top, rect, el = el.parentNode;do{
rect = el.getBoundingClientRect();if(top <= rect.bottom ===false)returnfalse;
el = el.parentNode;}while(el != document.body);// Check it's within the document viewportreturn top <= document.documentElement.clientHeight;};
Saya hanya perlu memeriksa apakah itu terlihat di sumbu Y (untuk fitur Ajax scroll-more-records scrolling).
Cara saya menggunakannya adalah ketika elemen bergulir ke tampilan, saya menambahkan kelas yang memicu animasi keyframe CSS. Ini sangat mudah dan bekerja dengan sangat baik ketika Anda memiliki lebih dari 10 hal untuk dikondisikan secara kondisional pada sebuah halaman.
Anda harus melakukan cache di $window = $(window)luar scroll handler
Adam Rehal
2
Sebagian besar penggunaan dalam jawaban sebelumnya gagal pada titik-titik ini:
-Ketika setiap piksel elemen terlihat, tetapi bukan " sudut ",
-Ketika elemen lebih besar dari viewport dan terpusat ,
-Sebagian besar dari mereka hanya memeriksa elemen tunggal di dalam dokumen atau jendela .
Nah, untuk semua masalah ini saya punya solusi dan sisi positifnya adalah:
-Anda dapat kembali visibleketika hanya piksel dari sisi mana pun yang muncul dan bukan sudut,
-Anda masih dapat kembali visiblesementara elemen lebih besar dari viewport,
-Anda dapat memilih parent elementatau secara otomatis membiarkannya memilih,
-Bekerja pada elemen yang ditambahkan secara dinamis juga.
Jika Anda memeriksa cuplikan di bawah ini, Anda akan melihat perbedaan dalam menggunakan overflow-scrollwadah elemen tidak akan menimbulkan masalah dan melihat bahwa tidak seperti jawaban lain di sini bahkan jika piksel muncul dari sisi mana pun atau ketika suatu elemen lebih besar dari viewport dan kami melihat bagian dalamnya piksel elemen yang masih berfungsi.
Penggunaannya sederhana:
// For checking element visibility from any sides
isVisible(element)// For checking elements visibility in a parent you would like to checkvar parent = document;// Assuming you check if 'element' inside 'document'
isVisible(element, parent)// For checking elements visibility even if it's bigger than viewport
isVisible(element,null,true)// Without parent choice
isVisible(element, parent,true)// With parent choice
Demonstrasi tanpa crossSearchAlgorithmyang berguna untuk elemen yang lebih besar dari viewport check element3 piksel dalam untuk melihat:
function isVisible(element, parent, crossSearchAlgorithm){var rect = element.getBoundingClientRect(),
prect =(parent !=undefined)? parent.getBoundingClientRect(): element.parentNode.getBoundingClientRect(),
csa =(crossSearchAlgorithm !=undefined)? crossSearchAlgorithm :false,
efp =function(x, y){return document.elementFromPoint(x, y)};// Return false if it's not in the viewportif(rect.right < prect.left || rect.bottom < prect.top || rect.left > prect.right || rect.top > prect.bottom){returnfalse;}var flag =false;// Return true if left to right any border pixel reachedfor(var x = rect.left; x < rect.right; x++){if(element.contains(efp(rect.top, x))|| element.contains(efp(rect.bottom, x))){
flag =true;break;}}// Return true if top to bottom any border pixel reachedif(flag ==false){for(var y = rect.top; y < rect.bottom; y++){if(element.contains(efp(rect.left, y))|| element.contains(efp(rect.right, y))){
flag =true;break;}}}if(csa){// Another algorithm to check if element is centered and bigger than viewportif(flag ==false){var x = rect.left;var y = rect.top;// From top left to bottom rightwhile(x < rect.right || y < rect.bottom){if(element.contains(efp(x,y))){
flag =true;break;}if(x < rect.right){ x++;}if(y < rect.bottom){ y++;}}if(flag ==false){
x = rect.right;
y = rect.top;// From top right to bottom leftwhile(x > rect.left || y < rect.bottom){if(element.contains(efp(x,y))){
flag =true;break;}if(x > rect.left){ x--;}if(y < rect.bottom){ y++;}}}}}return flag;}// Check multiple elements visibility
document.getElementById('container').addEventListener("scroll",function(){var elementList = document.getElementsByClassName("element");var console = document.getElementById('console');for(var i=0; i < elementList.length; i++){// I did not define parent, so it will be element's parentif(isVisible(elementList[i])){
console.innerHTML ="Element with id["+ elementList[i].id +"] is visible!";break;}else{
console.innerHTML ="Element with id["+ elementList[i].id +"] is hidden!";}}});// Dynamically added elementsfor(var i=4; i <=6; i++){var newElement = document.createElement("div");
newElement.id ="element"+ i;
newElement.classList.add("element");
document.getElementById('container').appendChild(newElement);}
Anda lihat, ketika Anda berada di dalam elemen3 itu gagal untuk mengetahui apakah itu terlihat atau tidak, karena kami hanya memeriksa apakah elemen tersebut terlihat dari sisi atau sudut .
Dan ini termasuk crossSearchAlgorithmyang memungkinkan Anda untuk tetap kembali visibleketika elemen lebih besar dari viewport:
function isVisible(element, parent, crossSearchAlgorithm){var rect = element.getBoundingClientRect(),
prect =(parent !=undefined)? parent.getBoundingClientRect(): element.parentNode.getBoundingClientRect(),
csa =(crossSearchAlgorithm !=undefined)? crossSearchAlgorithm :false,
efp =function(x, y){return document.elementFromPoint(x, y)};// Return false if it's not in the viewportif(rect.right < prect.left || rect.bottom < prect.top || rect.left > prect.right || rect.top > prect.bottom){returnfalse;}var flag =false;// Return true if left to right any border pixel reachedfor(var x = rect.left; x < rect.right; x++){if(element.contains(efp(rect.top, x))|| element.contains(efp(rect.bottom, x))){
flag =true;break;}}// Return true if top to bottom any border pixel reachedif(flag ==false){for(var y = rect.top; y < rect.bottom; y++){if(element.contains(efp(rect.left, y))|| element.contains(efp(rect.right, y))){
flag =true;break;}}}if(csa){// Another algorithm to check if element is centered and bigger than viewportif(flag ==false){var x = rect.left;var y = rect.top;// From top left to bottom rightwhile(x < rect.right || y < rect.bottom){if(element.contains(efp(x,y))){
flag =true;break;}if(x < rect.right){ x++;}if(y < rect.bottom){ y++;}}if(flag ==false){
x = rect.right;
y = rect.top;// From top right to bottom leftwhile(x > rect.left || y < rect.bottom){if(element.contains(efp(x,y))){
flag =true;break;}if(x > rect.left){ x--;}if(y < rect.bottom){ y++;}}}}}return flag;}// Check multiple elements visibility
document.getElementById('container').addEventListener("scroll",function(){var elementList = document.getElementsByClassName("element");var console = document.getElementById('console');for(var i=0; i < elementList.length; i++){// I did not define parent so it will be element's parent// and it will do crossSearchAlgorithmif(isVisible(elementList[i],null,true)){
console.innerHTML ="Element with id["+ elementList[i].id +"] is visible!";break;}else{
console.innerHTML ="Element with id["+ elementList[i].id +"] is hidden!";}}});// Dynamically added elementsfor(var i=4; i <=6; i++){var newElement = document.createElement("div");
newElement.id ="element"+ i;
newElement.classList.add("element");
document.getElementById('container').appendChild(newElement);}
Kode ini dibuat untuk informasi yang lebih tepat jika ada bagian elemen yang ditampilkan dalam tampilan atau tidak. Untuk opsi kinerja atau hanya slide vertikal, jangan gunakan ini! Kode ini lebih efektif dalam menggambar kasus.
Anda harus mencoba dan menjelaskan mengapa versi Anda lebih baik. Seperti berdiri, itu terlihat kurang lebih sama dengan solusi lainnya.
Andy E
1
Solusi hebat ini memiliki BOX / ScrollContainer dan tidak menggunakan WINDOW (hanya jika tidak ditentukan). Lihatlah kode daripada menilai itu adalah solusi yang lebih universal (Sedang banyak mencari itu)
teter
1
Sesederhana mungkin, IMO:
function isVisible(elem){var coords = elem.getBoundingClientRect();returnMath.abs(coords.top)<= coords.height;}
Saya memiliki pertanyaan yang sama dan menemukan jawabannya dengan menggunakan getBoundingClientRect ().
Kode ini sepenuhnya 'generik' dan hanya perlu ditulis satu kali agar bisa berfungsi (Anda tidak harus menuliskannya untuk setiap elemen yang ingin Anda ketahui ada di viewport).
Kode ini hanya memeriksa untuk melihat apakah itu secara vertikal di viewport, bukan horizontal . Dalam hal ini, 'elemen' variabel (array) menampung semua elemen yang Anda periksa secara vertikal di viewport, jadi ambil elemen apa pun yang Anda inginkan di mana saja dan simpan di sana.
'For loop', loop melalui setiap elemen dan memeriksa untuk melihat apakah itu secara vertikal di viewport. Kode ini dijalankan setiap kali pengguna menggulir! Jika getBoudingClientRect (). Top kurang dari 3/4 viewport (elemennya adalah seperempat di viewport), ia terdaftar sebagai 'di viewport'.
Karena kodenya generik, Anda ingin tahu elemen 'mana' yang ada di viewport. Untuk mengetahuinya, Anda dapat menentukannya dengan atribut khusus, nama simpul, id, nama kelas, dan banyak lagi.
Ini kode saya (beri tahu saya jika tidak berfungsi; sudah diuji di Internet Explorer 11, Firefox 40.0.3, Versi Chrome 45.0.2454.85 m, Opera 31.0.1889.174, dan Edge dengan Windows 10, [belum Safari belum ]) ...
// Scrolling handlers...
window.onscroll =function(){var elements = document.getElementById('whatever').getElementsByClassName('whatever');for(var i =0; i != elements.length; i++){if(elements[i].getBoundingClientRect().top <= window.innerHeight*0.75&&
elements[i].getBoundingClientRect().top >0){
console.log(elements[i].nodeName +' '+
elements[i].className +' '+
elements[i].id +' is in the viewport; proceed with whatever code you want to do here.');}};
Semua jawaban di sini menentukan apakah elemen tersebut sepenuhnya terkandung dalam viewport, tidak hanya terlihat dalam beberapa cara. Misalnya, jika hanya setengah dari gambar terlihat di bagian bawah tampilan, solusi di sini akan gagal, mengingat "di luar".
Saya memiliki use case di mana saya melakukan pemuatan malas melalui IntersectionObserver, tetapi karena animasi yang terjadi selama pop-in, saya tidak ingin mengamati gambar yang sudah berpotongan pada pemuatan halaman. Untuk melakukan itu, saya menggunakan kode berikut:
Ini pada dasarnya memeriksa untuk melihat apakah bagian atas atau bawah terikat secara independen di viewport. Ujung yang berlawanan mungkin berada di luar, tetapi selama salah satu ujung berada, itu "terlihat" setidaknya sebagian.
Jawaban:
Pembaruan: Waktu berjalan terus dan begitu juga browser kami. Teknik ini tidak lagi direkomendasikan dan Anda harus menggunakan solusi Dan jika Anda tidak perlu mendukung versi Internet Explorer sebelum 7.
Solusi asli (sekarang kedaluwarsa):
Ini akan memeriksa apakah elemen tersebut sepenuhnya terlihat di viewport saat ini:
Anda dapat memodifikasi ini hanya untuk menentukan apakah ada bagian elemen yang terlihat di viewport:
sumber
getBoundingClientRect
secara spesifik tujuan menemukan koordinat elemen ... Mengapa kita tidak menggunakannya?Sekarang sebagian besar browser mendukung metode getBoundingClientRect , yang telah menjadi praktik terbaik. Menggunakan jawaban lama sangat lambat , tidak akurat dan memiliki beberapa bug .
Solusi yang dipilih sebagai benar hampir tidak pernah tepat . Anda dapat membaca lebih lanjut tentang bug-nya.
Solusi ini diuji pada Internet Explorer 7 (dan yang lebih baru), iOS 5 (dan yang lebih baru) Safari, Android 2.0 (Eclair) dan yang lebih baru, BlackBerry, Opera Mobile, dan Internet Explorer Mobile 9 .
Cara Penggunaan:
Anda dapat yakin bahwa fungsi yang diberikan di atas mengembalikan jawaban yang benar pada saat dipanggil, tetapi bagaimana dengan visibilitas elemen pelacakan sebagai suatu peristiwa?
Tempatkan kode berikut di bagian bawah
<body>
tag Anda :Jika Anda melakukan modifikasi DOM, mereka dapat mengubah visibilitas elemen Anda tentu saja.
Panduan dan perangkap umum:
Mungkin Anda perlu melacak halaman zoom / cubit perangkat seluler? jQuery harus menangani zoom / pinch cross browser, jika tidak, pertama atau kedua tautan akan membantu Anda.
Jika Anda memodifikasi DOM , ini dapat memengaruhi visibilitas elemen. Anda harus mengambil kendali atas itu dan menelepon
handler()
secara manual. Sayangnya, kami tidak memiliki browser lintasonrepaint
acara . Di sisi lain yang memungkinkan kami melakukan optimasi dan melakukan pengecekan ulang hanya pada modifikasi DOM yang dapat mengubah visibilitas elemen.Never Ever menggunakannya di dalam jQuery $ (document) .ready () saja, karena tidak ada jaminan CSS telah diterapkan pada saat ini. Kode Anda dapat bekerja secara lokal dengan CSS Anda pada hard drive, tetapi sekali memakai server jauh itu akan gagal.
Setelah
DOMContentLoaded
dipecat, gaya diterapkan , tetapi gambar belum dimuat . Jadi, kita harus menambahkanwindow.onload
pendengar acara.Kami belum dapat menangkap acara zoom / pinch.
Pilihan terakhir bisa berupa kode berikut:
Anda dapat menggunakan pageVisibiliy fitur hebat dari API HTML5 jika Anda peduli jika tab dengan halaman web Anda aktif dan terlihat.
TODO: metode ini tidak menangani dua situasi:
z-index
overflow-scroll
dalam wadah elemensumber
return (rect.bottom >= 0 && rect.right >= 0 && rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth));
isElementInViewport(document.getElementById('elem'))
) dan bukan objek jQuery (misalnya,isElementInViewport($("#elem))
). Setara jQuery adalah menambahkan[0]
seperti:isElementInViewport($("#elem)[0])
.el is not defined
Memperbarui
Di browser modern, Anda mungkin ingin memeriksa API Pengamat titik - temu yang memberikan manfaat berikut:
Intersection Observer sedang dalam perjalanan untuk menjadi standar penuh dan sudah didukung di Chrome 51+, Edge 15+ dan Firefox 55+ dan sedang dikembangkan untuk Safari. Tersedia juga polyfill .
Jawaban sebelumnya
Ada beberapa masalah dengan jawaban yang diberikan Dan yang mungkin membuatnya menjadi pendekatan yang tidak cocok untuk beberapa situasi. Beberapa masalah ini ditunjukkan dalam jawabannya di dekat bagian bawah, bahwa kodenya akan memberikan hasil positif palsu untuk elemen yang:
clip
properti CSSBatasan ini ditunjukkan dalam hasil tes sederhana berikut :
Solusinya:
isElementVisible()
Inilah solusi untuk masalah-masalah tersebut, dengan hasil tes di bawah ini dan penjelasan dari beberapa bagian kode
Dan hasilnya:
Catatan tambahan
Namun metode ini bukan tanpa batasannya sendiri. Misalnya, elemen yang diuji dengan indeks-z lebih rendah daripada elemen lain di lokasi yang sama akan diidentifikasi sebagai disembunyikan bahkan jika elemen di depan tidak benar-benar menyembunyikan bagiannya. Namun, metode ini memiliki kegunaan dalam beberapa kasus yang tidak dicakup solusi Dan.
Keduanya
element.getBoundingClientRect()
dandocument.elementFromPoint()
merupakan bagian dari spesifikasi Draft Kerja CSSOM dan didukung di setidaknya IE 6 dan yang lebih baru dan sebagian besar browser desktop untuk waktu yang lama (meskipun, tidak sempurna). Lihat Quirksmode pada fungsi-fungsi ini untuk informasi lebih lanjut.contains()
digunakan untuk melihat apakah elemen yang dikembalikan olehdocument.elementFromPoint()
adalah simpul anak dari elemen yang kami uji untuk visibilitas. Ini juga mengembalikan true jika elemen yang dikembalikan adalah elemen yang sama. Ini hanya membuat pemeriksaan lebih kuat. Ini didukung di semua browser utama, Firefox 9.0 menjadi yang terakhir yang menambahkannya. Untuk dukungan Firefox yang lebih lama, periksa riwayat jawaban ini.Jika Anda ingin menguji lebih banyak poin di sekitar elemen untuk visibilitas ― yaitu, untuk memastikan elemen tidak tercakup oleh lebih dari, katakanlah, 50% ― tidak perlu banyak untuk menyesuaikan bagian terakhir dari jawaban. Namun, perlu diketahui bahwa mungkin akan sangat lambat jika Anda memeriksa setiap piksel untuk memastikan itu 100% terlihat.
sumber
doc
sebagai alias untukdocument
. Ya, saya suka menganggap ini sebagai solusi yang layak untuk kasus tepi.element.contains(efp(rect.right - (rect.width / 2), rect.bottom - (rect.height / 2)))
Saya mencoba jawaban Dan . Namun , aljabar yang digunakan untuk menentukan batas berarti bahwa elemen tersebut harus berukuran ≤ ukuran viewport dan sepenuhnya berada di dalam viewport
true
, sehingga mudah mengarah ke negatif palsu. Jika Anda ingin menentukan apakah suatu elemen ada di viewport sama sekali, jawaban ryanve dekat, tetapi elemen yang diuji harus tumpang tindih dengan viewport, jadi coba ini:sumber
Sebagai layanan publik:
Jawaban Dan dengan perhitungan yang benar (elemen dapat> jendela, terutama pada layar ponsel), dan pengujian jQuery yang benar, serta menambahkan isElementPartiallyInViewport:
By the way, perbedaan antara window.innerWidth dan document.documentElement.clientWidth adalah bahwa clientWidth / clientHeight tidak termasuk scrollbar, sedangkan window.innerWidth / Height tidak.
Kasus cobaan
sumber
isElementPartiallyInViewport
sangat berguna juga. BagusLihat sumber ambang , yang menggunakan getBoundingClientRect . Itu seperti:
Itu kembali
true
jika ada bagian dari elemen di viewport.sumber
Versi saya yang lebih pendek dan lebih cepat:
Dan jsFiddle sesuai kebutuhan: https://jsfiddle.net/on1g619L/1/
sumber
Saya merasa bermasalah bahwa tidak ada versi jQuery- sentris dari fungsi yang tersedia. Ketika saya menemukan solusi Dan, saya memata-matai kesempatan untuk menyediakan sesuatu untuk orang-orang yang suka memprogram dalam gaya jQuery OO. Sangat bagus dan tajam dan bekerja seperti pesona bagi saya.
Bada bing bada booming
Pemakaian
sumber
API Pengamat Titik- Temu yang baru menjawab pertanyaan ini dengan sangat langsung.
Solusi ini akan memerlukan polyfill karena Safari, Opera dan Internet Explorer belum mendukung ini (polyfill termasuk dalam solusi).
Dalam solusi ini, ada kotak di luar pandangan yang menjadi target (diamati). Ketika muncul, tombol di bagian atas di header disembunyikan. Ini ditampilkan setelah kotak meninggalkan tampilan.
sumber
<!DOCTYPE html>
ke HTMLIntersectionObserver
ini adalah fitur eksperimental (yang dapat berubah di masa mendatang).IntersectionObserver
hanya mengaktifkan callback setelah perpindahan target relatif ke root.observe
acara dipecat segera memberi tahu Anda saat ini persimpangan elemen dilacak. Jadi, dalam beberapa cara - itu alamat.Semua jawaban yang saya temui di sini hanya memeriksa apakah elemen diposisikan di dalam viewport saat ini . Tetapi itu tidak berarti bahwa itu terlihat .
Bagaimana jika elemen yang diberikan ada di dalam div dengan konten yang meluap, dan itu tidak terlihat?
Untuk mengatasinya, Anda harus memeriksa apakah elemen tersebut terkandung oleh semua orang tua.
Solusi saya melakukan hal itu:
Ini juga memungkinkan Anda menentukan berapa banyak elemen yang harus terlihat.
Solusi ini mengabaikan fakta bahwa elemen mungkin tidak terlihat karena fakta lain, seperti
opacity: 0
.Saya telah menguji solusi ini di Chrome dan Internet Explorer 11.
sumber
Saya menemukan bahwa jawaban yang diterima di sini terlalu rumit untuk kebanyakan kasus penggunaan. Kode ini melakukan pekerjaan dengan baik (menggunakan jQuery) dan membedakan antara elemen yang sepenuhnya terlihat dan sebagian terlihat:
sumber
$window = $(window)
luar scroll handler.Solusi paling sederhana sebagai dukungan Element.getBoundingClientRect () telah menjadi sempurna :
sumber
Saya pikir ini adalah cara yang lebih fungsional untuk melakukannya. Jawaban Dan tidak bekerja dalam konteks rekursif.
Fungsi ini memecahkan masalah ketika elemen Anda berada di dalam div yang lain dapat digulir dengan menguji setiap level secara rekursif hingga tag HTML, dan berhenti pada false pertama.
sumber
Jawaban yang paling diterima tidak berfungsi saat memperbesar Google Chrome di Android. Dalam kombinasi dengan jawaban Dan , untuk menjelaskan Chrome di Android, visualViewport harus digunakan. Contoh berikut hanya mengambil pemeriksaan vertikal ke akun dan menggunakan jQuery untuk ketinggian jendela:
sumber
Inilah solusi saya. Ini akan berfungsi jika suatu elemen disembunyikan di dalam wadah yang dapat digulir.
Ini demo (coba ubah ukuran jendela menjadi)
Saya hanya perlu memeriksa apakah itu terlihat di sumbu Y (untuk fitur Ajax scroll-more-records scrolling).
sumber
Berdasarkan solusi Dan , saya harus membersihkan implementasi sehingga menggunakannya berkali-kali pada halaman yang sama lebih mudah:
Cara saya menggunakannya adalah ketika elemen bergulir ke tampilan, saya menambahkan kelas yang memicu animasi keyframe CSS. Ini sangat mudah dan bekerja dengan sangat baik ketika Anda memiliki lebih dari 10 hal untuk dikondisikan secara kondisional pada sebuah halaman.
sumber
$window = $(window)
luar scroll handlerSebagian besar penggunaan dalam jawaban sebelumnya gagal pada titik-titik ini:
Nah, untuk semua masalah ini saya punya solusi dan sisi positifnya adalah:
Jika Anda memeriksa cuplikan di bawah ini, Anda akan melihat perbedaan dalam menggunakan
overflow-scroll
wadah elemen tidak akan menimbulkan masalah dan melihat bahwa tidak seperti jawaban lain di sini bahkan jika piksel muncul dari sisi mana pun atau ketika suatu elemen lebih besar dari viewport dan kami melihat bagian dalamnya piksel elemen yang masih berfungsi.Penggunaannya sederhana:
Demonstrasi tanpa
crossSearchAlgorithm
yang berguna untuk elemen yang lebih besar dari viewport check element3 piksel dalam untuk melihat:Tampilkan cuplikan kode
Anda lihat, ketika Anda berada di dalam elemen3 itu gagal untuk mengetahui apakah itu terlihat atau tidak, karena kami hanya memeriksa apakah elemen tersebut terlihat dari sisi atau sudut .
Dan ini termasuk
crossSearchAlgorithm
yang memungkinkan Anda untuk tetap kembalivisible
ketika elemen lebih besar dari viewport:Tampilkan cuplikan kode
JSFiddle untuk dimainkan: http://jsfiddle.net/BerkerYuceer/grk5az2c/
Kode ini dibuat untuk informasi yang lebih tepat jika ada bagian elemen yang ditampilkan dalam tampilan atau tidak. Untuk opsi kinerja atau hanya slide vertikal, jangan gunakan ini! Kode ini lebih efektif dalam menggambar kasus.
sumber
Solusi yang lebih baik:
sumber
Sesederhana mungkin, IMO:
sumber
Berikut adalah fungsi yang memberi tahu jika suatu elemen terlihat di viewport saat ini dari elemen induk :
sumber
Ini memeriksa apakah suatu elemen setidaknya sebagian terlihat (dimensi vertikal):
sumber
Saya memiliki pertanyaan yang sama dan menemukan jawabannya dengan menggunakan getBoundingClientRect ().
Kode ini sepenuhnya 'generik' dan hanya perlu ditulis satu kali agar bisa berfungsi (Anda tidak harus menuliskannya untuk setiap elemen yang ingin Anda ketahui ada di viewport).
Kode ini hanya memeriksa untuk melihat apakah itu secara vertikal di viewport, bukan horizontal . Dalam hal ini, 'elemen' variabel (array) menampung semua elemen yang Anda periksa secara vertikal di viewport, jadi ambil elemen apa pun yang Anda inginkan di mana saja dan simpan di sana.
'For loop', loop melalui setiap elemen dan memeriksa untuk melihat apakah itu secara vertikal di viewport. Kode ini dijalankan setiap kali pengguna menggulir! Jika getBoudingClientRect (). Top kurang dari 3/4 viewport (elemennya adalah seperempat di viewport), ia terdaftar sebagai 'di viewport'.
Karena kodenya generik, Anda ingin tahu elemen 'mana' yang ada di viewport. Untuk mengetahuinya, Anda dapat menentukannya dengan atribut khusus, nama simpul, id, nama kelas, dan banyak lagi.
Ini kode saya (beri tahu saya jika tidak berfungsi; sudah diuji di Internet Explorer 11, Firefox 40.0.3, Versi Chrome 45.0.2454.85 m, Opera 31.0.1889.174, dan Edge dengan Windows 10, [belum Safari belum ]) ...
sumber
Ini adalah solusi mudah dan kecil yang berhasil bagi saya.
Contoh : Anda ingin melihat apakah elemen terlihat di elemen induk yang memiliki gulir melimpah.
sumber
Semua jawaban di sini menentukan apakah elemen tersebut sepenuhnya terkandung dalam viewport, tidak hanya terlihat dalam beberapa cara. Misalnya, jika hanya setengah dari gambar terlihat di bagian bawah tampilan, solusi di sini akan gagal, mengingat "di luar".
Saya memiliki use case di mana saya melakukan pemuatan malas melalui
IntersectionObserver
, tetapi karena animasi yang terjadi selama pop-in, saya tidak ingin mengamati gambar yang sudah berpotongan pada pemuatan halaman. Untuk melakukan itu, saya menggunakan kode berikut:Ini pada dasarnya memeriksa untuk melihat apakah bagian atas atau bawah terikat secara independen di viewport. Ujung yang berlawanan mungkin berada di luar, tetapi selama salah satu ujung berada, itu "terlihat" setidaknya sebagian.
sumber
Saya menggunakan fungsi ini (ini hanya memeriksa apakah y adalah inscreen karena sebagian besar waktu x tidak diperlukan)
sumber
Untuk tantangan serupa, saya sangat menikmati inti ini yang memperlihatkan polyfill untuk scrollIntoViewIfNeeded () .
Semua Kung Fu yang diperlukan untuk menjawab ada di dalam blok ini:
this
mengacu pada elemen yang Anda ingin tahu apakah itu, misalnya,overTop
atauoverBottom
- Anda hanya perlu mengetahui ...sumber