Ketika saya bermain dengan <input type="range">
, Firefox memicu acara pertukaran hanya jika kita meletakkan slider ke posisi baru di mana Chrome dan orang lain memicu acara pertukaran saat slider ditarik.
Bagaimana saya bisa mewujudkannya dengan menyeret di Firefox?
function showVal(newVal){
document.getElementById("valBox").innerHTML=newVal;
}
<span id="valBox"></span>
<input type="range" min="5" max="10" step="1" onchange="showVal(this.value)">
onchange
tidak menyala. Itu dalam pemecahan masalah yang saya temukan pertanyaan ini.Jawaban:
Tampaknya Chrome dan Safari salah:
onchange
seharusnya hanya dipicu ketika pengguna melepaskan mouse. Untuk mendapatkan pembaruan terus-menerus, Anda harus menggunakanoninput
acara tersebut, yang akan menangkap pembaruan langsung di Firefox, Safari dan Chrome, baik dari mouse dan keyboard.Namun,
oninput
tidak didukung di IE10, jadi taruhan terbaik Anda adalah menggabungkan dua penangan acara, seperti ini:Lihat utas Bugzilla ini untuk informasi lebih lanjut.
sumber
$("#myelement").on("input change", function() { doSomething(); });
dengan jQuery.onchange()
tidak berfungsi di web seluler sepertiAndroid Chrome
daniOS Safari
. Ada saran alternatif?RINGKASAN:
Saya berikan di sini kemampuan lintas-peramban desktop dan seluler tanpa jQuery untuk secara konsisten merespons interaksi rentang / penggeser, sesuatu yang tidak mungkin dilakukan di peramban saat ini. Ini pada dasarnya memaksa semua browser untuk meniru
on("change"...
acara IE11 untuk merekaon("change"...
atauon("input"...
acara. Fungsi baru adalah ...... di mana
r
elemen input rentang Anda danf
pendengar Anda. Pendengar akan dipanggil setelah interaksi apa pun yang mengubah nilai rentang / penggeser tetapi tidak setelah interaksi yang tidak mengubah nilai itu, termasuk interaksi awal mouse atau sentuh pada posisi penggeser saat ini atau saat memindahkan salah satu ujung penggeser.Masalah:
Pada awal Juni 2016, berbagai browser berbeda dalam hal bagaimana mereka merespons penggunaan rentang / slider. Lima skenario relevan:
Tabel berikut menunjukkan bagaimana setidaknya tiga browser desktop berbeda dalam perilaku mereka sehubungan dengan skenario di atas yang mereka respons:
Larutan:
The
onRangeChange
berfungsi memberikan respon lintas-browser konsisten dan dapat diprediksi interaksi berbagai / slider. Itu memaksa semua browser untuk berperilaku sesuai dengan tabel berikut:Di IE11, kode ini pada dasarnya memungkinkan semuanya beroperasi sesuai status quo, yaitu memungkinkan
"change"
acara berfungsi dengan cara standar dan"input"
acara tidak relevan karena tidak pernah menyala. Di browser lain,"change"
acara secara efektif dibungkam (untuk mencegah peristiwa tambahan dan kadang-kadang tidak mudah-muncul dari penembakan). Selain itu,"input"
acara ini hanya akan mengaktifkan pendengar ketika nilai rentang / penggeser berubah. Untuk beberapa browser (misalnya Firefox) ini terjadi karena pendengar secara efektif dibungkam dalam skenario 1, 4 dan 5 dari daftar di atas.(Jika Anda benar-benar membutuhkan pendengar untuk diaktifkan dalam skenario 1, 4 dan / atau 5 Anda dapat mencoba memasukkan
"mousedown"
/"touchstart"
,"mousemove"
/"touchmove"
dan / atau"mouseup"
/"touchend"
peristiwa. Solusi semacam itu berada di luar cakupan jawaban ini.)Fungsi di Peramban Seluler:
Saya telah menguji kode ini di peramban desktop tetapi tidak di peramban seluler mana pun. Namun, dalam jawaban lain di halaman ini MBourne telah menunjukkan bahwa solusi saya di sini "... tampaknya berfungsi di setiap browser yang dapat saya temukan (Menangkan desktop: IE, Chrome, Opera, FF; Android Chrome, Opera dan FF, Safari Safari) " . (Terima kasih MBourne.)
Pemakaian:
Untuk menggunakan solusi ini, sertakan
onRangeChange
fungsi dari ringkasan di atas (disederhanakan / diperkecil) atau cuplikan kode demo di bawah ini (identik secara fungsional tetapi lebih jelas) dalam kode Anda sendiri. Aktifkan sebagai berikut:di mana elemen DOM
myRangeInputElmt
yang Anda inginkan<input type="range">
danmyListener
merupakan fungsi pendengar / penangan yang Anda inginkan dipanggil pada"change"
peristiwa-seperti.Pendengar Anda mungkin kurang parameter jika diinginkan atau dapat menggunakan
event
parameter, yaitu salah satu dari berikut ini akan berfungsi, tergantung pada kebutuhan Anda:atau
(Menghapus pendengar acara dari
input
elemen (misalnya menggunakanremoveEventListener
) tidak dibahas dalam jawaban ini.)Deskripsi Demo:
Dalam cuplikan kode di bawah ini, fungsi
onRangeChange
menyediakan solusi universal. Sisa kode hanyalah contoh untuk menunjukkan penggunaannya. Setiap variabel yang dimulai denganmy...
tidak relevan dengan solusi universal dan hanya hadir untuk kepentingan demo.Demo ini menunjukkan rentang / nilai slider serta berapa kali standar
"change"
,"input"
dan"onRangeChange"
acara kustom telah dipecat (masing-masing baris A, B dan C). Saat menjalankan cuplikan ini di browser yang berbeda, perhatikan hal berikut saat Anda berinteraksi dengan rentang / slider:Kode Demo:
Kredit:
Meskipun implementasinya di sini sebagian besar milik saya, itu terinspirasi oleh jawaban MBourne . Jawaban lain itu menyarankan bahwa peristiwa "input" dan "perubahan" dapat digabungkan dan bahwa kode yang dihasilkan akan berfungsi di browser desktop dan seluler. Namun, kode dalam jawaban itu menghasilkan peristiwa "ekstra" tersembunyi yang dipecat, yang dengan sendirinya bermasalah, dan peristiwa yang dipecat berbeda di antara peramban, masalah selanjutnya. Implementasi saya di sini menyelesaikan masalah tersebut.
Kata kunci:
Jenis slider rentang input JavaScript mengubah input browser kompatibilitas-silang mobile desktop no-jQuery
sumber
Saya memposting ini sebagai jawaban karena itu layak menjadi jawaban itu sendiri daripada komentar di bawah jawaban yang kurang berguna. Saya menemukan metode ini jauh lebih baik daripada jawaban yang diterima karena dapat menyimpan semua js dalam file terpisah dari HTML.
Jawaban diberikan oleh Jamrelian dalam komentarnya di bawah jawaban yang diterima.
Namun perlu diperhatikan komentar Jaime ini
Seperti di dalamnya akan memecat acara ketika Anda telah berhenti menggerakkan mouse, dan kemudian lagi ketika Anda melepaskan tombol mouse.
Memperbarui
Sehubungan dengan
change
acara daninput
acara yang menyebabkan fungsi memicu dua kali, ini bukan masalah.Jika Anda memiliki fungsi untuk mematikan fungsi
input
, sangat kecil kemungkinannya bahwa akan ada masalah saatchange
acara diaktifkan.input
menyala dengan cepat saat Anda menarik slider input rentang. Khawatir tentang satu lagi panggilan fungsi menembak pada akhirnya adalah seperti khawatir tentang setetes air dibandingkan dengan lautan air yang merupakaninput
peristiwa.Alasan bahkan termasuk
change
acara sama sekali adalah demi kompatibilitas browser (terutama dengan IE).sumber
UPDATE: Saya meninggalkan jawaban ini di sini sebagai contoh tentang bagaimana menggunakan peristiwa mouse untuk menggunakan interaksi rentang / slider di browser desktop (tetapi bukan ponsel). Namun, saya sekarang juga menulis jawaban yang sama sekali berbeda dan, saya percaya, jawaban yang lebih baik di bagian lain halaman ini yang menggunakan pendekatan berbeda untuk menyediakan solusi desktop -dan-mobile lintas-browser untuk masalah ini.
Jawaban asli:
Rangkuman: Solusi lintas-browser, JavaScript biasa (yaitu, no-jQuery) untuk memungkinkan nilai input rentang baca tanpa menggunakan
on('input'...
dan / atauon('change'...
yang berfungsi secara tidak konsisten di antara browser.Sampai hari ini (akhir Februari 2016), masih ada inkonsistensi browser, jadi saya memberikan pekerjaan baru di sini.
Masalahnya: Saat menggunakan input rentang, yaitu bilah geser,
on('input'...
memberikan nilai rentang yang terus diperbarui di Mac dan Windows Firefox, Chrome dan Opera serta Mac Safari, sementaraon('change'...
hanya melaporkan nilai rentang saat mouse-up. Sebaliknya, di Internet Explorer (v11),on('input'...
tidak berfungsi sama sekali, danon('change'...
terus diperbarui.Saya melaporkan di sini 2 strategi untuk mendapatkan pelaporan nilai rentang terus menerus yang identik di semua browser menggunakan vanilla JavaScript (yaitu tidak ada jQuery) dengan menggunakan mousedown, mousemove dan (mungkin) peristiwa mouseup.
Strategi 1: Lebih pendek tetapi kurang efisien
Jika Anda lebih suka kode yang lebih pendek daripada kode yang lebih efisien, Anda dapat menggunakan solusi pertama ini yang menggunakan mouse dan mouse tetapi tidak menggunakan mouse. Ini membaca bilah geser sesuai kebutuhan, tetapi terus menembak tanpa perlu selama acara tetikus apa pun, bahkan ketika pengguna belum mengklik dan karenanya tidak menyeret bilah geser. Ini pada dasarnya membaca nilai rentang baik setelah 'mousedown' dan selama acara 'mousemove', sedikit menunda masing-masing menggunakan
requestAnimationFrame
.Strategi 2: Lebih lama tetapi lebih efisien
Jika Anda membutuhkan kode yang lebih efisien dan dapat mentolerir panjang kode yang lebih lama, maka Anda dapat menggunakan solusi berikut yang menggunakan mousedown, mousemove, dan mouseup. Ini juga membaca bilah geser sesuai kebutuhan, tetapi berhenti membacanya segera setelah tombol mouse dilepaskan. Perbedaan mendasar adalah bahwa hanya mulai mendengarkan 'mousemove' setelah 'mousedown', dan berhenti mendengarkan untuk 'mousemove' setelah 'mouseup'.
Demo: Penjelasan lebih lengkap tentang perlunya, dan implementasi, penyelesaian di atas
Kode berikut lebih lengkap menunjukkan banyak aspek dari strategi ini. Penjelasan tertanam dalam demonstrasi:
Tampilkan cuplikan kode
sumber
touchmove
harus cukup, dan saya pikir itu bisa diperlakukan sepertimousemove
dalam kasus ini.Solusi Andrew Willem tidak kompatibel untuk perangkat seluler.
Berikut ini adalah modifikasi dari solusi keduanya yang bekerja di Edge, IE, Opera, FF, Chrome, iOS Safari, dan perangkat seluler (yang dapat saya uji):
Pembaruan 1: Bagian "requestAnimationFrame" yang dihapus, karena saya setuju itu tidak perlu:
Pembaruan 2: Respon untuk jawaban terbaru Andrew 2 Juni 2016:
Terima kasih, Andrew - yang tampaknya berfungsi di setiap browser yang dapat saya temukan (Menangkan desktop: IE, Chrome, Opera, FF; Android Chrome, Opera dan FF, Safari Safari).
Pembaruan 3: solusi if ("oninput in slider)
Tampaknya ini berfungsi di semua browser di atas. (Saya tidak dapat menemukan sumber aslinya sekarang.) Saya menggunakan ini, tetapi kemudian gagal pada IE dan saya mencari yang lain, maka saya berakhir di sini.
Tetapi sebelum saya memeriksa solusi Anda, saya perhatikan ini berfungsi lagi di IE - mungkin ada beberapa konflik lainnya.
sumber
Untuk perilaku lintas-browser yang baik, dan kode yang dapat dimengerti, yang terbaik adalah menggunakan atribut onchange dalam kombinasi formulir:
Menggunakan oninput yang sama , nilainya diubah secara langsung.
sumber
Namun pendekatan lain - hanya menetapkan bendera pada elemen yang menandakan jenis acara apa yang harus ditangani:
sumber
Anda dapat menggunakan acara JavaScript "ondrag" untuk memecat secara terus-menerus. Itu lebih baik daripada "input" karena alasan berikut:
Dukungan browser.
Dapat membedakan antara acara "ondrag" dan "perubahan". "input" menyala untuk seret dan ubah.
Di jQuery:
Referensi: http://www.w3schools.com/TAgs/ev_ondrag.asp
sumber