Jendela popup adalah salah satu metode tertua untuk menampilkan tambahan dokumen kepada pengguna. Secara umum, kamu hanya menjalankan:
window.open('https://javascript.info/')
…Dan akan terbuka jendela baru yang telah diberi URL, Kebanyakan peramban moderen akan membuka jendela baru bukannya jendela terpisah.
Popup ada sejak jaman dahulu. Ide awalnya adalah untuk menampilkan konten lain tanpa menutup jendela utama. Saat ini, ada cara lain untuk melakukan hal tersebut: Kita bisa membuka konten secara dinamis dengan fetch dan menampilkannya di dalam sebuah <div>
yang dihasilkan secara dinamis. Jadi popups adalah sesuatu yang tidak kita gunakan setiap hari.
Kemudian, popups itu rumit di perangkat seluler, karena tidak menampilkan beberapa jendela secara serempak.
Namun, ada tugas dimana popups masih digunakan, misalnya untuk otorisasi OAuth (masuk dengan Google/Facebook/…), karena:
- Popup adalah sebuah jendela terpisah dengan ekosistem Javascript independennya sendiri. Sehingga aman membuka popup dari situs pihak ketiga yang tidak terpercaya.
- Sangat mudah untuk membuka popup.
- Sebuah popup dapat menavigasi (merubah URL) dan mengirimkan pesan ke pembuka jendela.
Pemblokiran Popup
Di masa lalu, situs jahat sering sekali menyalahgunakan popups. Sebuah halaman jahat dapat membuka banyak sekali jendela popup dengan iklan. Sehingga saat ini kebanyakan peramban mencoba untuk memblokir dan melindungi pengguna.
Kebanyakan peramban akan memblokir popups jika dipangil dari luar aktifitas yang dipicu oleh pengguna seperti onclick
.
Sebgai contoh:
// popup diblokir
window.open('https://javascript.info');
// popup diperbolehkan
button.onclick = () => {
window.open('https://javascript.info');
};
Dengan cara ini pengguna agak terlindungi dari popups yang tidak diinginkan dan fungsionalitasnya tidak dinonaktifkan secara total.
Bagaimana jika popups dibuka dari onclick
, tetapi setelah setTimeout
? Hal ini sedikit rumit.
Coba kode berikut:
// terbuka setelah 3 detik
setTimeout(() => window.open('http://google.com'), 3000);
Popup terbuka di Chrome, namun diblokir di Firefox.
…Jika kita mengurangi penundaan, popup akan bekerja di Firefox juga:
// open after 1 seconds
setTimeout(() => window.open('http://google.com'), 1000);
Perbedaannya adalah Firefox memperlakukan sebuah timeout antara 2000ms atau kurang dari itu untuk dapat diterima, namun lebih dari itu – hilangkan “kepercayaan”, Firefox berasumsi bahwa saat ini “diluar kendali pengguna”. Sehingga yang pertama akan diblokir, dan yang kedua tidak.
window.open
Sintak untuk membuka popup adalah: window.open(url, name, params)
:
url
: URL yang akan dimuat di dalam jendela baru.
- nama
- nama dari jendela baru. Setiap jendela memiliki sebuah
window.name
, dan dengan ini kita bisa secara spesifik menentukan jendela mana yang digunakan untuk popup. Jika telah ada jendela menggunakan nama tersebut – URL akan menjadi gantinya, jika tidak jendela baru terbuka. - parameter
- Konfigurasi untuk jendela baru. Mengandung pengaturan, yang dipisahkan dengan koma. Tidak boleh ada spasi di dalam parameter, sebagai contoh:
width=200,height=100
.
Pengaturan untuk params
:
- Posisi:
left/top
(numeric) – mengatur sudut jendela atas-kanan di layar. Namun ada batasan: sebuah jendela baru tidak bisa diposisikan tersembunyi.width/height
(numeric) – Lebar dan tinggi dari jendela baru. Namun ada batasan pada Lebar/tinggi minimal, sehingga tidak mungkin untuk membuat jendela tidak terlihat.
- Fitur jendela:
menubar
(yes/no) – menampilkan atau menyembunyikan menu peramban pada jendela baru.toolbar
(yes/no) – menampilkan atau menyembunyikan navigasi bar peramban (kembali, kedepan, isi ulang dan sebagainya) pada jendela baru.location
(yes/no) – menampilkan atau menyembunyikan URL pada jendela baru. FF dan IE tidak mengizinkan untuk meyembunyikan URL secara defaultstatus
(yes/no) – menampilkan atau menyembunyikan bar status. Sekali lagi kebanyakan peramban memaksa untuk menampilkannya.resizable
(yes/no) – mengizinkan atau menolak untuk merubah ukuran jendela baru. Tidak direkomendasikan.scrollbars
(yes/no) – mengizinkan atau menolak scrollbars. untuk jendela baru. Tidak direkomendasikan.
Ada juga sedikit dukungan untuk fitur spesifik peramban, Dimana biasanya tidak digunakan. Periksa window.open in MDN Sebagai contoh.
Contoh: sebuah jendela sederhana
Mari buka jendela dengan pengaturan fitur paling sedikit untuk melihat fitur mana yang akan diizinkan atau tidak oleh peramban:
let params = `scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no,
width=0,height=0,left=-1000,top=-1000`;
open('/', 'test', params);
Dalam contoh kebanyakan “fitur jendela” telah dinonaktifkan dan jendela berada di luar layar. Jalankan dan lihat apa yang terjadi. Kebanyakan peramban akan “Memperbaiki” hal-hal yang ganjil seperti width/height
yang kosong dan left/top
yang keluar jendela. Sebagai contoh, Chrome membuka semacam jendela dengan lebar/tinggi penuh. sehingga akan menempati layar penuh.
Mari tambahkan opsi penempatan normal dan masuk akal untuk koordinat width
, height
, left
, top
:
let params = `scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no,
width=600,height=300,left=100,top=100`;
open('/', 'test', params);
Kebanyakan peramban menampilkan contoh diatas sesuai dengan yang diinginkan.
Aturan untuk penggaturan yang dihilangkan:
- Jika tidak ada argumen ketiga di dalam pemanggilan
open
, atau kosong, maka parameter default jendela yang akan digunakan. - Jika ada serangkaian parameter, namun sebagian fitur
yes/no
diabaikan, maka fitur yang diabaikan akan diasumsikan untuk memiliki nilaino
. Sehingga jika anda menetapkan parameter, pastikan secara eksplisit anda telah menyetel semua fitur yang dibutuhkan ke yes. - Jika tidak ada
left/top
di dalam parameter, maka peramban akan mencoba untuk membuka sebuah jendela baru didekat jendela yang terakhir terbuka. - Jika tidak ada
width/height
, maka jendela baru akan memiliki ukuran yang sama seperti jendela yang terakhir terbuka.
Mengakses popup dari jendela
Pemanggilan Open
mengembalikan referensi ke jendela baru. referensi itu bisa digunakan untuk memanipulasi properti, merubah lokasi dan melakukan hal lain yang lebih dari itu.
Pada contoh ini, kita menghasilkan popup konten dari Javascript:
let newWin = window.open("about:blank", "hello", "width=200,height=200");
newWin.document.write("Hello, world!");
Dan disini kita memodifikasi konten setelah dimuat:
let newWindow = open('/', 'example', 'width=300,height=300')
newWindow.focus();
alert(newWindow.location.href); // (*) about:blank, loading belum dimulai
newWindow.onload = function() {
let html = `<div style="font-size:30px">Welcome!</div>`;
newWindow.document.body.insertAdjacentHTML('afterbegin', html);
};
Penting untuk dicatat: Segera setelah window.open
, saat itu jendela baru belum dimuat. Hal itu didemonstrasikan oleh alert
di baris (*)
, Sehingga kita menunggu untuk onload
untuk memodifikasinya. Kita juga bisa menggunakan handler DOMContentLoaded
untuk newWin.document
.
Jendela dapat dengan leluasa mengakses konten satu sama lain hanya jika mereka datang dari asal yang sama (protocol://domain:port yang sama)
Jika tidak, semisal jendela utama datang dari site.com
, dan popup datang dari gmail.com
, hal ini mustahil dilakukan demi alasan keamanan penguna. Untuk lebih detail lihat bagian Cross-window communication.
Mengakses jendela dari popup
Popup mungkin mengakses “pembuka” jendela menggunakan referensei window.openner
. Ini akan menjadi null
dari semua jendela kecuali popup.
Jika code dibawah dijalankan, maka konten pembuka jendela saat ini akan dibuah menjadi “Test”:
let newWin = window.open("about:blank", "hello", "width=200,height=200");
newWin.document.write(
"<script>window.opener.document.body.innerHTML = 'Test'<\/script>"
);
Sehingga terjadi koneksi dua arah antara jendela: jendela utama dan popup memiliki sebuah referensi satu sama lain.
Menutup sebuah popup
Untuk menutup sebuah jendela: win.close()
.
Untuk memeriksa apakah jendela sudah tertutup: win.closed
.
Secara teknis, metode close()
tersedia pada setiap window
, namun window.close()
diabaikan oleh kebanyakan beramban jika window
tidak dibuat dengan window.open
. Jadi hanya akan bekerja untuk popup.
properti closed
bernilai true
jika jendela ditutup. Hal ini berguna untuk memeriksa apakah popup (atau jendela utama) masih terbuka atau tidak. seorang pengguna bisa menutupnya kapan saja, dan kode kita mengambil pertimbangan untuk diperhitungkan.
Code dibawah ini dimuat dan kemudian menutup jendela:
let newWindow = open('/', 'example', 'width=300,height=300');
newWindow.onload = function() {
newWindow.close();
alert(newWindow.closed); // benar
};
berpindah dan merubah ukuran.
Ada metode untuk memindahkan/merubah ukuran sebuah jendela:
win.moveBy(x,y)
- Memindahkan jendela ke posisi
x
piksel ke kanan dany
piksel kebawah. Nilai negatif dapat diterima (untuk memindahkan kiri/atas). win.moveTo(x,y)
- Memindahkan jendela ke koordinat
(x,y)
di layar. win.resizeBy(width,height)
- Merubah ukuran jendela dengan memberikan
width/height
ke ukuran sat ini. Nilai negatif dapat diterima. win.resizeTo(width,height)
- Merubah ukuran jendela ke ukuran yang diberikan.
Ada juga window.onresize
event.
Untuk mencegah penyalahgunaan, peramban biasanya memblokir metode ini. Mereka hanya bekerja baik pada popup yang kami buka, yang tidak memiliki tab tambahan.
Javascript tidak memiliki cara untuk mengecilkan atau memaksimalkan sebuah jendela. fungsi OS-level ini tersembunyi dari pengembang frontend metode Move/resize tidak dapat berjalan pada jendela maximized/minimized.
Gulir jendela
Kami telah membicarakan tentang mengulir jendela di bagian Window sizes and scrolling.
win.scrollBy(x,y)
: Gulir jendela x
piksel ke kanan dan y
kebawah terhadap posisi gulir saat ini. Nilai negatif dapat diterima.
win.scrollTo(x,y)
: Scroll the window to the given coordinates (x,y)
.
elem.scrollIntoView(top = true)
- Mengulir jendela untuk membuat
elem
terlihat diatas atau di bawah darielem.scrollIntoView(false)
, Kemudian ada juga eventwindow.onscroll
.
Fokus/kabur di jendela
Secara teori, ada metode window.focus()
dan window.blur()
untuk memfokuskan/tidak fokus sebuah jendela. Dan ada juga even focus/blur
yang mengizinkan untuk menangkap momen saat pegunjung fokus pada jendela dan berpindah ke tempat lain.
Meskipun, dalam praktiknya hal ini dibatasi, karena pada masa lalu halaman jahat menyalahgunakannya.
Sebagai contoh, lihat code ini:
window.onblur = () => window.focus();
Mesikipun pengguna mencoba untuk berpindah dari jendela (window.onblur
), hal ini membawa jendela kembali fokus. Tujuanya adalah untuk “mengunci” pengguna selama berada di dalam window
.
Sehingga peramban harus memperkenalkan banyak batasan kode seperti ini dan melindungi pengguna dari iklan dan halaman jahat. Mereka bergantung ke peramban.
Sebagai contoh, sebuah peramban mobile pada umumnya mengabaikan window.focus()
. Dan fokus tidak bekerja saat sebuah popup terbuka di dalam tab yang terpisah daripada membuka sebuah jendela baru.
Masih ada beberapa kasus pengunaan menggunakan pangilan sejenis untuk menjalankan dan berguna.
Sebagai contoh:
- Saat kita membuka popup, mungkin ide yang bagus untuk menjalankan
newWindow.focus()
. untuk beberapa kombinasi OS/peramban memastikan bahwa pengguna saat ini berada di dalam jendela baru - Jika kita ingin melacak kapan pengunjung mengunakan web-app, kita dapat melacak
window.onfocus/onblur
. Hal ini mengijinkan kita untuk menangguhkan / melanjutkan di dalam aktifitas animasi dan semacamnya. Tetapi tolong dicatat bahwa eventblur
berarti pengunjung berpindah dari jendela, teteapi mereka mungkin masih mengamatinya. Jendela berada di latar belakang, namun mungkin masih dapat dilihat.
kesimpulan
Jendela popup jarang digunakan, karena ada beberapa alternatif: memuat dan menampilkan informasi in-page, atau di dalam iframe.
Jika kita akan membuka popup, cara yang benar adalah dengan memberitahu pengguna tentang hal ini. Sebuah ikon “jendela terbuka” dekat tautan atau tombol yang mengizinkan pengunjung untuk tetap fokus dan ingat kedua jendela.
- Popup dapat dibuka dengan pemanggilan
open(url, name, params)
. hal ini akan mengembalikan referensi untuk jendela yang lebih baru. - Peramban memblokir pemanggilan
open
dari kode yang berasal dari luar aksi pengguna. Biasanya notifikasi muncul, sehingga pengguna mungkin mengizinkannya. - Secara umum peramban membuka tab baru, tetapi jika ukuran disediakan, maka akan terbuka jendela popup.
- Popup mungkin mengakses pembuka jendela menggunakan properti
window.opener
. - Jendela utama dan popup dapat secara bebas membaca dan memodifikasi satu sama lain jika mereka memiliki asal yang sama. Jika tidak mereka dapat merubah lokasi satu sama lain dan bertukar pesan.
Untuk menutuo popup: gunakan pemanggilan close()
. Juga pengguna mungkin menutupnya (seperti jendela yang lain). window.closed
adalah true
setelahnya.
- Metode
focus()
danblur()
mengizinkan sebuah jendela untuk fokus/ tidak fokus. Tetapi mereka tidak bekerja setiap saat. focus
danblur
even mengizinkan untuk melacak perpindahan masuk dan keluar jendela. Namun tolong dicatat bahwa sebuah jendela mungkin masih dapat terlihat meskipun di dalam status latar belakang, setelahblur
.
komentar
<code>
, untuk beberapa baris – bungkus dengan tag<pre>
, untuk lebih dari 10 baris – gunakan sandbox (plnkr, jsbin, < a href='http://codepen.io'>codepen…)