Saat ada komponen terkontrol untuk nama formulir yang telah disimpan pengguna di browser mereka (umum dengan kolom nama pengguna / sandi), browser terkadang akan merender halaman dengan nilai di kolom tersebut tanpa mengaktifkan peristiwa onChange. Jika pengguna mengirimkan formulir, status komponen tidak mencerminkan apa yang ditampilkan kepada pengguna.
Saat bereksperimen dengan ini, tampaknya data ada di sana saat dimuat (diuji dengan mencatat nilai this.refs.myinput.getDOMNode ().)
Ini sepertinya membahasnya lebih banyak: http://stackoverflow.com/a/11710295
atm saya menggunakan https://github.com/tbosch/autofill-event ini
cc saya
(Kiat @viscaper : tekan "Berlangganan" di kolom kanan.)
Adakah pembaruan atau saran praktik terbaik yang satu ini? Polyfill acara IsiOtomatis sepertinya solusi palu godam.
Safari (8) memang mengirimkan peristiwa perubahan pada pengisian otomatis, tetapi peristiwa tersebut tidak menggelembung sehingga tidak mencapai penangan react.
Diskusi terkait di https://github.com/angular/angular.js/issues/1460 telah ditutup, dengan beberapa saran, salah satunya adalah memanfaatkan https://github.com/tbosch/autofill-event untuk mengaktifkan ubah acara di IsiOtomatis, secara manual.
Saya pikir, kita juga bisa menutup di sini.
Alangkah baiknya jika acara IsiOtomatis sebagai bagian dari React, mungkin sebagai addon. Fungsi ini akan diperlukan untuk hampir semua orang yang menggunakan React untuk validasi formulir. Skrip peristiwa IsiOtomatis juga menambahkan dependensi untuk jQuery, yang mungkin tidak diinginkan dalam banyak kasus.
Ini adalah bug browser yang mempengaruhi semua browser dengan sedikit berbeda. Saya pikir hanya karena sudut punted mencoba untuk bekerja atau memperbaikinya tidak berarti bereaksi harus. Itu hal yang biasa tapi saya mengerti jika ini adalah "wontfix".
Saya tidak terlalu ahli dalam berbagai pelacak bug browser, tetapi alangkah baiknya jika seseorang yang dapat menemukan atau membuka masalah untuk ini. Saya pikir tim react memiliki bobot lebih dari kebanyakan pengguna saat membuka masalah tentang itu. Dan kami dapat mengumpulkan tiket di sini untuk para pengembang yang tertarik.
Saya menyusul dengan benang sudut. Firefox memiliki masalah dengan bidang sandi (https://bugzilla.mozilla.org/show_bug.cgi?id=950510 masih terbuka), tidak ada kabar tentang bug safari #, chrome telah diperbaiki.
Masalah sudah dilacak di beberapa tempat - https://github.com/angular/angular.js/issues/1460#issuecomment -53947546
Masalah Chrome sekarang ditutup, tetapi cukup jelas tidak berfungsi di Chrome 50 dengan React 0.14.8.
belum ada perbaikan?
Saya merasa seperti ini bekerja untuk sementara dan bangkrut lagi baru-baru ini?
ada pembaruan tentang masalah ini?
Berikut ekstrak solusi saya untuk masalah ini:
export default class Input extends Component {
static propTypes = {
value: PropTypes.string,
onFieldChange: PropTypes.func,
};
static defaultProps = {
value: '',
}
componentDidMount() {
this._listener = setInterval(() => {
if (!this.input || this._previousValue === this.input.value) {
return;
}
this._previousValue = this.input.value;
const evt = document.createEvent('HTMLEvents');
evt.initEvent('input', true, true);
this.input.dispatchEvent(evt);
}, 20);
}
componentWillUnmount() {
clearInterval(this._listener);
}
refInput = (input) => this.input = input;
render() {
const { label,
value,
onFieldChange,
} = this.props;
this.input = this.input || { value };
return (
<input
value={this.input.value}
onChange={onFieldChange}
ref={this.refInput}
/>
);
}
}
CATATAN: value
berasal dari negara bagian dan onFieldChange
memperbarui status dengan nilai baru
Kode setInterval berasal dari https://github.com/Pephers/react-autofill
Adakah yang bisa mengonfirmasi bahwa masalah ini telah diperbaiki dengan iOS 10.2? Saya tidak dapat mereproduksinya sekarang ...
Saya masih mengalami masalah di iOS 10.2 dengan Chrome versi 55.0.2883.79 ... Bertentangan dengan apa yang dijelaskan di atas, bagi saya konten yang diisi otomatis berkedip sebentar di formulir dan kemudian dihapus lagi.
Jadi sekarang konsisten dengan apa yang disimpan di negara bagian, namun, IsiOtomatis masih tidak berfungsi ...
Saya mereproduksi masalah yang sama yang dihadapi oleh @irisSchaffer. Saya memiliki aplikasi isomorfik, di mana saya membuat halaman statis dengan react dan express, kemudian pada klien saya mengekspor props dan menggunakan komponen halaman yang sama.
Bahkan saat tidak menangani nilai masukan kata sandi melalui react, komponen react klien menghapus kata sandi yang disimpan dari masukan, bahkan ketika chrome menampilkannya sebentar. Ketika saya menonaktifkan javascript dari browser, kata sandi yang disimpan tetap di tempatnya.
Masalah ini hanya terlihat di Chrome, menggunakan versi terakhirnya, 58.
Tidak berhubungan dengan react, password yang disimpan tidak dapat diakses melalui element.value hingga ada event yang diaktifkan di dom, seperti focus, key event apapun, dll. Mencoba mensimulasikan event fire melalui javascript, namun tidak berhasil mengisi nilai Properti.
+1. ada perbaikan atau peretasan?
Saya masih menghadapi masalah ini di iOS 10.3.3 Chrome 60.0.3112.89.
Pengisian otomatis berfungsi, mengisi bidang tetapi tidak mengubah status.
Mengatasi masalah dekorator: https://github.com/Pephers/react-autofill
Komponen umum mengatasi:
/**
Trigger onChange event after browser auto-fill.
<strong i="8">@see</strong> https://github.com/facebook/react/issues/1159
<strong i="9">@example</strong> <AutoFillWatch component={ref =>
<input required type="password" ref={ref} />
}/>
*/
class AutoFillWatch extends Component {
static propTypes = {
// Auto-fill component like: <input type="password"
component: PropTypes.func.isRequired,
// component pass-through reference
ref: PropTypes.func,
}
componentDidMount() {
this._listener = setInterval(() => {
if (!this.input || this._previousValue === this.input.value) {
return;
}
this._previousValue = this.input.value;
const evt = document.createEvent('HTMLEvents');
evt.initEvent('input', true, true);
this.input.dispatchEvent(evt);
}, 100);
}
componentWillUnmount() {
clearInterval(this._listener);
}
componentDidMount() {
const {ref} = this.props
if(ref) {
console.log('ref', this.input);
ref(this.input)
}
}
refInput = (input) => this.input = input;
render() {
const {component} = this.props
return component(this.refInput)
}
}
Chrome untuk iOS (pastikan Anda mengujinya dengan IsiOtomatis dari Chrome, dan bukan saran dari keyboard iOS) hanya mengeluarkan change
saat mengisi otomatis nilai. Mobile Safari di sisi lain mengeluarkan focus
, keydown
, input
, keyup
, change
dan blur
, sebagai melakukan Chrome dan Safari di Mac.
React tidak menggunakan acara change
untuk <input />
yang tampaknya menjadi penyebab utama masalah ini: https://github.com/facebook/react/blob/e932ad68bed656eed5295b61ba74e5d0857902ed/src/renderers /dom/shared/eventPlugins/ChangeEventPlugin.js#L66 -L71
Tidakkah mungkin React onChange
juga dipicu pada event DOM change
? Akankah ada salahnya?
Masalah terkait untuk Chrome iOS: https://bugs.chromium.org/p/chromium/issues/detail?id=705275
Saya telah menguji autofilling dan event dengan halaman kecil berikut:
<html>
<head>
<script type="text/javascript">
window.onload = function () {
let elements = document.querySelectorAll('input');
let actions = document.getElementById('actions')
let events = 'focus blur keydown keyup change input'.split(' ');
elements.forEach(element => {
events.forEach(event => {
element.addEventListener(event, e => {
console.log(e);
let eTypeNode = document.createTextNode(element.name + ' > ' + e.type + ":" + e.code + ":" + e.keyIdentifier);
actions.appendChild(eTypeNode);
actions.appendChild(document.createElement('br'));
})
})
})
};
</script>
</head>
<body>
<form>
<input type="text" name="name" id="a" autocomplete="name" />
<input type="email" name="email" id="b" autocomplete="email" />
<input type="tel" name="tel" id="c" autocomplete="tel" />
</form>
<div id="actions"></div>
</body>
</html>
Peristiwa perubahan dipancarkan di Chrome v62 saat Anda membungkus input dengan elemen <form />
.
ada penangan kejadian onInput yang akan mengambil nilai bidang masukan jika berubah.
Masih melihat beberapa perilaku tidak biasa di sini dengan IsiOtomatis di iOS. Dekorator react-autofill di atas tampaknya bekerja dengan baik dengan autofill sederhana tetapi tidak dengan pintasan autofill yang disediakan oleh keyboard.
Ini harus diperbaiki di Chrome untuk iOS sekarang: https://chromium.googlesource.com/chromium/src/+/55518e17850cac0bdc6fca7b24092bea479e34db. Saya tidak yakin kapan patch ini akan disertakan dalam versi rilis.
Mengapa onChange harus digunakan?
Mengapa kita HARUS menggunakan 'onChange' tapi bukan 'change event'
class Input extends Component {
componentDidMount(){
this.input.addEventListener('change', (e)=>{
this.props.onChange(this.props.field, e.target.value)
})
}
render(){
const { className, name, label, autofill, field, onBlur, onChange, value, error, visited, required, type, maxLength } = this.props
return (
<div className={ [styles.inputWrap, className || ''].join(' ') } onBlur={e => onBlur(field)}>
<input ref={n => this.input = n} id={field} name={name || field} type={ type || 'text' } defaultValue={ value }
autoComplete={ autofill } maxLength={maxLength} />
<div className={ [styles.placeholder, value? styles.active:''].join(' ') }>
<FormattedMessage id={label} />
<i className={styles.required}>{required? '*':''}</i>
<span className={ styles.error }>{ visited? error:'' }</span>
</div>
</div>
)
}
}
Peristiwa perubahan dipancarkan di Chrome v62 saat Anda membungkus input dengan elemen
<form />
.
Saya mengonfirmasi bahwa solusi ini berfungsi untuk Chrome untuk mengisi otomatis nomor telepon melalui autoComplete="tel"
https://github.com/catamphetamine/react-phone-number-input/issues/101
Solusi di atas menggunakan this._previousValue !== this.input.value
sayangnya hanya berfungsi untuk iOS Safari. .value
iOS Chrome masih kosong setelah pengisian otomatis.
Saya tidak tahu bagaimana orang menangani IsiOtomatis dalam formulir saat menggunakan komponen yang dikontrol. Pertimbangkan skenario login ini:
.value
sebagai kosongKecuali ada cara agar Chrome melaporkan nilai, saya tidak dapat memikirkan solusi selain menggunakan komponen yang tidak terkontrol, validasi input html5, dan mendapatkan nilai formulir saat dikirimkan seperti dulu.
Anda dapat melacak (dan memberi bintang) masalahnya di sini: https://bugs.chromium.org/p/chromium/issues/detail?id=813175
Saya tidak bisa mendapatkan solusi di atas untuk bekerja dengan @DominicTobias. Ada banyak lapisan masalah. Yang pertama adalah bahwa this.input.value
selalu kosong. Namun, saya menemukan, bahwa jika Anda menggunakan document.getElementById
di setiap loop, kemudian document.getElementById(id).value
- Anda akan mendapatkan nilai kembali.
Ini tidak menyelesaikan masalah dispatchEvent
, tetapi setidaknya Anda bisa mendapatkan nilai yang diisi otomatis dan dapat melakukan hal-hal dengannya (misalnya hanya memanggil penangan onChange
dari input terkontrol).
@wlingke senang mengetahuinya (dan betapa anehnya)! Saya harus menempuh rute itu juga jika mereka tidak memperbaiki bug tepat waktu untuk rilis saya
@wlingke Saat menyiapkan demo untuk orang-orang Chrome, saya menyadari sesuatu - ini bukan masalah dengan Chrome, saya seharusnya membaca komentar di atas dengan lebih cermat (khususnya komentar @ oscar-b). onChange
adalah acara sintetis di React yang sebenarnya tidak menggunakan acara change
, yang tampaknya cukup aneh bagi saya.
Anda bahkan dapat melihat dalam demo di bawah ini bahwa perilakunya berbeda, lebih seperti mendengarkan acara input
. Saat Anda menggunakan acara change
acara tersebut berfungsi dengan baik di iOS Chrome.
Jadi saya akan menyarankan untuk mendapatkan referensi ke elemen dan hanya mendengarkan acara perubahan nyata, serta acara onChange
yang tampaknya menjadi acara input
jika Anda perlu memperbarui status sebagai pengguna sedang mengetik.
@DominicTobias Saya sebelumnya mencoba acara change
dan input
secara terpisah serta keduanya sekaligus di dekorator itu tetapi tidak dapat membuatnya berfungsi di aplikasi saya.
Saya juga tidak yakin apakah ini mengubah banyak hal .. tetapi ada perbedaan saat mengisi otomatis SATU bidang dibandingkan mengisi otomatis bidang GANDA. Peristiwa input
berfungsi dengan baik saat mengisi otomatis satu bidang. Namun, di chrome seluler Anda sebenarnya dapat mengisi otomatis sekumpulan bidang sekaligus dari keyboard (seperti nama depan, nama belakang, email semua dengan satu ketukan).
Dalam skenario kedua tersebut, dekorator memungkinkan kolom pertama mengisi otomatis dengan benar (kolom pertama berarti kolom yang sedang dalam fokus). Namun, dekorator (yang dilampirkan ke semua 3 bidang), tampaknya tidak berfungsi di bidang lain.
@wlingke Menarik, saya menambahkan beberapa bidang lagi tetapi ketika mengisi otomatis ketiganya sekaligus di iOS Chrome, saya benar-benar menerima peristiwa perubahan secara asli (tetapi 0 untuk versi React di bawah):
(Tangkapan layar berasal dari browser desktop tetapi saya mendapatkan hasil yang sama di ponsel saya)
@DominicTobias Saya rasa jika Anda menggunakan acara input
- yang saya gunakan sebelumnya, ini akan bekerja sepenuhnya di Desktop. Dan bekerja untuk masukan pertama di Seluler.
Acara input
paling dekat dengan reaksi onChange
. File peristiwa change
setelah elemen kehilangan fokus dari apa yang saya pahami (https://stackoverflow.com/questions/17047497/what-is-the-difference-between-change-and-input-event- untuk-elemen-masukan)
Yap bereaksi karena alasan tertentu terikat pada acara input
: https://stackoverflow.com/questions/38256332/in-react-whats-the-difference-between-onchange-and-oninput
Jadi untuk menyederhanakannya, saya juga menyebutnya dalam komponen Input
untuk peristiwa perubahan aktual (serta peristiwa input normal). Sekarang berfungsi di iOS Chrome. Cobalah dan beri tahu saya!
componentDidMount() {
this.inputRef.addEventListener('change', this.onChange);
}
onChange = (event) => {
// React actually uses the input even for onChange, this causes autofill to
// break in iOS Chrome as it only fires a change event.
if (this.props.onChange) {
this.props.onChange(event);
}
}
componentWillUnount() {
this.inputRef.removeEventListener('change', this.onChange);
}
Sunting: Chrome seharusnya telah diperbaiki di v65 tetapi orang-orang melaporkan itu masih tidak berfungsi: /
Terima kasih atas penjelasan Dominic. Kami memperbaiki perilaku itu pada bulan Desember. Kami sekarang mengaktifkan peristiwa keydown, perubahan, masukan, dan keyup.
https://chromium-review.googlesource.com/c/chromium/src/+/771674Kami juga memperbaiki React.
https://chromium-review.googlesource.com/c/chromium/src/+/844324sementara ini memperbaiki perilaku IsiOtomatis, ini masih tidak memanggil penangan onChange.
Saya juga mengangkat masalah tentang ini dan pengembang yakin itu akan diperbaiki di 65 ... https://bugs.chromium.org/p/chromium/issues/detail?id=813175
Saya juga mendengarkan acara asli change
seperti yang dilakukan @DominicTobias dan berfungsi untuk saya di iOS Chrome. Saya memicu onChange
bentuk redux di pendengar acara asli yang terpasang di mount.
Saya juga menggunakan pemilih input:-webkit-autofill
untuk penataan.
Lihat hasilnya sendiri di bagian bawah https://labrewlangerie.com (formulir kontak).
Sepertinya perbaikan ini akhirnya menuju Chrome iOS! Tidak yakin dalam versi apa, karena tampaknya ini telah digabungkan pada 1 Desember.
https://bugs.chromium.org/p/chromium/issues/detail?id=705275#c11
https://chromium-review.googlesource.com/c/chromium/src/+/771674
https://chromium.googlesource.com/chromium/src/+/55518e17850cac0bdc6fca7b24092bea479e34db
seharusnya sudah ada di chrome terbaru. Saya masih menghadapi masalah ini (Angular 5).
Sama di sini di Chrome 65, React 15.6.
Sayang sekali, Mahmadi bilang itu akan masuk pada 13 Maret di v65 :(
Komentar 15 oleh [email protected] , 9 Maret
Perbaikan tidak ada di Chrome 64. Saya buruk. Chrome 65 harus (diluncurkan mulai 13 Maret). Saya baru saja menguji situs web demo acara asli Anda dan berfungsi di Chrome 65. Saya menghargai Anda menindaklanjuti ini.
https://bugs.chromium.org/p/chromium/issues/detail?id=813175
Coba buka di sini di ponsel Anda dan periksa: https://kind-stallman-f3c045.netlify.com/native.html
Yang benar-benar aneh adalah bahwa di v65 ini berfungsi secara native, tetapi meskipun mendapatkan input bahkan tidak diterima di React! Perlu penyelidikan lebih lanjut Saya tidak begitu yakin bagaimana react melampirkan handler (atau apakah itu melakukannya pada elemen dokumen seperti handler klik misalnya).
Secara asli saya dapat melihat acara input terjadi sekarang (https://kind-stallman-f3c045.netlify.com/native.html):
Tetapi entah bagaimana React tidak menerima kejadian-kejadian itu (https://kind-stallman-f3c045.netlify.com):
tambahkan onBlur = {this.handleChange} pada masukan
Tim KlarnaUI memiliki peretasan yang menarik untuk menangani masalah ini dengan mengeksploitasi acara onAnimationStart
dan kelas pseudo :-webkit-autofill
seperti yang dijelaskan dalam artikel ini - https://medium.com/@brunn/detecting -autofilled- field-in-javascript-aed598d25da7
Kami telah menggunakan retasan ini di aplikasi kami, ini berfungsi dengan baik (hanya dapat menguji di Chrome). Saya akan mencoba membuat shim menggunakan teknik ini sehingga menjadi generik.
Ada pembaruan tentang masalah ini?
up, apa trik terbaik untuk saat ini?
@ericflo @sophiebits
Masalah ini sepertinya masih berlanjut, ada pembaruan?
@Pixelatex @Aarbel lihat jawaban saya lebih jauh - https://github.com/facebook/react/issues/1159#issuecomment -371604044
Pada dasarnya React mendengarkan acara input
bukan change
satu untuk onChange, jadi jawaban itu hanya mendengarkan keduanya.
@DominicTobias Saya mencoba ini tetapi kami harus memiliki klik aktual di suatu tempat di halaman untuk membuat ini berfungsi. acara tidak terdaftar sampai saat itu.
Telah berjuang tentang masalah ini selama sekitar satu hari total sekarang. Saya pasti dapat membuat daftar apa yang TIDAK berfungsi di Desktop Chrome 67 dan React 15.6.0:
onAnimationStart
dengan input:-webkit-autofill
https://medium.com/@brunn/detecting -autofilled-fields-in-javascript-aed598d25da7 - aktif sebelum waktunya (formulir belum diisi)this.inputRef.addEventListener("transitionend", this.doSomething, false)
dalam kombinasi dengan input:-webkit-autofill
css transisi - aktif tepat waktu tetapi Anda tidak dapat membangunkan halaman, seperti yang disebutkan @Pixelatexthis.inputRef.addEventListener("change", this.doSomething)
- bahkan tidak menyala sampai Anda mengklik halamanonBlur={this.doSomething}
- tidak mengaktifkan acaraSekali lagi, sayangnya solusi ini TIDAK BEKERJA. HTML tidak berisi nilai isi otomatis kecuali Anda mencolek halaman. Yang paling dekat adalah 2 karena Anda dapat mengetik document
di konsol dan itu akan membangunkan halaman, dan sejauh ini secara terprogram ini tidak berhasil.
@DominicTobias Apakah solusi Anda berfungsi di Chrome Desktop?
Sebenarnya, saya memiliki peretasan yang kotor. Jika Anda menggunakan solusi 2 dari komentar sebelumnya, Anda dapat mengandalkan [di sinilah kekotoran] "Data Formulir Tersimpan adalah Data yang Valid". Kemudian Anda dapat melihat transisi setelah acara pengisian otomatis selesai dan mengaktifkan tombol Kirim, misalnya. Begini caranya:
css:
input:-webkit-autofill {
transition: background-color 0.1s ease-in-out 0s;
}
dalam konstruktor:
this.autofillCompleted = this.autofillCompleted.bind(this)
Di dalam kelas Komponen React Anda:
componentDidMount(){
if(this.myInputRef)
this.myInputRef.addEventListener("transitionend", this.autofillCompleted, false)
}
autofillCompleted(){
this.setState({ submitActive: true });
}
componentWillUnmount(){
if(this.myInputRef)
this.myInputRef.removeEventListener("transitionend", this.autofillCompleted, false)
}
Di dalam JSX:
<FormControl
inputRef={(node) => this.myInputRef= node}
/>
PS untuk komponen dasar (seperti input
), gunakan ref
prop daripada inputRef
Di desktop Chrome dan Safari iOS 12 terbaru, membungkus elemen dalam <form>
memang menyebabkan pelengkapan otomatis mengeluarkan acara onChange.
@rxb membungkus <p> </p>
?
@basarat maaf, lupa penurunan harga kode saya dan tag hilang ... <form>
tag
Ada pembaruan tentang masalah ini?
Ada pembaruan tentang masalah ini?
Jika ada pembaruan, mereka akan membahas masalah ini.
Harap jangan memposting jika Anda tidak memiliki sesuatu yang berarti untuk ditambahkan - Anda mengirim spam ke semua orang yang berlangganan masalah ini. Terima kasih.
Saya juga mengangkat masalah tentang ini dan pengembang yakin itu akan diperbaiki di 65 ... https://bugs.chromium.org/p/chromium/issues/detail?id=813175
Perbaikan ini sayangnya tidak dikoordinasikan dengan tim React. Kami tidak menyadari bahwa Chrome di iOS sekarang menyetel properti yang secara tidak sengaja memicu penangan perubahan di versi sebelumnya. Itu tidak disengaja di pihak kami untuk mendukung ini - dan kami telah membuat perubahan yang menghapus perilaku (kami tidak sadar Chrome mulai mengandalkannya).
Jika Anda bekerja di browser dan menambahkan peretasan khusus React, harap pastikan untuk menghubungi seseorang dari tim React.
Adakah yang bisa merebus ini menjadi bug saat ini . React menangani event KEDUA change
dan input
untuk input. Jika IsiOtomatis mengaktifkan salah satu fitur tersebut, maka fitur itu akan berfungsi. Jadi tidak jelas apakah masalah aslinya di sini masih relevan. ATAU ada beberapa hal di sini yang mungkin menjadi masalah berbeda
Apakah ada sesuatu yang saya lewatkan di sini, dan apakah ada yang tahu browser mana yang berfungsi atau tidak berfungsi dengan benar?
Ngomong-ngomong, kami ingin menganggap ini sebagai bagian dari # 9657 - idealnya apa pun yang kami lakukan di sana harus sebagian digunakan untuk membantu memecahkan masalah ini.
@jquense kami menggunakan nilai yang benar, tetapi kami tidak mengirim acara perubahan:
http://react-hydration.surge.sh/hydration
ok, saya juga telah melakukan sedikit riset:
Saya pikir ada dua masalah di sini:
berikut adalah situs yang dapat Anda gunakan untuk menguji: https://jquense.github.io/browser-test-pages/autofill/login/
Dari apa yang saya tahu, semua platform dan browser lain berfungsi dengan baik untuk memilih nilai yang diisi otomatis
perhatikan bahwa di atas adalah halaman gatsby jadi _also_ mendemonstrasikan masalah SSR
@nhunzaker Anda memiliki ide cerdas tentang kasus chrome IOS? sepertinya Vue punted https://github.com/vuejs/vue/issues/7058 juga
React tidak membuat pelengkapan otomatis mati
Saya telah mengajukan bug Chrome baru untuk masalah Chrome di iOS: https://bugs.chromium.org/p/chromium/issues/detail?id=895898
Sudahkah Anda mencoba menentukan atribut 'nama' untuk masukan? itu berhasil untuk saya. onChange dipicu pada IsiOtomatis pengguna
@eatsjobs Kami menggunakan nama attr, tetapi memiliki masalah yang sama.
Saya diuji
$$(':-webkit-autofill')
Bekerja pada chrome 70, mengembalikan input pengisian otomatis.
@QuantumInformation sama untuk saya :(
handleOnChange = e => {
this.setState({ email: e.target.value }, () => {
alert(this.state.email)
})
}
<form>
<input
name="email"
type="email"
placeholder="Enter Your Email"
autocomplete="email"
value={this.state.email}
onChange={e => this.handleOnChange(e)}
/>
</form>
Saya mencoba cara ini, sepertinya semuanya bekerja dengan baik.
IsiOtomatis menyetel status saya dengan benar. (ios 12)
Bagi mereka yang menemukan masalah ini baru-baru ini, ini disebabkan oleh browser secara sengaja untuk menghindari risiko keamanan.
Jika kami dapat mengakses nilai yang diisi otomatis setelah halaman dimuat, akan menjadi sangat mudah untuk menulis kode berbahaya untuk mengekstrak informasi pada formulir yang ditujukan untuk phishing. Memberi pengguna tidak ada kesempatan untuk bereaksi. Mungkin sebagian dari alasan mengapa autocomplete="off"
diabaikan oleh browser.
Untuk mengatasi masalah ini kita perlu:
Untuk mengatasi masalah ini, pikirkan kembali bagaimana formulir awalnya dirancang dan dimaksudkan untuk digunakan. Ketika pengguna mengklik <button type="submit" />
di dalam <form>
itu pada dasarnya mengatakan "hei tindakan ini dimaksudkan oleh pengguna, sekarang mari kita evaluasi nilai formulir".
Pertimbangkan contoh SignInForm yang sangat sederhana ini yang ditulis di React:
import React from 'react';
class SignInForm extends React.Component {
constructor() {
this.state = {
email: '',
password: '',
};
this.handleEmail = this.handleEmail.bind(this);
this.handlePassword = this.handlePassword.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleEmail(event) {
this.setState({ email: event.target.value });
}
handlePassword(event) {
this.setState({ password: event.target.value });
}
handleSubmit() {
console.log(this.state.email); // The email value
console.log(this.state.password); // The password value
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input
name="email"
type="text"
value={this.state.email}
onChange={this.handleEmail}
placeholder="Email"
/>
<input
name="password"
type="text"
value={this.state.password}
onChange={this.handlePassword}
placeholder="Password"
/>
<button type="submit" onClick={this.handleSubmit}>Sign In</button>
</form>
);
}
}
export default SignInForm;
Setelah diserahkan, formulir akan memperbarui dan mengevaluasi bidang masukan yang sesuai.
Ini berarti:
Menurut saya, ini adalah pendekatan yang paling pragmatis dan akan menghemat banyak sakit kepala. Saya harap ini membantu orang lain di masa depan.
Sunting: Bagi mereka yang tidak terbiasa dengan React, Anda dapat melihat tautan ini untuk implementasi dasar formulir dan beberapa info menarik tambahan: https://html.spec.whatwg.org/multipage/forms.html
Bagi mereka yang menemukan masalah ini baru-baru ini, ini disebabkan oleh browser secara sengaja untuk menghindari risiko keamanan.
Jika kami dapat mengakses nilai yang diisi otomatis setelah halaman dimuat, akan menjadi sangat mudah untuk menulis kode berbahaya untuk mengekstrak informasi pada formulir yang ditujukan untuk phishing. Memberi pengguna tidak ada kesempatan untuk bereaksi. Mungkin sebagian dari alasan mengapa
autocomplete="off"
diabaikan oleh browser.Untuk mengatasi masalah ini kita perlu:
- Terima fakta bahwa kami tidak akan (dan tidak akan pernah) memiliki akses ke nilai yang diisi otomatis saat node DOM dipasang
- Rangkul masalah keamanan yang dibawa oleh browser
Untuk mengatasi masalah ini, pikirkan kembali bagaimana formulir awalnya dirancang dan dimaksudkan untuk digunakan. Ketika pengguna mengklik
<button type="submit" />
di dalam<form>
itu pada dasarnya mengatakan "hei tindakan ini dimaksudkan oleh pengguna, sekarang mari kita evaluasi nilai formulir".Pertimbangkan contoh SignInForm yang sangat sederhana ini yang ditulis di React:
import React from 'react'; class SignInForm extends React.Component { constructor() { this.state = { email: '', password: '', }; this.handleEmail = this.handleEmail.bind(this); this.handlePassword = this.handlePassword.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleEmail(event) { this.setState({ email: event.target.value }); } handlePassword(event) { this.setState({ password: event.target.value }); } handleSubmit() { console.log(this.state.email); // The email value console.log(this.state.password); // The password value } render() { return ( <form onSubmit={this.handleSubmit}> <input name="email" type="text" value={this.state.email} onChange={this.handleEmail} placeholder="Email" /> <input name="password" type="text" value={this.state.password} onChange={this.handlePassword} placeholder="Password" /> <button type="submit" onClick={this.handleSubmit}>Sign In</button> </form> ); } } export default SignInForm;
Setelah diserahkan, formulir akan memperbarui dan mengevaluasi bidang masukan yang sesuai.
Ini berarti:
- Kami tidak dapat menonaktifkan tombol kirim sama sekali
- Semua validasi harus terjadi setelah pengguna mengklik tombol ini
Menurut saya, ini adalah pendekatan yang paling pragmatis dan akan menghemat banyak sakit kepala. Saya harap ini membantu orang lain di masa depan.
Sunting: Bagi mereka yang tidak terbiasa dengan React, Anda dapat melihat tautan ini untuk implementasi dasar formulir dan beberapa info menarik tambahan: https://html.spec.whatwg.org/multipage/forms.html
Terima kasih atas ringkasannya, namun saya benar-benar bingung. Anda mengatakan bahwa ketika kami mengirimkan formulir, itu akan "diperbarui sesuai". Apakah ini berarti ini akan mengaktifkan peristiwa perubahan tambahan untuk setiap bidang yang diisi secara otomatis sebelum mengaktifkan peristiwa pengiriman? Atau apakah itu berarti bahwa ketika event submit diaktifkan, nilainya sekarang dapat dibaca melalui referensi? Jika yang pertama, kami dapat membuat komponen seperti yang Anda tunjukkan di cuplikan. Jika itu yang terakhir maka kita perlu mengadopsi pendekatan berbasis referensi untuk formulir yang bergerak maju.
@thomasjulianstoelen Apa maksud Anda?
@bayu_joo
Dalam pengalaman saya (dengan chrome, setidaknya), telah memperbarui bidang pada interaksi pertama pengguna dengan halaman (klik, pengiriman formulir, dll), dan telah mengirimkan peristiwa dengan perubahan, memungkinkan variabel model untuk diperbarui. Saya belum menguji browser lain.
Anda dapat menyetel atribut autocomplete = "off" (HTML5), atau mencatat nilai masukan dalam hash url.
Gali lebih dalam masalah ini: Chromium membuat perubahan untuk mengeluarkan peristiwa asli "perubahan" dan "masukan" berdasarkan laporan bug ini: https://bugs.chromium.org/p/chromium/issues/detail?id= 813175. Namun, untuk beberapa alasan, React masih tidak memicu event onChange
sebagai respon dari salah satu event native ini. Ini mungkin terkait dengan logika deduplikasi React (https://github.com/facebook/react/issues/10135) atau fakta bahwa peristiwa yang dipancarkan secara terprogram oleh Chrome di iOS membawa bendera isTrusted=false
.
Bisakah seseorang dari tim React melihat lebih dalam ke event handler React onChange
untuk mencari tahu mengapa event tidak dipicu? @gaearon atau @zpao (tebakan acak)?
Sementara itu, saya menggunakan peristiwa onInput
, yang mendengarkan peristiwa "input" asli secara langsung.
Saya pikir ini adalah komit di Chrome yang merusak perilaku:
Ini menghapus tanda simulated
dari peristiwa perubahan, yang mungkin menyebabkan logika dedupe mengabaikan peristiwa ini.
@nfiacco yang commitnya dari tahun 2018, terbitan ini dibuka tahun 2014, jadi di permukaan itu tidak bertambah ... Kecuali jika penyebabnya sekarang berbeda dengan saat terbitan pertama kali?
Saya kembali dari 2022
Komentar yang paling membantu
Sudahkah Anda mencoba menentukan atribut 'nama' untuk masukan? itu berhasil untuk saya. onChange dipicu pada IsiOtomatis pengguna