Saya sedang mengerjakan proyek obrolan H5 baru-baru ini, dan saya menemui salah satu kendala terbesar: kotak input menjadi fokus, keyboard lunak muncul, dan kotak input harus diserap (atau di atasnya) pada metode input kotak. Persyaratannya sangat jelas dan terkesan sederhana, namun nyatanya tidak. Setelah bereksperimen dengan beberapa model, kami menemukan bahwa masalah utama yang ada adalah sebagai berikut:
Mari kita telusuri solusi dari permasalahan di atas satu per satu.
Dapatkan status pop-up dan tarik kembali keyboard lunakPenting untuk mengetahui apakah soft keyboard naik atau turun, dan pemrosesan kompatibilitas selanjutnya harus didasarkan pada hal ini. Namun, H5 tidak secara langsung memonitor kejadian asli dari soft keyboard. Ia hanya dapat secara tidak langsung memantau kinerja aspek lain dari halaman tersebut dengan memunculkan atau menarik kembali soft keyboard, sehingga menyelamatkan negara. Apalagi performa di iOS dan Android berbeda.
Performa pop-up keyboard lunak iOSDi iOS, ketika kotak input (input, textarea, atau rich text) mendapat fokus, keyboard muncul, halaman (tampilan web) tidak dikompresi, atau tinggi (height) tidak berubah, tetapi halaman (tampilan web) sebagai keseluruhannya akan bergulir ke atas. Dan tinggi gulir maksimum (scrollTop) adalah tinggi keyboard lunak.
Kinerja pop-up keyboard lunak AndroidDemikian pula, di Android, kotak input menjadi fokus dan keyboard muncul, namun tinggi halaman (tampilan web) akan berubah. Secara umum, tingginya adalah tinggi area visual (tinggi asli dikurangi tinggi soft keyboard ), kecuali karena konten halaman yang Diperluas dapat menghasilkan pengguliran, namun tampilan web itu sendiri tidak dapat menggulir.
Performa runtuhnya keyboard lunak iOSSaat tombol tarik kembali pada keyboard lunak atau area halaman di luar kotak masukan terpicu, kotak masukan kehilangan fokus dan keyboard lunak ditarik kembali.
Kinerja keyboard lunak Android runtuhKetika area di luar kotak input terpicu, kotak input kehilangan fokus dan keyboard lunak ditarik kembali. Namun, ketika tombol tarik kembali pada keyboard dipicu, kotak input tidak akan kehilangan fokus, dan keyboard lunak juga akan ditarik kembali.
Pantau pop-up dan runtuhnya keyboard lunakBerdasarkan perbedaan performa pop-up dan penciutan keyboard di atas pada iOS dan Android, kita dapat melakukan pemrosesan berikut secara terpisah untuk memantau pop-up dan penciutan keyboard lunak:
// Menilai jenis perangkat var judgeDeviceType = function () { var ua = window.navigator.userAgent.toLocaleLowerCase(); var isIOS = /iphone|ipad|ipod/.test(ua); ( ua); return { isIOS: isIOS, isAndroid: isAndroid }}()// Dengarkan fungsi acara pop-up dan ciutkan keyboard lunak dari kotak input mendengarkanKeybord($input) { if (judgeDeviceType.isIOS) { // Keyboard IOS muncul: Kotak input IOS dan Android menjadi fokus dan keyboard muncul $input.addEventListener('focus', function () { console.log(' Keyboard IOS Muncul! '); // Operasi setelah keyboard IOS muncul}, false) // Keyboard IOS ditarik: IOS Jika Anda mengklik di luar kotak input atau mengklik tombol retract, kotak input akan kehilangan fokus dan keyboard akan ditarik kembali. $input.addEventListener('blur', () => { console.log('IOS keyboard retracted!') ; // Pengoperasian setelah keyboard iOS dilipat }) } // Keyboard Android dilipat: Saat keyboard Android muncul atau dilipat, tinggi halaman akan berubah, dan berdasarkan ini, keyboard dilipat if (judgeDeviceType.isAndroid) { var originHeight = document.documentElement.clientHeight ||. document.body.clientHeight; window.addEventListener('resize', function () { var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < resizeHeight) { console.log('Keyboard Android disingkirkan!'); // Operasi setelah keyboard Android disingkirkan} else { console.log('Keyboard Android muncul! '); // Operasi setelah keyboard Android muncul} originHeight = resizeHeight) }}var $inputs = document.querySelectorAll('.input');for (var i = 0; i < $inputs.length; i++) { mendengarkanKeybord($input[i]);}Saat memunculkan soft keyboard, kotak input selalu bergulir ke area yang terlihat.
Terkadang kita akan membuat formulir masukan dengan banyak item masukan. Kotak masukan mendapat fokus dan keyboard lunak muncul. Jika kotak input terletak di bagian bawah halaman, di iOS, seluruh tampilan web akan digulung pada jarak tertentu sehingga kotak input yang terfokus secara otomatis berada di area yang terlihat . Ini hanya akan mengubah tinggi halaman, tanpa menggulir ke elemen yang sedang difokuskan ke area yang terlihat.
Karena cara di atas telah diterapkan untuk memantau pop-up dan penarikan kembali keyboard iOS dan Android, di sini Anda hanya perlu menggulir (scrollIntoView()) elemen fokus ke area visual setelah keyboard Android muncul. Untuk melihat efeknya, Anda bisa klik di sini.
// Dapatkan elemen fokus dan gulir ke area yang terlihat function activeElementScrollIntoView(activeElement, delay) { var dapat diedit = activeElement.getAttribute('contenteditable') // Kotak masukan, area teks, atau teks kaya tidak bergulir ke area yang terlihat setelah diperoleh area fokus if (activeElement.tagName == 'INPUT' || activeElement.tagName == 'TEXTAREA' || dapat diedit === '' || dapat diedit) { setTimeout(function () { activeElement.scrollIntoView(); }, delay) }}// ...// Operasikan activeElementScrollIntoView($input, 1000);// ... setelah keyboard Android munculBangkitkan keyboard lunak numerik murni
Kotak input formulir di atas mengharuskan Anda memasukkan nomor telepon. Mirip dengan ini, keyboard lunak numerik akan muncul. Karena kita berbicara tentang kompatibilitas keyboard lunak, mari masukkan di sini. Solusi yang lebih baik adalah sebagai berikut:
<p>Silakan masukkan nomor ponsel Anda</p><input type=tel novalidate=novalidate pattern=[0-9]* class=input>
Jika Anda menggunakan browser WeChat versi IOS12 dan V6.7.4+ untuk membuka demo masukan formulir di atas, Anda akan terkejut menemukan bahwa setelah keyboard ditarik, halaman yang semula digulir ke atas tidak kembali ke posisi bawah, menyebabkan keyboard asli untuk memantul. Posisi awal kosong.
Faktanya, ini adalah bug Apple di iOS dan akan muncul di semua perangkat iOS12 yang dikemas dengan Xcode10. WeChat secara resmi telah memberikan solusinya. Cukup gulir halaman (tampilan web) kembali ke posisi bawah jendela (posisi ClientHeight) setelah soft keyboard ditutup. Demo input form yang telah diperbaiki di atas dapat diklik di sini
console.log('Keyboard iOS disingkirkan!');// Browser WeChat versi 6.7.4+IOS12 akan menunjukkan bahwa setelah keyboard disingkirkan, tampilan didorong ke atas tetapi tidak ke bawah var wechatInfo = window.navigator.userAgent .match( /MicroMessenger//([/d/.]+)/i);if (!wechatInfo) kembali;var wechatVersion = wechatInfo[1];var versi = (navigator.appVersion).match(/OS (/d+)_(/d+)_?(/d+)?/);if (+wechatVersion.replace(//./g, '') >= 674 && +versi[1] >= 12) { window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));}Kompatibel dengan metode masukan pihak ketiga
Setelah disebutkan di atas, sebenarnya lebih dari separuh jebakan kotak masukan obrolan H5 telah terisi. Selanjutnya, mari kita lihat struktur HTML dasar kotak masukan obrolan.
<div class=chat__content> <div> <p>Beberapa konten obrolan 1</p> </div> <!--Hilangkan ribuan baris konten obrolan--></div><div class=input__content> <div class =input contenteditable=true></div> <button>Kirim</button></div>
gaya
/* Hilangkan beberapa gaya */.chat__content { height: calc(100% - 40px); margin-bottom: 40px; overflow-y: auto; overflow-x:hidden;}.input__content { display: flex; posisi: absolut; kiri: 0; kanan: 0; bawah: 0; align-items: tengah;}/* Hilangkan beberapa gaya*/
Sederhana sekali, cukup bagi area konten dan area input. Area input sudah benar-benar diposisikan. Menurut metode demo input formulir di atas, memang benar bahwa sebagian besar browser Android baik-baik saja, tetapi pengujiannya dilakukan pada IOS Browser metode masukan asli dan Untuk metode masukan pihak ketiga (seperti metode masukan Sogou), kotak masukan akan diblokir sepenuhnya; untuk browser QQ atau browser WeChat, dengan metode masukan pihak ketiga, kotak masukan akan diblokir setengah; dengan browser Baidu, dengan metode masukan pihak ketiga, kotak masukan akan diblokir dan juga akan tertutup sepenuhnya. Untuk melihat efeknya, Anda dapat mengunjungi di sini di browser yang sesuai.
Di UC Browser, setelah keyboard lunak muncul, ketinggian bilah judul di atas browser memiliki efek dinamis penundaan penurunan ketinggian, yang menyebabkan tampilan web bergulir sedikit ke bawah dan kotak masukan bawah bergulir ke non- daerah yang terlihat.
Sedangkan untuk metode masukan pihak ketiga, ada spekulasi bahwa posisi gulir awal tampilan web salah karena perhitungan ketinggian yang salah setelah panel metode masukan muncul. Faktanya, kedua titik tersebut disebabkan oleh webview yang tidak bergulir pada tempatnya. Setelah keyboard lunak muncul, elemen fokus dapat digulir lagi ke area yang terlihat, sehingga memaksa tampilan web untuk bergulir ke tempatnya.
console.log('Keyboard Android muncul!');activeElementScrollIntoView($input, 1000);Solusi hack yang kompatibel dengan browser Android Xiaomi
Pada browser Android Xiaomi, setelah menerapkan solusi di atas, saya menemukan bahwa kotak input obrolan masih diblokir dengan ketat, dan scrollIntoView() masih tidak bergerak. Jadi menurut saya sebenarnya karena soft keyboard telah di-scroll ke bawah, dan tinggi halaman lebih besar dari tinggi area visual saat soft keyboard muncul. Dengan cara ini, tinggi halaman hanya dapat dinaikkan secara paksa setelahnya keyboard lunak muncul sehingga kotak input dapat ditampilkan. Berdasarkan penjelasan di atas, ini kompatibel dengan metode masukan pihak ketiga. Untuk melihat efeknya, Anda dapat mengklik di sini.
// Keyboard Android ditarik kembali: Ketinggian halaman akan berubah ketika keyboard Android muncul atau ditarik. Berdasarkan hal ini, penarikan keyboard diketahui jika (judgeDeviceType.isAndroid) { var originHeight = document.documentElement.clientHeight || document. body.clientHeight ; window.addEventListener('mengubah ukuran', fungsi () { var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < resizeHeight) { console.log('keyboard Android ditutup!'); // Memperbaiki masalah kotak input yang masih diblokir oleh metode input di browser Xiaomi if (judgeDeviceType.isMiuiBrowser ) { document.body.style.marginBottom = '0px'; } } else { console.log('Keyboard Android muncul!'); Memperbaiki masalah kotak input yang masih diblokir oleh metode input di browser Xiaomi if (judgeDeviceType.isMiuiBrowser) { document.body.style.marginBottom = '40px'; } activeElementScrollIntoView($input, 1000); }, PALSU )}Meringkaskan
Ujung H5 memiliki jalan panjang dan banyak jebakan, jadi Anda harus terus mencoba. Memahami perbedaan kinerja antara halaman pop-up keyboard lunak di iOS dan Android merupakan prasyarat. Langkah kedua adalah menggulir elemen fokus ke area yang terlihat. Pada saat yang sama, perbedaan dalam metode input pihak ketiga dan beberapa browser harus diperhitungkan.
Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.