Wenn es eine kontrollierte Komponente für Formularnamen gibt, die der Benutzer in seinem Browser gespeichert hat (wie bei Benutzernamen- / Kennwortfeldern üblich), rendert der Browser die Seite manchmal mit Werten in diesen Feldern, ohne onChange-Ereignisse auszulösen. Wenn der Benutzer das Formular sendet, spiegelt der Komponentenstatus nicht wider, was dem Benutzer angezeigt wird.
Beim Experimentieren scheint es, dass die Daten beim Laden vorhanden sind (getestet durch Protokollieren des Wertes this.refs.myinput.getDOMNode ().)
Dies scheint etwas mehr zu diskutieren: http://stackoverflow.com/a/11710295
atm Ich benutze diese https://github.com/tbosch/autofill-event
cc mich
( @visionscaper Tipp: Drücken Sie in der rechten Spalte auf "Abonnieren".)
Irgendwelche Updates oder empfohlenen Best Practices zu diesem Thema? Die Polyfill für das automatische Ausfüllen von Ereignissen scheint eine Vorschlaghammerlösung zu sein.
Safari (8) löst Änderungsereignisse beim automatischen Ausfüllen aus, sprudelt jedoch nicht, sodass sie den Reaktionshandler nicht erreichen.
Eine verwandte Diskussion unter https://github.com/angular/angular.js/issues/1460 wurde mit einigen Vorschlägen abgeschlossen, von denen einer https://github.com/tbosch/autofill-event zum Feuern verwendet Ändern Sie das Ereignis beim automatischen Ausfüllen manuell.
Ich denke, wir können auch hier schließen.
Es wäre schön, das AutoFill-Event als Teil von React als Addon zu haben. Diese Funktionalität wird für praktisch jeden erforderlich sein, der React zur Formularvalidierung verwendet. Das AutoFill-Event-Skript fügt außerdem eine Abhängigkeit für jQuery hinzu, die in vielen Fällen unerwünscht sein kann.
Dies ist ein Browser-Fehler, der alle Browser etwas anders betrifft. Ich denke, nur weil Winkel beim Versuch, herumzuarbeiten oder zu reparieren, nicht bedeutet, dass man reagieren sollte. Es ist eine häufige Sache, aber ich verstehe, ob dies ein "Wontfix" ist.
Ich bin nicht besonders gut mit den Bug-Trackern der verschiedenen Browser vertraut, aber es wäre schön, wenn jemand, der dies tut, Probleme dafür finden oder öffnen könnte. Ich denke, das Reaktionsteam hat mehr Gewicht als die meisten Benutzer, wenn sie ein Problem damit eröffnen. Und wir könnten hier die Tickets für die interessierten Reaktionsentwickler abholen.
Ich holte den eckigen Faden ein. Firefox hat Probleme mit Passwortfeldern (https://bugzilla.mozilla.org/show_bug.cgi?id=950510 ist noch offen), kein Wort zu Safari's Bug #, Chrome ist behoben.
An einigen Stellen werden bereits Probleme verfolgt - https://github.com/angular/angular.js/issues/1460#issuecomment -53947546
Das Chrome-Problem ist jetzt geschlossen, funktioniert aber in Chrome 50 mit React 0.14.8 eindeutig nicht.
Noch kein Fix?
Ich habe das Gefühl, dass dies eine Weile funktioniert hat und vor kurzem wieder kaputt gegangen ist?
Gibt es ein Update zu diesem Thema?
Hier ein Auszug meiner Lösung für dieses Problem:
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}
/>
);
}
}
HINWEIS: value
stammt aus dem Status und onFieldChange
aktualisiert den Status mit dem neuen Wert
Der setInterval-Code stammt von https://github.com/Pephers/react-autofill
Kann jemand bestätigen, dass dieses Problem mit iOS 10.2 behoben wurde? Ich kann es jetzt nicht reproduzieren ...
Ich habe immer noch Probleme unter iOS 10.2 mit Chrome Version 55.0.2883.79 ... Im Gegensatz zu dem, was oben beschrieben wurde, blinkt der automatisch ausgefüllte Inhalt für mich kurz im Formular und wird dann wieder entfernt.
Es stimmt also jetzt mit dem überein, was im Status gespeichert ist. Das automatische Ausfüllen funktioniert jedoch immer noch nicht ...
Ich reproduziere das gleiche Problem, auf das @irisSchaffer gestoßen ist. Ich habe eine isomorphe Anwendung, in der ich eine statische Seite mit Reagieren und Ausdrücken rendere. Dann exportiere ich auf dem Client die Requisiten und verwende dieselbe Seitenkomponente.
Selbst wenn der Kennworteingabewert nicht durch "Reagieren" behandelt wird, löscht die Client-Reaktionskomponente das gespeicherte Kennwort aus der Eingabe, auch wenn Chrome es kurz anzeigt. Wenn ich Javascript im Browser deaktiviere, bleibt das gespeicherte Passwort an seiner Stelle.
Dieses Problem ist nur in Chrome mit der letzten Version 58 sichtbar.
Das gespeicherte Passwort ist über element.value nicht zugänglich, bis ein Ereignis auf dem Dom ausgelöst wird, z. B. der Fokus, ein Schlüsselereignis usw. Es wurde versucht, ein Ereignis durch Javascript zu simulieren, ohne dass der Wert ausgefüllt werden muss Eigentum.
+1. irgendwelche Fixes oder Hacks?
Ich bin immer noch mit diesem Problem unter iOS 10.3.3 Chrome 60.0.3112.89 konfrontiert.
Das automatische Ausfüllen funktioniert, füllt das Feld, ändert aber nicht den Status.
Umgehung des Dekorateurs: https://github.com/Pephers/react-autofill
Allgemeine Komponentenumgehung:
/**
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 für iOS (stellen Sie sicher, dass Sie mit dem automatischen Ausfüllen von Chrome testen und nicht mit den Vorschlägen der iOS-Tastatur) gibt nur beim automatischen Ausfüllen von Werten change
. Mobile Safari hingegen gibt focus
, keydown
, input
, keyup
, change
und blur
aus macht Chrome und Safari auf Mac.
React verwendet kein change
-Ereignis für reguläre <input />
was die Hauptursache für dieses Problem zu sein scheint: https://github.com/facebook/react/blob/e932ad68bed656eed5295b61ba74e5d0857902ed/src/renderers /dom/shared/eventPlugins/ChangeEventPlugin.js#L66 -L71
Wäre es nicht möglich, dass React onChange
auch bei DOM change
-Ereignissen ausgelöst wird? Würde das schaden?
Zugehöriges Problem für Chrome iOS: https://bugs.chromium.org/p/chromium/issues/detail?id=705275
Ich habe das automatische Ausfüllen und Ereignisse mit der folgenden kleinen Seite getestet:
<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>
Das Änderungsereignis wird in Chrome v62 ausgegeben, wenn Sie Eingaben mit einem <form />
-Element umschließen.
Es gibt einen onInput-Ereignishandler, der den Wert eines Eingabefelds abruft, wenn er sich ändert.
Hier wird immer noch ein ungewöhnliches Verhalten beim automatischen Ausfüllen unter iOS festgestellt. Der obige Dekorator für das automatische Ausfüllen von Reaktionen scheint mit dem einfachen automatischen Ausfüllen gut zu funktionieren, nicht jedoch mit den von der Tastatur bereitgestellten Verknüpfungen zum automatischen Ausfüllen.
Dies sollte jetzt in Chrome für iOS behoben sein: https://chromium.googlesource.com/chromium/src/+/55518e17850cac0bdc6fca7b24092bea479e34db. Ich bin mir nicht sicher, wann dieser Patch in einer veröffentlichten Version enthalten sein wird.
Warum muss onChange verwendet werden?
Warum MÜSSEN wir 'onChange' verwenden, aber nicht das '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>
)
}
}
Das Änderungsereignis wird in Chrome v62 ausgegeben, wenn Sie Eingaben mit einem
<form />
-Element umschließen.
Ich bestätige, dass diese Lösung für Chrome zum automatischen Ausfüllen von Telefonnummern über autoComplete="tel"
funktioniert
https://github.com/catamphetamine/react-phone-number-input/issues/101
Die oben genannten Lösungen mit this._previousValue !== this.input.value
funktionieren leider nur für iOS Safari. Das .value
iOS Chrome ist nach dem automatischen Ausfüllen noch leer.
Ich habe keine Ahnung, wie Leute mit dem automatischen Ausfüllen von Formularen umgegangen sind, wenn sie kontrollierte Komponenten verwendet haben. Betrachten Sie dieses Anmeldeszenario:
.value
als leer gemeldetSofern es keine Möglichkeit gibt, Chrome dazu zu bringen, den Wert zu melden, kann ich mir keine andere Lösung vorstellen als die Verwendung unkontrollierter Komponenten, die Validierung von HTML5-Eingaben und das Abrufen von Formularwerten beim Senden wie früher.
Sie können das Problem hier verfolgen (und markieren): https://bugs.chromium.org/p/chromium/issues/detail?id=813175
Ich konnte die obige Lösung auch nicht für @DominicTobias verwenden. Es gibt mehrere Ebenen von Problemen. Das erste war, dass this.input.value
immer leer zurückkam. Ich habe jedoch festgestellt, dass Sie einen Wert zurückerhalten, wenn Sie in jeder Schleife document.getElementById
, dann document.getElementById(id).value
.
Dies löst das dispatchEvent
-Problem nicht, aber zumindest können Sie den automatisch ausgefüllten Wert abrufen und damit arbeiten (z. B. nur den onChange
-Handler einer kontrollierten Eingabe aufrufen).
@wlingke gut zu wissen (und wie seltsam)! Ich muss auch diesen Weg gehen, wenn sie den Fehler nicht rechtzeitig vor meiner Veröffentlichung beheben
@wlingke Als ich eine Demo für die Chrome-Leute onChange
ist ein synthetisches Ereignis in React, bei dem das Ereignis change
, was mir ziemlich seltsam erscheint.
Sie können sogar in der Demo unten sehen, dass es sich anders verhält, eher so, als würde es auf ein input
-Ereignis warten. Wenn Sie das echte change
-Ereignis verwenden, funktioniert es in iOS Chrome ordnungsgemäß.
Daher würde ich vorschlagen, einen Verweis auf das Element zu erhalten und nur das eigentliche Änderungsereignis sowie das onChange
-Ereignis anzuhören, das das input
-Ereignis zu sein scheint, wenn Sie den Status als das aktualisieren müssen Benutzer tippt.
@DominicTobias Ich habe zuvor sowohl change
als auch input
Ereignisse einzeln sowie beide gleichzeitig in diesem Dekorateur ausprobiert, konnte es aber in meiner App nicht zum Laufen bringen.
Ich bin mir auch nicht sicher, ob sich dadurch etwas ändert. Aber es gibt einen Unterschied zwischen dem automatischen Ausfüllen eines Feldes und dem automatischen Ausfüllen mehrerer Felder. Das input
-Ereignis funktionierte einwandfrei, wenn ein Feld automatisch ausgefüllt wurde. In Mobile Chrome können Sie jedoch eine Reihe von Feldern gleichzeitig automatisch über die Tastatur ausfüllen (z. B. Vorname, Nachname, E-Mail-Adresse mit einem Fingertipp).
In diesem zweiten Szenario lässt der Dekorateur das erste Feld ordnungsgemäß automatisch ausfüllen (erstes Feld bedeutet das Feld, das derzeit scharfgestellt ist). Der Dekorateur (der an alle drei Felder angehängt ist) scheint jedoch nicht an den anderen Feldern zu arbeiten.
@wlingke Interessant, ich habe einige weitere Felder hinzugefügt, aber wenn ich alle drei Felder gleichzeitig in iOS Chrome automatisch
(Der Screenshot stammt vom Desktop-Browser, aber ich erhalte auf meinem Telefon das gleiche Ergebnis.)
@DominicTobias Ich denke, wenn Sie das input
-Ereignis verwenden - was ich zuvor verwendet habe, funktioniert es vollständig in Desktop. Und arbeiten Sie für die erste Eingabe in Mobile.
input
Ereignis ist dem onChange
Reaktion am nächsten. Das change
-Ereignis wird nur dann gespeichert, wenn ein Element nach meinem Verständnis den Fokus verliert (https://stackoverflow.com/questions/17047497/what-is-the-difference-between-change-and-input-event-). für ein Eingabeelement)
Yep react hat aus irgendeinem Grund onChange to input
event: https://stackoverflow.com/questions/38256332/in-react-whats-the-difference-between-onchange-and-oninput
Um die Dinge einfach zu halten, nenne ich es einfach auch in meiner Input
-Komponente für tatsächliche Änderungsereignisse (sowie die normalen Eingabeereignisse). Jetzt funktioniert es in iOS Chrome. Probieren Sie es aus und lassen Sie es mich wissen!
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);
}
Bearbeiten: Chrome soll in v65 behoben sein, aber die Leute berichten, dass es immer noch nicht funktioniert: /
Danke für die Erklärung Dominic. Wir haben dieses Verhalten bereits im Dezember behoben. Wir lösen jetzt Keydown-, Änderungs-, Eingabe- und Keyup-Ereignisse aus.
https://chromium-review.googlesource.com/c/chromium/src/+/771674Wir hatten auch eine Lösung für React.
https://chromium-review.googlesource.com/c/chromium/src/+/844324Dies behebt zwar das Verhalten beim automatischen Ausfüllen, ruft jedoch den onChange-Handler nicht auf.
Ich habe auch ein Problem dazu angesprochen und der Entwickler war sich sicher, dass es in 65 behoben werden würde ... https://bugs.chromium.org/p/chromium/issues/detail?id=813175
Ich höre auch das native change
-Ereignis wie onChange
redux-form im nativen Ereignis-Listener aus, der an mount angehängt ist.
Ich benutze auch den input:-webkit-autofill
Selektor für das Styling.
Überzeugen Sie sich selbst unter https://labrewlangerie.com (Kontaktformular).
Scheint, als ob dieses Update endlich auf dem Weg zu Chrome iOS ist! Ich bin mir jedoch nicht sicher, in welcher Version, da diese am 1. Dezember zusammengeführt worden zu sein scheint.
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
es sollte schon im neuesten chrom sein. Ich stehe immer noch vor diesem Problem (Winkel 5).
Gleiches hier in Chrome 65, Reagieren Sie 15.6.
Das ist eine Schande, Mahmadi sagte, dass es am 13. März auf v65 gehen würde :(
Kommentar 15 von [email protected] , 9. März
Das Update ist nicht in Chrome 64. Mein schlechtes. Chrome 65 muss (wird ab dem 13. März eingeführt). Ich habe gerade Ihre Demo-Website für native Ereignisse getestet und sie funktioniert unter Chrome 65. Ich freue mich, dass Sie dies weiterverfolgen.
https://bugs.chromium.org/p/chromium/issues/detail?id=813175
Versuchen Sie, hier auf Ihrem Telefon zu gehen und zu überprüfen: https://kind-stallman-f3c045.netlify.com/native.html
Was wirklich seltsam ist, ist, dass es in v65 nativ funktioniert, aber obwohl es eine Eingabe erhält, wird es in React nicht empfangen! Benötigen Sie weitere Untersuchungen? Ich bin mir nicht ganz sicher, wie der Handler reagiert (oder ob er auf dem Dokumentelement ausgeführt wird, wie z. B. ein Klick-Handler).
Nativ kann ich sehen, dass das Eingabeereignis jetzt stattfindet (https://kind-stallman-f3c045.netlify.com/native.html):
Aber irgendwie erhält React keines dieser Ereignisse (https://kind-stallman-f3c045.netlify.com):
add onBlur = {this.handleChange} bei der Eingabe
Das KlarnaUI-Team hat einen interessanten Hack, um dieses Problem zu lösen, indem es das onAnimationStart
-Ereignis und die :-webkit-autofill
-Pseudoklasse ausnutzt, wie in diesem Artikel beschrieben - https://medium.com/@brunn/detecting -autofilled- Felder-in-Javascript-aed598d25da7
Wir haben diesen Hack in unseren Anwendungen verwendet, er funktioniert einwandfrei (konnte nur auf Chrome getestet werden). Ich werde versuchen, mit dieser Technik eine Unterlegscheibe zu entwickeln, damit sie generisch ist.
Irgendwelche Updates zu diesem Problem?
Was ist der beste Trick für den Moment?
@ericflo @sophiebits
Dieses Problem scheint immer noch zu bestehen, irgendwelche Updates?
@Pixelatex @Aarbel siehe meine Antwort etwas weiter oben - https://github.com/facebook/react/issues/1159#issuecomment -371604044
Grundsätzlich lauscht React auf das input
-Ereignis und nicht auf das change
one-Ereignis für onChange, sodass diese Antwort nur auf beide hört.
@DominicTobias Ich habe es versucht, aber wir müssen irgendwo auf der Seite einen tatsächlichen Klick haben, damit dies funktioniert. Die Veranstaltung wird bis dahin nicht registriert.
Ich habe jetzt seit ungefähr einem Tag mit dem Thema zu kämpfen. Ich kann definitiv auflisten, was in Desktop Chrome 67 und React 15.6.0 NICHT funktioniert:
onAnimationStart
mit input:-webkit-autofill
https://medium.com/@brunn/detecting -autofilled-fields-in-javascript-aed598d25da7 - wird vorzeitig ausgelöst (das Formular ist noch nicht ausgefüllt)this.inputRef.addEventListener("transitionend", this.doSomething, false)
in Kombination mit input:-webkit-autofill
css-Übergang - wird pünktlich ausgelöst, aber Sie können die Seite nicht @Pixelatex erwähnt hatthis.inputRef.addEventListener("change", this.doSomething)
- wird erst ausgelöst, wenn Sie auf die Seite klickenonBlur={this.doSomething}
- löst kein Ereignis ausAuch diese Lösungen funktionieren leider NICHT. Der HTML-Code enthält den automatisch ausgefüllten Wert nur, wenn Sie die Seite anstoßen. Die nächstgelegene ist 2, da Sie document
in die Konsole eingeben können und die Seite aktiviert wird. Bisher hat dies programmgesteuert nicht funktioniert.
@DominicTobias Funktioniert Ihre Lösung auf Desktop Chrome?
Eigentlich habe ich einen dreckigen Hack. Wenn Sie Lösung 2 aus dem vorherigen Kommentar verwenden, können Sie sich auf [hier kommt Schmutzigkeit] "Gespeicherte Formulardaten sind gültige Daten" verlassen. Anschließend können Sie den Übergang nach Abschluss des Ereignisses zum automatischen Ausfüllen abfangen und beispielsweise die Schaltfläche Senden aktivieren. Hier ist wie:
CSS:
input:-webkit-autofill {
transition: background-color 0.1s ease-in-out 0s;
}
im Konstruktor:
this.autofillCompleted = this.autofillCompleted.bind(this)
Innerhalb Ihrer React Component-Klasse:
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)
}
In JSX:
<FormControl
inputRef={(node) => this.myInputRef= node}
/>
PS: Verwenden Sie für grundlegende Komponenten (wie input
) ref
prop anstelle von inputRef
In der neuesten Chrome Desktop- und iOS 12-Safari führt das Umschließen von Elementen in <form>
, dass die automatische Vervollständigung ein onChange-Ereignis auslöst.
@rxb in <p> </p>
einwickeln?
@basarat Entschuldigung, ich habe meinen Code-Markdown vergessen und das Tag ist verschwunden ... <form>
tag
Gibt es ein Update zu diesem Thema?
Gibt es ein Update zu diesem Thema?
Wenn es Updates gäbe, wären sie zu diesem Thema.
Bitte posten Sie nicht, wenn Sie nichts Sinnvolles hinzuzufügen haben - Sie spammen jeden, der dieses Problem abonniert hat. Vielen Dank.
Ich habe auch ein Problem dazu angesprochen und der Entwickler war sich sicher, dass es in 65 behoben werden würde ... https://bugs.chromium.org/p/chromium/issues/detail?id=813175
Dieser Fix wurde leider nicht mit dem React-Team koordiniert. Uns war nicht bekannt, dass Chrome unter iOS jetzt eine Eigenschaft festlegt, die in früheren Versionen versehentlich den Änderungshandler ausgelöst hat. Wir hatten nicht die Absicht, dies zu unterstützen - und wir haben bereits eine Änderung vorgenommen, durch die das Verhalten beseitigt wurde (wir waren uns nicht bewusst, dass Chrome sich darauf verlassen hat).
Wenn Sie an einem Browser arbeiten und einen reaktionsspezifischen Hack hinzufügen, stellen Sie sicher, dass Sie jemanden aus dem React-Team einschleifen.
Kann jemand dies auf den aktuellen Fehler reduzieren. React behandelt BEIDE change
und input
Ereignisse für Eingaben. Wenn das automatische Ausfüllen eines der beiden auslöst, sollte es funktionieren. Es ist also nicht klar, dass das ursprüngliche Problem hier immer noch relevant ist. ODER es gibt hier einige Dinge, die unterschiedliche Probleme haben können
Gibt es etwas, das ich hier verpasst habe, und weiß jemand, welche Browser sich richtig verhalten oder nicht?
Übrigens wollen wir dies als Teil von # 9657 betrachten - idealerweise sollte alles, was wir dort tun, teilweise dazu beitragen, dieses Problem zu lösen.
@jquense Wir verwenden den richtigen Wert, senden jedoch kein Änderungsereignis:
http://react-hydration.surge.sh/hydration
ok, ich habe auch ein bisschen recherchiert:
Ich denke, hier gibt es zwei Probleme:
Hier ist eine Site, die Sie zum Testen verwenden können: https://jquense.github.io/browser-test-pages/autofill/login/
Soweit ich weiß, funktionieren alle anderen Plattformen und Browser einwandfrei für die Auswahl automatisch ausgefüllter Werte
Beachten Sie, dass es sich bei der obigen Seite um eine Gatsby-Seite handelt, sodass auch das SSR-Problem demonstriert wird
@nhunzaker Sie haben clevere Ideen zum IOS- https://github.com/vuejs/vue/issues/7058 gestoßen
React macht die automatische Vervollständigung nicht deaktiviert
Ich habe einen neuen Chrome-Fehler für das Chrome unter iOS-Problem gemeldet :
Haben Sie versucht, das Attribut 'name' für die Eingabe zu definieren? Für mich geht das. Der onChange wird beim automatischen Ausfüllen des Benutzers ausgelöst
@eatsjobs Wir verwenden attr name, haben aber das gleiche Problem.
Ich habe getestet
$$(':-webkit-autofill')
Funktioniert auf Chrome 70 und gibt automatisch ausgefüllte Eingänge zurück.
@QuantumInformation für mich gleich :(
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>
Ich versuche es so, sehe aus, als würde alles gut funktionieren.
Beim automatischen Ausfüllen wurde mein Status korrekt eingestellt. (ios 12)
Für diejenigen, die kürzlich auf dieses Problem gestoßen sind, wird es absichtlich von Browsern verursacht, um Sicherheitsrisiken zu vermeiden.
Wenn wir nach dem Laden der Seite auf automatisch ausgefüllte Werte zugreifen können, ist es sehr einfach, schädlichen Code zu schreiben, um Informationen in ein für Phishing bestimmtes Formular zu extrahieren. Geben Sie dem Benutzer keine Chance zu reagieren. Wahrscheinlich ein Teil des Grundes, warum autocomplete="off"
von Browsern ignoriert wird.
Um dieses Problem zu lösen, müssen wir:
Um dieses Problem zu lösen, denken Sie daran, wie Formulare ursprünglich entworfen wurden und verwendet werden sollen. Wenn der Benutzer auf ein <button type="submit" />
in einem <form>
klickt, heißt es im Grunde "Hey, diese Aktion ist vom Benutzer beabsichtigt, jetzt wollen wir die Formularwerte auswerten".
Betrachten Sie dieses Beispiel einer wirklich einfachen SignInForm, die in React geschrieben wurde:
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;
Nach dem Absenden aktualisiert und bewertet das Formular die Eingabefelder entsprechend.
Das heisst:
Meiner Meinung nach ist dies der pragmatischste Ansatz und erspart viel Kopfschmerzen. Ich hoffe, das hilft anderen in Zukunft.
Bearbeiten: Für diejenigen, die mit React nicht vertraut sind, können Sie unter diesem Link eine grundlegende Implementierung eines Formulars und einige zusätzliche wichtige Informationen finden: https://html.spec.whatwg.org/multipage/forms.html
Für diejenigen, die kürzlich auf dieses Problem gestoßen sind, wird es absichtlich von Browsern verursacht, um Sicherheitsrisiken zu vermeiden.
Wenn wir nach dem Laden der Seite auf automatisch ausgefüllte Werte zugreifen können, ist es sehr einfach, schädlichen Code zu schreiben, um Informationen in ein für Phishing bestimmtes Formular zu extrahieren. Geben Sie dem Benutzer keine Chance zu reagieren. Wahrscheinlich ein Teil des Grundes, warum
autocomplete="off"
von Browsern ignoriert wird.Um dieses Problem zu lösen, müssen wir:
- Akzeptieren Sie die Tatsache, dass wir beim Bereitstellen des DOM-Knotens keinen Zugriff auf automatisch ausgefüllte Werte haben (und dies auch nie tun werden)
- Umfassen Sie die Sicherheitsbedenken, die von den Browsern aufgeworfen werden
Um dieses Problem zu lösen, denken Sie daran, wie Formulare ursprünglich entworfen wurden und verwendet werden sollen. Wenn der Benutzer auf ein
<button type="submit" />
in einem<form>
klickt, heißt es im Grunde "Hey, diese Aktion ist vom Benutzer beabsichtigt, jetzt wollen wir die Formularwerte auswerten".Betrachten Sie dieses Beispiel einer wirklich einfachen SignInForm, die in React geschrieben wurde:
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;
Nach dem Absenden aktualisiert und bewertet das Formular die Eingabefelder entsprechend.
Das heisst:
- Wir können die Schaltfläche "Senden" überhaupt nicht deaktivieren
- Die gesamte Validierung muss erfolgen, sobald der Benutzer auf diese Schaltfläche klickt
Meiner Meinung nach ist dies der pragmatischste Ansatz und erspart viel Kopfschmerzen. Ich hoffe, das hilft anderen in Zukunft.
Bearbeiten: Für diejenigen, die mit React nicht vertraut sind, können Sie unter diesem Link eine grundlegende Implementierung eines Formulars und einige zusätzliche wichtige Informationen finden: https://html.spec.whatwg.org/multipage/forms.html
Vielen Dank für die Zusammenfassung, aber ich bin gründlich verwirrt. Sie sagen, wenn wir ein Formular senden, wird es "entsprechend aktualisiert". Bedeutet dies, dass zusätzliche Änderungsereignisse für jedes Feld ausgelöst werden, das automatisch ausgefüllt wird, bevor das Übermittlungsereignis ausgelöst wird? Oder bedeutet dies, dass die Werte beim Auslösen des Submit-Ereignisses jetzt über Refs lesbar sind? Wenn es das erstere ist, können wir Komponenten erstellen, wie Sie sie im Snippet gezeigt haben. Wenn es das letztere ist, müssen wir einen ref-basierten Ansatz für Formulare verfolgen, die sich weiterentwickeln.
@thomasjulianstoelen Was hast du gemeint?
@ Woodwardgb
Nach meiner Erfahrung (zumindest mit Chrome) wurden die Felder bei der ersten Interaktion des Benutzers mit der Seite (Klicks, Formularübermittlungen usw.) aktualisiert und Ereignisse mit der Änderung übermittelt, sodass die Modellvariablen aktualisiert werden konnten. Ich habe jedoch noch keine anderen Browser getestet.
Sie können das Attribut autocomplete = "off" (HTML5) setzen oder den Eingabewert im URL-Hash aufzeichnen.
Wir haben uns ein bisschen mehr mit diesem Problem befasst: Chromium hat eine Änderung vorgenommen, um sowohl native "Änderungs-" als auch "Eingabe" -Ereignisse basierend auf diesem Fehlerbericht auszugeben: https://bugs.chromium.org/p/chromium/issues/detail?id= 813175. Aus irgendeinem Grund löst React jedoch immer noch nicht das Ereignis onChange
als Reaktion auf eines dieser nativen Ereignisse aus. Dies hängt wahrscheinlich entweder mit der Deduplizierungslogik von React (https://github.com/facebook/react/issues/10135) oder mit der Tatsache zusammen, dass Ereignisse, die von Chrome unter iOS programmgesteuert ausgegeben werden, das Flag isTrusted=false
.
Kann jemand aus dem React-Team einen genaueren Blick auf den React onChange
-Event-Handler werfen, um herauszufinden, warum das Ereignis nicht ausgelöst wird? @gaearon oder @zpao (zufällige Vermutungen)?
In der Zwischenzeit verwende ich das onInput
-Ereignis, das direkt auf das native "Eingabe" -Ereignis wartet.
Ich denke, dies ist das Commit in Chrome, das das Verhalten gebrochen hat:
Dadurch wird das Flag simulated
aus dem Änderungsereignis entfernt, wodurch die Deduplizierungslogik diese Ereignisse wahrscheinlich ignoriert.
@nfiacco , das Commit stammt aus dem Jahr 2018, diese Ausgabe wurde 2014 eröffnet, also auf den ersten summiert ... Es sei denn, die Ursache unterscheidet sich jetzt von der, als die Ausgabe ursprünglich geöffnet wurde?
Ich kam von 2022 zurück
Hilfreichster Kommentar
Haben Sie versucht, das Attribut 'name' für die Eingabe zu definieren? Für mich geht das. Der onChange wird beim automatischen Ausfüllen des Benutzers ausgelöst