Saya memiliki JavaScript yang melakukan aktivitas secara berkala. Ketika pengguna tidak melihat situs (yaitu, jendela atau tab tidak memiliki fokus), alangkah baiknya untuk tidak berjalan.
Apakah ada cara untuk melakukan ini menggunakan JavaScript?
Titik referensi saya: Obrolan Gmail memutar suara jika jendela yang Anda gunakan tidak aktif.
javascript
browser
focus
window
Luke Francl
sumber
sumber
requestAnimationFrame
API, atau gunakan fitur modern yang frekuensisetTimeout
/setInterval
berkurang ketika jendela tidak terlihat (1 detik di Chrome, misalnya).blur
/focus
di browser yang tidak mendukungnya.blur
/focus
acara ... yang akan digunakan terbatas, karena jendela bisa tidak aktif tetapi terlihat sepenuhnya atau sebagian (ada juga ikon "pratinjau" di beberapa bilah tugas yang orang harapkan terus berlanjut diperbarui).Jawaban:
Sejak awalnya menulis jawaban ini, spesifikasi baru telah mencapai status rekomendasi berkat W3C. The Halaman Visibilitas API (di MDN ) sekarang memungkinkan kita untuk lebih akurat mendeteksi ketika halaman tersembunyi kepada pengguna.
Dukungan browser saat ini:
Kode berikut jatuh kembali ke metode blur / fokus yang kurang dapat diandalkan di browser yang tidak kompatibel:
onfocusin
danonfocusout
yang diperlukan untuk IE 9 dan menurunkan , sementara semua yang lain memanfaatkanonfocus
danonblur
, kecuali untuk iOS, yang menggunakanonpageshow
danonpagehide
.sumber
focusin
danfocusout
dari iframe ke jendela atas. Untuk browser yang lebih baru, Anda hanya perlu menanganifocus
danblur
acara pada setiap objek iframewindow
. Anda harus menggunakan kode yang diperbarui yang baru saja saya tambahkan yang setidaknya akan mencakup kasus-kasus di browser yang lebih baru.Saya akan menggunakan jQuery karena semua yang harus Anda lakukan adalah ini:
Atau setidaknya itu berhasil untuk saya.
sumber
window
fokus akan longgar, yang benar, tetapi tergantung pada apa niat Anda mungkin bukan yang Anda butuhkan.Ada 3 metode khas yang digunakan untuk menentukan apakah pengguna dapat melihat halaman HTML, namun tidak ada yang bekerja dengan sempurna:
The W3C Halaman Visibilitas API seharusnya melakukan hal ini (didukung sejak: Firefox 10, MSIE 10, Chrome 13). Namun, API ini hanya memunculkan peristiwa-peristiwa ketika tab browser sepenuhnya ditimpa (misalnya ketika pengguna berubah dari satu tab ke yang lain). API tidak memunculkan peristiwa ketika visibilitas tidak dapat ditentukan dengan akurasi 100% (misalnya Alt + Tab untuk beralih ke aplikasi lain).
Menggunakan metode fokus / blur memberi Anda banyak kesalahan positif. Misalnya, jika pengguna menampilkan jendela yang lebih kecil di atas jendela browser, jendela browser akan kehilangan fokus (
onblur
dinaikkan) tetapi pengguna masih dapat melihatnya (jadi masih perlu di-refresh). Lihat juga http://javascript.info/tutorial/focusUntuk meningkatkan perilaku tidak sempurna yang dijelaskan di atas, saya menggunakan kombinasi dari 3 metode: W3C Visibility API, lalu fokus / blur dan metode aktivitas pengguna untuk mengurangi tingkat positif palsu. Ini memungkinkan untuk mengelola acara berikut:
Beginilah cara kerjanya: ketika dokumen kehilangan fokus, aktivitas pengguna (seperti gerakan mouse) pada dokumen dimonitor untuk menentukan apakah jendela terlihat atau tidak. Probabilitas visibilitas halaman berbanding terbalik dengan waktu aktivitas pengguna terakhir pada halaman: jika pengguna tidak membuat aktivitas pada dokumen untuk waktu yang lama, halaman kemungkinan besar tidak terlihat. Kode di bawah ini meniru API Visibilitas Halaman W3C: berperilaku dengan cara yang sama tetapi memiliki tingkat positif palsu yang kecil. Ini memiliki keuntungan menjadi multibrowser (diuji pada Firefox 5, Firefox 10, MSIE 9, MSIE 7, Safari 5, Chrome 9).
Karena saat ini tidak ada solusi lintas-browser yang berfungsi tanpa false positive, Anda sebaiknya berpikir dua kali untuk menonaktifkan aktivitas berkala di situs web Anda.
sumber
Ada perpustakaan yang rapi tersedia di GitHub:
https://github.com/serkanyersen/ifvisible.js
Contoh:
Saya telah menguji versi 1.0.1 di semua browser yang saya miliki dan dapat mengonfirmasi bahwa itu berfungsi dengan:
... dan mungkin semua versi yang lebih baru.
Tidak sepenuhnya bekerja dengan:
.now()
selalu kembalitrue
untuk saya)sumber
Menggunakan: Halaman Visibilitas API
Bisakah saya menggunakan? http://caniuse.com/#feat=pagevisibility
sumber
Saya membuat Obrolan Komet untuk aplikasi saya, dan ketika saya menerima pesan dari pengguna lain saya menggunakan:
sumber
document.hasFocus()
adalah cara paling bersih untuk melakukannya. Semua cara lain menggunakan api visibilitas atau peristiwa berbasis atau mencari berbagai tingkat aktivitas pengguna / kurangnya aktivitas menjadi terlalu rumit dan penuh dengan kasus tepi dan lubang. letakkan di interval sederhana dan angkat acara khusus saat hasilnya berubah. Contoh: jsfiddle.net/59utucz6/1Saya mulai menggunakan jawaban wiki komunitas, tetapi menyadari bahwa itu tidak mendeteksi acara alt-tab di Chrome. Ini karena ia menggunakan sumber acara pertama yang tersedia, dan dalam hal ini adalah API visibilitas halaman, yang di Chrome tampaknya tidak melacak tab-alt.
Saya memutuskan untuk memodifikasi skrip sedikit untuk melacak semua peristiwa yang mungkin terjadi untuk perubahan fokus halaman. Inilah fungsi yang bisa Anda singgahi:
Gunakan seperti ini:
Versi ini mendengarkan semua peristiwa visibilitas yang berbeda dan mengaktifkan panggilan balik jika ada dari mereka yang menyebabkan perubahan. The
focused
danunfocused
penangan memastikan bahwa callback tidak disebut beberapa kali jika beberapa API menangkap perubahan visibilitas yang sama.sumber
document.hidden
dandocument.webkitHidden
. Tanpaelse
dalamif
konstruksi kita akan mendapatkan 2 panggilan balik kan?Ini sangat sulit. Tampaknya tidak ada solusi mengingat persyaratan berikut.
Ini terjadi karena:
Dengan adanya batasan ini, dimungkinkan untuk mengimplementasikan solusi yang menggabungkan - Halaman Visibilitas API - window blur / focus - document.activeElement
Itu mampu:
Ketika iframe memiliki fokus, acara blur / fokus Anda tidak dipanggil sama sekali, dan laman Visibilitas API tidak akan memicu pada alt + tab.
Saya membangun di atas solusi @ AndyE dan menerapkan solusi (hampir baik) ini di sini: https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test1.html (maaf, saya punya masalah dengan JSFiddle).
Ini juga tersedia di Github: https://github.com/qmagico/estante-components
Ini bekerja pada chrome / chromium. Jenisnya berfungsi pada firefox, kecuali ia tidak memuat konten iframe (ada ide mengapa?)
Bagaimanapun, untuk menyelesaikan masalah terakhir (4), satu-satunya cara yang dapat Anda lakukan adalah mendengarkan acara blur / fokus pada iframe. Jika Anda memiliki kontrol atas iframe, Anda dapat menggunakan API postMessage untuk melakukannya.
https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test2.html
Saya masih belum menguji ini dengan cukup banyak browser. Jika Anda dapat menemukan lebih banyak info tentang tempat ini tidak berfungsi, beri tahu saya di komentar di bawah.
sumber
http://jsfiddle.net/ARTsinn/JTxQY/
sumber
ini bekerja untuk saya di chrome 67, firefox 67,
sumber
kamu bisa menggunakan:
sumber
Di HTML 5 Anda juga bisa menggunakan:
onpageshow
: Script untuk dijalankan ketika jendela menjadi terlihatonpagehide
: Script untuk dijalankan ketika jendela disembunyikanLihat:
sumber
Ini adalah adaptasi dari jawaban dari Andy E.
Ini akan melakukan tugas, mis. Menyegarkan halaman setiap 30 detik, tetapi hanya jika halaman tersebut terlihat dan fokus.
Jika visibilitas tidak dapat dideteksi, maka hanya fokus yang akan digunakan.
Jika pengguna memfokuskan halaman, maka itu akan segera diperbarui
Halaman tidak akan diperbarui lagi hingga 30 detik setelah panggilan ajax
sumber
Untuk solusi tanpa jQuery, periksa Visibility.js yang menyediakan informasi tentang tiga status halaman
dan juga pembungkus kenyamanan untuk setInterval
Fallback untuk browser lama (IE <10; iOS <7) juga tersedia
sumber
Cara yang sedikit lebih rumit akan digunakan
setInterval()
untuk memeriksa posisi mouse dan membandingkannya dengan pemeriksaan terakhir. Jika mouse belum bergerak dalam waktu yang ditentukan, pengguna mungkin menganggur.Ini memiliki keuntungan tambahan dengan memberi tahu jika pengguna menganggur, alih-alih hanya memeriksa jika jendela tidak aktif.Seperti yang telah ditunjukkan oleh banyak orang, ini tidak selalu merupakan cara yang baik untuk memeriksa apakah pengguna atau jendela peramban menganggur, karena pengguna bahkan mungkin tidak menggunakan mouse atau menonton video, atau serupa. Saya hanya menyarankan satu cara yang mungkin untuk memeriksa idle-ness.
sumber
Untuk angular.js, berikut adalah arahan (berdasarkan jawaban yang diterima) yang akan memungkinkan controller Anda bereaksi terhadap perubahan visibilitas:
Anda dapat menggunakannya seperti contoh ini:, di
<div react-on-window-focus="refresh()">
manarefresh()
fungsi lingkup dalam lingkup apa pun Pengontrol berada dalam ruang lingkup.sumber
Inilah solusi yang solid dan modern. (Pendek manis 👌🏽)
Ini akan mengatur pendengar untuk memicu ketika peristiwa visibilitas dipecat yang bisa menjadi fokus atau kabur.
sumber
Jika Anda ingin bertindak pada seluruh peramban blur : Seperti yang saya komentari, jika peramban kehilangan fokus, tidak ada acara yang disarankan yang diaktifkan. Ide saya adalah untuk menghitung dalam satu lingkaran dan mengatur ulang penghitung jika suatu peristiwa terjadi. Jika penghitung mencapai batas saya melakukan location.href ke halaman lain. Ini juga menyala jika Anda bekerja pada dev-tools.
Ini adalah konsep yang berhasil diuji pada FF.
sumber