ãŠãŒã¶ãŒããã©ãŠã¶ãŒã«ä¿åãããã©ãŒã åã®å¶åŸ¡ãããã³ã³ããŒãã³ãïŒãŠãŒã¶ãŒå/ãã¹ã¯ãŒããã£ãŒã«ããšå ±éïŒãããå Žåããã©ãŠã¶ãŒã¯ãonChangeã€ãã³ããçºçãããã«ããããã®ãã£ãŒã«ãã®å€ã§ããŒãžãã¬ã³ããªã³ã°ããããšããããŸãã ãŠãŒã¶ãŒããã©ãŒã ãéä¿¡ããå Žåãã³ã³ããŒãã³ãã®ç¶æ ã¯ãŠãŒã¶ãŒã«è¡šç€ºãããŠããå 容ãåæ ããŠããŸããã
ãããå®éšãããšãããŒã¿ã¯ããŒãæã«ååšããããã«èŠããŸãïŒthis.refs.myinput.getDOMNodeïŒïŒãvalueããã°ã«èšé²ããŠãã¹ãæžã¿ïŒ
ããã¯ããå°ããããè°è«ããŠããããã§ãïŒ http ïŒ
atmç§ã¯ããã䜿çšããŠããŸãhttps://github.com/tbosch/autofill-event
cc me
ïŒ @visionscaperã®ãã³ãïŒå³åŽã®åã®[賌èª]ãæŒããŠãã ãããïŒ
ããã«é¢ããæŽæ°ãŸãã¯ææ¡ããããã¹ããã©ã¯ãã£ã¹ã¯ãããŸããïŒ èªåå ¥åã€ãã³ãã®ããªãã£ã«ã¯ãã¹ã¬ããžãã³ããŒãœãªã¥ãŒã·ã§ã³ã®ããã§ãã
SafariïŒ8ïŒã¯ãèªåå ¥åæã«å€æŽã€ãã³ãããã£ã¹ãããããŸãããããã«ããªããããreactãã³ãã©ãŒã«å°éããŸããã
https://github.com/angular/angular.js/issues/1460ã§ã®é¢é£ãããã£ã¹ã«ãã·ã§ã³ã¯çµäºããããã€ãã®ææ¡ããããŸããããã®ãã¡ã®1ã€ã¯ã httpsïŒ//github.com/tbosch/autofill-eventã䜿çšããŠãŸããèªåå ¥åã®ã€ãã³ããæåã§å€æŽããŸãã
ããã§ãéããããšãã§ãããšæããŸãã
ã¢ããªã³ãšããŠå¯èœãªãReactã®äžéšãšããŠautofill-eventããããšäŸ¿å©ã§ãã ãã®æ©èœã¯ããã©ãŒã ã®æ€èšŒã«Reactã䜿çšããã»ãŒãã¹ãŠã®äººã«å¿ èŠã«ãªããŸãã autofill-eventã¹ã¯ãªããã¯ãjQueryã®äŸåé¢ä¿ãè¿œå ããŸãããããã¯å€ãã®å ŽåæãŸãããªãå ŽåããããŸãã
ããã¯ããã¹ãŠã®ãã©ãŠã¶ã«å°ãç°ãªã圱é¿ãäžãããã©ãŠã¶ã®ãã°ã§ãã åé¿ãããä¿®æ£ãããããããšããŠè§åºŠããã³ããããããšãã£ãŠãåå¿ããå¿ èŠããããšã¯éããŸããã ããã¯ããããããšã§ãããããããäžåãã§ãããã©ããã¯ç解ããŠããŸãã
ç§ã¯ããŸããŸãªãã©ãŠã¶ã®ãã°ãã©ãã«ãŒã«ããŸã粟éããŠããŸãããããã®åé¡ãèŠã€ãããéãããã§ãã人ããããããã®ã§ããã åå¿ããŒã ã¯ãããã«é¢ããåé¡ãéããšãã«ãã»ãšãã©ã®ãŠãŒã¶ãŒãããéèŠã ãšæããŸãã ãããŠãèå³ã®ããåå¿éçºè ã®ããã«ãããã§ãã±ãããåŒãä»ããããšãã§ããŸãã
è§ã®ãã糞ã«è¿œãã€ããã Firefoxã«ã¯ãã¹ã¯ãŒããã£ãŒã«ãã«é¢ããåé¡ãããïŒhttps://bugzilla.mozilla.org/show_bug.cgi?id=950510ã¯ãŸã éããŠããŸãïŒãsafariã®ãã°çªå·ã«é¢ããæ å ±ã¯ãããŸãããchromeã¯ä¿®æ£ãããŠããŸãã
åé¡ã¯ãã§ã«ããã€ãã®å Žæã§è¿œè·¡ãããŠããŸã-https
Chromeã®åé¡ã¯è§£æ±ºãããŸããããReact0.14.8ãæèŒããChrome50ã§ã¯æããã«æ©èœããŸããã
ãŸã ä¿®æ£ã¯ãããŸãããïŒ
ããã¯ãã°ããã®éæ©èœããŠããŠãæè¿ãŸãå£ãããããªæ°ãããŸããïŒ
ãã®åé¡ã«é¢ããæŽæ°ã¯ãããŸããïŒ
ãã®åé¡ã«å¯Ÿããç§ã®è§£æ±ºçã®æç²ã¯æ¬¡ã®ãšããã§ãã
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}
/>
);
}
}
æ³šïŒ value
ã¯ç¶æ
ããååŸããã onFieldChange
ã¯ç¶æ
ãæ°ããå€ã§æŽæ°ããŸã
setIntervalã³ãŒãã¯https://github.com/Pephers/react-autofillããã®ãã®ã§ã
ãã®åé¡ãiOS10.2ã§ä¿®æ£ãããããšã誰ãã確èªã§ããŸããïŒ ä»ã¯åçŸã§ããŸãã...
ChromeããŒãžã§ã³55.0.2883.79ã®iOS10.2ã§ããŸã åé¡ããããŸã...ãã ããäžèšã®èª¬æãšã¯ç°ãªããèªåå
¥åãããã³ã³ãã³ãããã©ãŒã ã§çæéç¹æ»
ããåŸãåã³åé€ãããŸãã
ãã®ãããç¶æ
ã«ä¿åãããŠãããã®ãšäžèŽããããã«ãªããŸããããèªåå
¥åã¯ãŸã æ©èœããŸãã...
@irisSchafferã§çºçããã®ãšåãåé¡ãåçŸããŠããŸãã ç§ã¯å圢ã®ã¢ããªã±ãŒã·ã§ã³ãæã£ãŠããŸããããã§ã¯ãreactãšexpressã䜿çšããŠéçããŒãžãã¬ã³ããªã³ã°ããã¯ã©ã€ã¢ã³ãã§å°éå ·ããšã¯ã¹ããŒãããŠåãããŒãžã³ã³ããŒãã³ãã䜿çšããŸãã
reactãä»ããŠãã¹ã¯ãŒãå ¥åå€ãåŠçããªãå Žåã§ããã¯ã©ã€ã¢ã³ãã®reactã³ã³ããŒãã³ãã¯ãchromeãçæé衚瀺ããå Žåã§ããä¿åããããã¹ã¯ãŒããå ¥åããåé€ããŸãã ãã©ãŠã¶ããJavaScriptãç¡å¹ã«ãããšãä¿åããããã¹ã¯ãŒãã¯ãã®ãŸãŸæ®ããŸãã
ãã®åé¡ã¯ãææ°ããŒãžã§ã³ã®58ã䜿çšããŠããChromeã§ã®ã¿çºçããŸãã
åå¿ãšã¯é¢ä¿ãªããä¿åããããã¹ã¯ãŒãã¯ããã©ãŒã«ã¹ãããŒã€ãã³ããªã©ãdomã§çºçããã€ãã³ããçºçãããŸã§ãelement.valueããã¢ã¯ã»ã¹ã§ããŸãããå€ã®å ¥åã«éããªããjavascriptãä»ããŠã€ãã³ãã®çºçãã·ãã¥ã¬ãŒãããããšããŸãããããããã£ã
+1ã ä¿®æ£ãããã¯ã¯ãããŸããïŒ
iOS 10.3.3 Chrome60.0.3112.89ã§ããã®åé¡ã«çŽé¢ããŠããŸãã
èªåå ¥åã¯æ©èœãããã£ãŒã«ãã«å ¥åãããŸãããç¶æ ã¯å€æŽãããŸããã
ãã³ã¬ãŒã¿ã®åé¿çïŒ https ïŒ
äžè¬çãªã³ã³ããŒãã³ãã®åé¿çïŒ
/**
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 for iOSïŒiOSããŒããŒãããã®ææ¡ã§ã¯ãªããChromeããã®èªåå
¥åã§ãã¹ãããããšã確èªããŠãã ããïŒã¯ãå€ãèªåå
¥åãããšãã«change
ã®ã¿ãåºåããŸãã äžæ¹ãã¢ãã€ã«Safariã¯focus
ã keydown
ã input
ã keyup
ã change
ã blur
æŸåºããŸãã Macã§ChromeãšSafariãå®è¡ããŸãã
Reactã¯éåžžã®<input />
change
ã€ãã³ãã䜿çšããŸãããããããã®åé¡ã®æ ¹æ¬åå ã®ããã§ãïŒ https ïŒ
React onChange
ãDOM change
ã€ãã³ãã§ãããªã¬ãŒããããšã¯ã§ããŸãããïŒ ãã®äžã«äœã害ã¯ãããŸããïŒ
Chrome iOSã®é¢é£ããåé¡ïŒ https ïŒ
次ã®å°ããªããŒãžã§èªåå ¥åãšã€ãã³ãããã¹ãããŸããã
<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>
Chrome v62ã§ã¯ãå
¥åã<form />
èŠçŽ ã§ã©ãããããšãå€æŽã€ãã³ããçºè¡ãããŸãã
å ¥åãã£ãŒã«ããå€æŽãããå Žåã«ãã®å€ãååŸããonInputã€ãã³ããã³ãã©ãŒããããŸãã
iOSã®èªåå ¥åã§ã¯ãããã§ãŸã ããã€ãã®ç°åžžãªåäœãèŠãããŸãã äžèšã®react-autofillãã³ã¬ãŒã¿ã¯ãåçŽãªèªåå ¥åã§ã¯ããŸãæ©èœããããã§ãããããŒããŒãã«ãã£ãŠæäŸãããèªåå ¥åã·ã§ãŒãã«ããã§ã¯æ©èœããŸããã
ããã¯ãChrome for iOSã§ä¿®æ£ãããã¯ãã§ãïŒ https ïŒ
onChangeã䜿çšããå¿
èŠãããã®ã¯ãªãã§ããïŒ
ãå€æŽã€ãã³ããã§ã¯ãªããonChangeãã䜿çšããå¿
èŠãããã®ã¯ãªãã§ãã
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>
)
}
}
Chrome v62ã§ã¯ãå ¥åã
<form />
èŠçŽ ã§ã©ãããããšãå€æŽã€ãã³ããçºè¡ãããŸãã
ãã®ãœãªã¥ãŒã·ã§ã³ãChromeã§æ©èœãã autoComplete="tel"
ä»ããŠé»è©±çªå·ãèªåå
¥åããããšã確èªããŸãã
https://github.com/catamphetamine/react-phone-number-input/issues/101
this._previousValue !== this.input.value
ã䜿çšããäžèšã®ãœãªã¥ãŒã·ã§ã³.value
ã¯ãèªåå
¥ååŸã空ã®ãŸãŸã§ãã
å¶åŸ¡ãããã³ã³ããŒãã³ãã䜿çšãããšãã«ããã©ãŒã ã®èªåå ¥åãã©ã®ããã«åŠçããŠãããããããŸããã ãã®ãã°ã€ã³ã·ããªãªãæ€èšããŠãã ããã
.value
ã空ãšããŠå ±åããŸãChromeã«å€ãå ±åãããæ¹æ³ããªãéããå¶åŸ¡ãããŠããªãã³ã³ããŒãã³ããhtml5å ¥åæ€èšŒãããã³æã®ããã«éä¿¡æã«ãã©ãŒã å€ãååŸãã以å€ã«ã解決çã¯èããããŸããã
ããã§åé¡ã远跡ïŒããã³ã¹ã¿ãŒä»ãïŒã§ããŸãïŒ https ïŒ
@DominicTobiasã§ããäžèšã®ãœãªã¥ãŒã·ã§ã³ãæ©èœãããããšãã§ããŸããã§ããã åé¡ã«ã¯è€æ°ã®å±€ããããŸãã 1ã€ç®ã¯ã this.input.value
åžžã«ç©ºçœãšããŠæ»ã£ãŠããããšã§ãã ãã ããåã«ãŒãã§document.getElementById
ã䜿çšãããšã document.getElementById(id).value
-å€ãè¿ãããããšãããããŸããã
ããã¯dispatchEvent
åé¡ã解決ããŸããããå°ãªããšãèªåå
¥åãããå€ãååŸããããã䜿çšããŠåŠçãå®è¡ã§ããŸãïŒããšãã°ãå¶åŸ¡ãããå
¥åã®onChange
ãã³ãã©ãŒãåŒã³åºãã ãã§ãïŒã
@wlingkeç¥ã£ãŠ
@wlingke Chromeã®äººãã¡ã®ããã«ãã¢ãèšå®ãããšããç§ã¯äœãã«æ°ã¥ããŸãã-ããã¯Chromeã®åé¡ã§ã¯ãããŸãããäžèšã®ã³ã¡ã³ãïŒç¹ã«@ oscar-bã³ã¡ã³ãïŒããã£ãšæ³šææ·±ãèªãã¹ãã§ããã onChange
ã¯ãå®éã«ã¯change
ã€ãã³ãã䜿çšããªããReactã®åæã€ãã³ãã§ãããç§ã«ã¯ããªãå¥åŠã«æããŸãã
以äžã®ãã¢ã§ã¯ã input
ã€ãã³ãããªãã¹ã³ããŠããããã«ãåäœãç°ãªãããšãããããŸãã å®éã®change
ã€ãã³ãã䜿çšãããšãiOSChromeã§æ£ããæ©èœããŸãã
ãããã£ãŠãèŠçŽ ãžã®åç
§ãååŸããŠãå®éã®å€æŽã€ãã³ããšãç¶æ
ãæŽæ°ããå¿
èŠãããå Žåã¯input
ã€ãã³ãã®ããã«èŠããonChange
ã€ãã³ãããªãã¹ã³ããããšããå§ãããŸãããŠãŒã¶ãŒãå
¥åããŠããŸãã
ãã¢ïŒ https ïŒ
@DominicTobias以åã change
ã€ãã³ããšinput
ã€ãã³ãã®äž¡æ¹ãå¥ã
ã«è©Šããã»ãããã®ãã³ã¬ãŒã¿ã§äžåºŠã«äž¡æ¹ãè©ŠããŸããããã¢ããªã§æ©èœãããããšãã§ããŸããã§ããã
ãŸããããã«ãã£ãŠç¶æ³ãå€ãããã©ããã¯ããããŸãããã1ã€ã®ãã£ãŒã«ããèªåå
¥åããå Žåãšè€æ°ã®ãã£ãŒã«ããèªåå
¥åããå Žåã«ã¯éãããããŸãã input
ã€ãã³ãã¯ã1ã€ã®ãã£ãŒã«ããèªåå
¥åãããšãã«æ£åžžã«æ©èœããŸããã ãã ããã¢ãã€ã«Chromeã§ã¯ãå®éã«ã¯ããŒããŒãããäžåºŠã«äžé£ã®ãã£ãŒã«ããèªåå
¥åã§ããŸãïŒåãå§ãé»åã¡ãŒã«ãªã©ããã¹ãŠ1åã®ã¿ããã§ïŒã
ãã®2çªç®ã®ã·ããªãªã§ã¯ããã³ã¬ãŒã¿ã¯æåã®ãã£ãŒã«ãã®èªåå ¥åãé©åã«èš±å¯ããŸãïŒæåã®ãã£ãŒã«ãã¯çŸåšãã©ãŒã«ã¹ãããŠãããã£ãŒã«ããæå³ããŸãïŒã ãã ãããã³ã¬ãŒã¿ïŒ3ã€ã®ãã£ãŒã«ããã¹ãŠã«ã¢ã¿ãããããŠããïŒã¯ãä»ã®ãã£ãŒã«ãã§ã¯æ©èœããŠããªãããã§ãã
@wlingkeèå³æ·±ãããšã«ãããã«ããã€ãã®ãã£ãŒã«ããè¿œå ããŸããããiOS Chromeã§3ã€ãã¹ãŠãäžåºŠã«èªåå ¥åãããšãå€æŽã€ãã³ãããã€ãã£ãã§æ£ããåä¿¡ãããŸãïŒãã ãã以äžã®ReactããŒãžã§ã³ã§ã¯0ïŒã
ïŒã¹ã¯ãªãŒã³ã·ã§ããã¯ãã¹ã¯ããããã©ãŠã¶ããã®ãã®ã§ãããé»è©±ã§ãåãçµæãåŸãããŸãïŒ
@DominicTobias input
ã€ãã³ãã䜿çšãããšã以å䜿çšãããã®ã§ãããšæããŸããããã¹ã¯ãããã§å®å
šã«æ©èœããŸãã ãããŠãã¢ãã€ã«ã§ã®æåã®å
¥åã®ããã«åããŸãã
input
ã€ãã³ãã¯reactã®onChange
æãè¿ãã§ãã change
ã€ãã³ãã¯ãèŠçŽ ãç§ãç解ããŠããããšãããã©ãŒã«ã¹ã倱ã£ãåŸã«ã®ã¿ãã¡ã€ã«ãããŸãïŒhttps://stackoverflow.com/questions/17047497/what-is-the-difference-between-change-and-input-event-å
¥åèŠçŽ ã®å ŽåïŒ
ããreactã¯äœããã®çç±ã§onChangeto input
ã€ãã³ãã«ãã€ã³ããããŠããŸãïŒ
ãããã£ãŠãç©äºãåçŽã«ããããã«ãå®éã®å€æŽã€ãã³ãïŒããã³éåžžã®å
¥åã€ãã³ãïŒã®Input
ã³ã³ããŒãã³ãã§ãåŒã³åºããŸãã çŸåšãiOSChromeã§åäœããŠããŸãã ãããè©ŠããŠãç§ã«ç¥ãããŠãã ããïŒ
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);
}
ç·šéïŒChromeã¯v65ã§ä¿®æ£ãããŠããã¯ãã§ãããããã§ãæ©èœããªããšã®å ±åããããŸãïŒ/
ãããã¯ã®èª¬æããããšãããããŸãã 12æã«ãã®åäœãä¿®æ£ããŸããã ããŒããŠã³ãå€æŽãå ¥åãããŒã¢ããã®åã€ãã³ããçºçãããŸãã
https://chromium-review.googlesource.com/c/chromium/src/+/771674Reactã®ä¿®æ£ããããŸããã
https://chromium-review.googlesource.com/c/chromium/src/+/844324ããã«ããèªåå ¥åã®åäœã¯ä¿®æ£ãããŸãããonChangeãã³ãã©ãŒã¯åŒã³åºãããŸããã
ç§ãããã«é¢ããåé¡ãæèµ·ããéçºè ã¯ããã65ã§ä¿®æ£ããããšç¢ºä¿¡ããŠããŸãã... httpsïŒ//bugs.chromium.org/p/chromium/issues/detailïŒid = 813175
@DominicTobiasã®ããã«ãã€ãã£ãã®change
ã€ãã³ããèŽããŠããŸããã onChange
ãããªã¬ãŒããŠããŸãã
ãŸããã¹ã¿ã€ãªã³ã°ã«input:-webkit-autofill
ã»ã¬ã¯ã¿ãŒã䜿çšããŠããŸãã
https://labrewlangerie.com ïŒãåãåãããã©ãŒã ïŒã®äžéšã§çµæã確èªããŠãã ããã
ãã®ä¿®æ£ãã€ãã«ChromeiOSã«å°å ¥ãããŠããããã§ãã ãã ããããã¯12æ1æ¥ã«çµ±åãããããã§ãããããã©ã®ããŒãžã§ã³ãã¯ããããŸããã
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
ããã¯ãã§ã«ææ°ã®ã¯ãã ã«ãªã£ãŠããã¯ãã§ãã ç§ã¯ãŸã ãã®åé¡ã«çŽé¢ããŠããŸãïŒAngular5ïŒã
Chrome 65ãReact15.6ã§ãåãã§ãã
ããã¯æ®å¿µã§ããMahmadiã¯ãããv65ã§3æ13æ¥ã«èµ·ãã£ãŠãããšèšããŸãã:(
ã³ã¡ã³ã15by mahmadi @ chromium.org ã3æ9æ¥
ä¿®æ£ã¯Chrome64ã«ã¯ãããŸãããç§ã®æªãã Chrome 65ãå¿ èŠã«ãªããŸãïŒ3æ13æ¥ããå±éäºå®ïŒã ãã€ãã£ãã€ãã³ãã®ãã¢ãŠã§ããµã€ãããã¹ããããšãããChrome65ã§åäœããŸãããã©ããŒã¢ããããŠããã ãããããšãããããŸãã
https://bugs.chromium.org/p/chromium/issues/detail?id=813175
æºåž¯é»è©±ã§ããã«ã¢ã¯ã»ã¹ããŠç¢ºèªããŠã¿ãŠãã ããïŒ //kind-stallman-f3c045.netlify.com/native.html
æ¬åœã«å¥åŠãªã®ã¯ãv65ã§ã¯ãã€ãã£ãã«æ©èœããŠããããšã§ãããReactã§åä¿¡ãããŠããªããŠããå ¥åãåãåã£ãŠããŸãã ããã«èª¿æ»ãå¿ èŠã§ããreactããã³ãã©ãŒãã©ã®ããã«ã¢ã¿ããããŠãããïŒãŸãã¯ãã¯ãªãã¯ãã³ãã©ãŒã®ããã«ããã¥ã¡ã³ãèŠçŽ ã§ãããè¡ã£ãŠãããã©ããïŒã¯æ£ç¢ºã«ã¯ããããŸããã
ãã€ãã£ãã§ã¯ãå ¥åã€ãã³ããçŸåšçºçããŠããã®ãèŠãããšãã§ããŸãïŒhttps://kind-stallman-f3c045.netlify.com/native.htmlïŒïŒ
ããããã©ããããããReactã¯ãããã®ã€ãã³ããåä¿¡ããŠââããŸããïŒhttps://kind-stallman-f3c045.netlify.comïŒïŒ
å ¥åã«onBlur = {this.handleChange}ãè¿œå ããŸã
KlarnaUIããŒã ã¯ããã®èšäºã§èª¬æãããŠããããã«ã onAnimationStart
ã€ãã³ããš:-webkit-autofill
ç䌌ã¯ã©ã¹ãæªçšããŠãã®åé¡ã«å¯ŸåŠããããã®èå³æ·±ãããã¯ãæã£ãŠããŸã-https
ãã®ããã¯ãã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšããŸããããæ£åžžã«æ©èœããŸãïŒChromeã§ã®ã¿ãã¹ãã§ããŸãïŒã ãã®ãã¯ããã¯ã䜿ã£ãŠã·ã ãèãåºããäžè¬çãªãã®ã«ããããšæããŸãã
ãã®åé¡ã«é¢ããææ°æ å ±ã¯ãããŸããïŒ
ããŠãä»ã®ãšããæé«ã®ããªãã¯ã¯äœã§ããïŒ
@ericflo @sophiebits
ãã®åé¡ã¯ãŸã 解決ããŠããªãããã§ãããæŽæ°ã¯ãããŸããïŒ
@ Pixelatex @ Aarbelç§ã®çãããã ãã-https
åºæ¬çã«ãReactã¯onChangeã®change
ã€ãã³ãã§ã¯ãªãinput
ã€ãã³ãããªãã¹ã³ãããããåçã¯äž¡æ¹ããªãã¹ã³ããŸãã
@DominicTobiasãããè©ŠããŸãããããããæ©èœãããã«ã¯ãããŒãžã®ã©ããã§å®éã«ã¯ãªãã¯ããå¿ èŠããããŸãã ãããŸã§ã€ãã³ãã¯ç»é²ãããŸããã
åèšã§çŽ1æ¥ããã®åé¡ã«åãçµãã§ããŸããã ãã¹ã¯ãããChrome67ãšReact15.6.0ã§æ©èœããªããã®ã確å®ã«ãªã¹ãã§ããŸãã
onAnimationStart
ãšinput:-webkit-autofill
https://medium.com/@brunn/detecting -autofilled-fields-in-javascript-aed598d25da7-æ©æã«èµ·åããŸãïŒãã©ãŒã ã¯ãŸã å
¥åãããŠããŸããïŒthis.inputRef.addEventListener("transitionend", this.doSomething, false)
ãšinput:-webkit-autofill
cssãã©ã³ãžã·ã§ã³ã®çµã¿åãã-æéã©ããã«èµ·åããŸããã ã¢ããããããšã¯ã§ããŸããthis.inputRef.addEventListener("change", this.doSomething)
-ããŒãžãã¯ãªãã¯ãããŸã§èµ·åããŸããonBlur={this.doSomething}
-ã€ãã³ããçºçãããŸããç¹°ãè¿ããŸããããããã®ãœãªã¥ãŒã·ã§ã³ã¯æ®å¿µãªããæ©èœããŸããã ããŒãžãçªãå Žåãé€ããŠãHTMLã«ã¯èªåå
¥åãããå€ã¯å«ãŸããŸããã ã³ã³ãœãŒã«ã«document
ãšå
¥åãããšãããŒãžããŠã§ã€ã¯ã¢ãããããããæãè¿ããã®ã¯2ã§ããããããŸã§ã®ãšããããã°ã©ã ã§ããã¯æ©èœããŸããã§ããã
@DominicTobiasãœãªã¥ãŒã·ã§ã³ã¯ãã¹ã¯ãããChromeã§æ©èœããŸããïŒ
å®éãç§ã¯æ±ãããã¯ãããŠããŸãã åã®ã³ã¡ã³ãã®ãœãªã¥ãŒã·ã§ã³2ã䜿çšããå Žåã¯ã[ä¿åããããã©ãŒã ããŒã¿ã¯æå¹ãªããŒã¿ã§ã] [ããã«æ±ãããããŸã]ãä¿¡é Œã§ããŸãã 次ã«ãã€ãã³ãã®èªåå ¥åãå®äºããåŸã®é·ç§»ããã£ãããã[éä¿¡]ãã¿ã³ãæå¹ã«ããŸãã æ¹æ³ã¯æ¬¡ã®ãšããã§ãã
cssïŒ
input:-webkit-autofill {
transition: background-color 0.1s ease-in-out 0s;
}
ã³ã³ã¹ãã©ã¯ã¿ãŒå ïŒ
this.autofillCompleted = this.autofillCompleted.bind(this)
React Componentã¯ã©ã¹å ïŒ
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)
}
JSXã®å éšïŒ
<FormControl
inputRef={(node) => this.myInputRef= node}
/>
åºæ¬ã³ã³ããŒãã³ãïŒ input
ïŒã®PSã§ã¯ã inputRef
代ããã«ref
å°éå
·ã䜿çšããŸã
ææ°ã®Chromeãã¹ã¯ããããšiOS12 Safariã§ã¯ãèŠçŽ ã<form>
ã§ã©ãããããšããªãŒãã³ã³ããªãŒããonChangeã€ãã³ããçºè¡ããŸãã
@rxbã<p> </p>
ã©ããããŸããïŒ
@basaratç³ãèš³ãããŸããããã³ãŒãã®<form>
ã¿ã°
ãã®åé¡ã«é¢ããæŽæ°ã¯ãããŸããïŒ
ãã®åé¡ã«é¢ããæŽæ°ã¯ãããŸããïŒ
æŽæ°ããã£ãå Žåããããã¯ãã®åé¡ã«ãªããŸãã
è¿œå ããæå³ã®ãããã®ããªãå Žåã¯æçš¿ããªãã§ãã ããããã®åé¡ã賌èªããŠãããã¹ãŠã®äººã«ã¹ãã ãéä¿¡ããŠããŸãã ããããšãã
ç§ãããã«é¢ããåé¡ãæèµ·ããéçºè ã¯ããã65ã§ä¿®æ£ããããšç¢ºä¿¡ããŠããŸãã... httpsïŒ//bugs.chromium.org/p/chromium/issues/detailïŒid = 813175
æ®å¿µãªããããã®ä¿®æ£ã¯ReactããŒã ãšèª¿æŽãããŠããŸããã§ããã iOSäžã®Chromeããéå»ã®ããŒãžã§ã³ã§èª€ã£ãŠå€æŽãã³ãã©ãŒãããªã¬ãŒããããããã£ãèšå®ããããã«ãªã£ãããšã«æ°ã¥ããŠããŸããã§ããã ããããµããŒãããããšã¯ç§ãã¡ã®åŽã§ã¯æå³çã§ã¯ãããŸããã§ããâãããŠç§ãã¡ã¯ãã§ã«åäœãåé€ããå€æŽãå ããŸããïŒChromeãããã«äŸåãå§ããããšãç§ãã¡ã¯ç¥ããŸããã§ããïŒã
ãã©ãŠã¶ã§äœæ¥ããŠããŠãReactåºæã®ããã¯ãè¿œå ããŠããå Žåã¯ãå¿ ãReactããŒã ã®èª°ãã«ã«ãŒãããŠãã ããã
誰ãããããçŸåšã®ãã°ã«èŠçŽã§ããŸããïŒ Reactã¯ãå
¥åã®change
input
ã€ãã³ããš
ããã§èŠéããããšã¯ãããŸããïŒãŸããã©ã®ãã©ãŠã¶ãŒãæ£ããåäœãããããŸãã¯æ£ããåäœããªããã誰ããç¥ã£ãŠããŸããïŒ
ãšããã§ããããïŒ9657ã®äžéšãšèŠãªããããšæããŸããçæ³çã«ã¯ããã®åé¡ã®è§£æ±ºãæ¯æŽãããµãŒãã¹ã«éšåçã«åå ããå¿ èŠããããŸãã
@jquenseæ£ããå€ã䜿çšããŸãããå€æŽã€ãã³ãã¯éä¿¡ããŸããã
http://react-hydration.surge.sh/hydration
ããããŸãããç§ãå°ã調æ»ããŸããïŒ
ããã«ã¯2ã€ã®åé¡ããããšæããŸãã
ããããã¹ãã«äœ¿çšã§ãããµã€ãã§ãïŒ https ïŒ
ç§ãèšããããšãããä»ã®ãã¹ãŠã®ãã©ãããã©ãŒã ãšãã©ãŠã¶ã¯ãèªåå ¥åãããå€ãéžæããããã«æ£åžžã«æ©èœããŸã
äžèšã¯gatsbyããŒãžã§ãããããSSRã®åé¡ã_ãŸã_瀺ããŠããŸãã
@nhunzakerããªãã¯IOSã¯ããŒã ã±ãŒã¹ã«ã€ããŠè³¢ãã¢ã€ãã¢ãæã£ãŠããŸããïŒ Vueããã³ãããããã«èŠããŸãhttps://github.com/vuejs/vue/issues/7058
Reactã¯ãªãŒãã³ã³ããªãŒãããªãã«ããŸãã
Chrome on iOSã®åé¡ã«ã€ããŠæ°ããChromeãã°ãå ±åããŸããïŒ https ïŒ
å ¥åã®ãnameãå±æ§ãå®çŸ©ããããšããŸãããïŒ ãããã«ã¯ã§ããã onChangeã¯ããŠãŒã¶ãŒã®èªåå ¥åæã«ããªã¬ãŒãããŸã
@eatsjobs attråã䜿çšããŠããŸãããåãåé¡ããããŸãã
ç§ã¯ãã¹ãããŸãã
$$(':-webkit-autofill')
Chrome 70ã§åäœããèªåå ¥åãããå ¥åãè¿ããŸãã
@QuantumInformationã¯ç§ã«ãšã£ãŠåãã§ã:(
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>
ç§ã¯ãã®æ¹æ³ãè©ŠããŸãããã¹ãŠãããŸãããããã«èŠããŸãã
ãªãŒããã£ã«ã¯ç§ã®ç¶æ
ãæ£ããèšå®ããŸããã ïŒios 12ïŒ
æè¿ãã®åé¡ã«ééãã人ã«ãšã£ãŠã¯ãã»ãã¥ãªãã£ãªã¹ã¯ãåé¿ããããã«ãã©ãŠã¶ã«ãã£ãŠæå³çã«åŒãèµ·ããããŠããŸãã
ããŒãžãèªã¿èŸŒãŸãããšãã«èªåå
¥åãããå€ã«ã¢ã¯ã»ã¹ã§ããã°ããã£ãã·ã³ã°ãç®çãšãããã©ãŒã ã«æ
å ±ãæœåºããæªæã®ããã³ãŒããéåžžã«ç°¡åã«èšè¿°ã§ããããã«ãªããŸãã ãŠãŒã¶ãŒã«åå¿ããæ©äŒãäžããŸããã ããããã autocomplete="off"
ããã©ãŠã¶ã«ãã£ãŠç¡èŠãããçç±ã®äžéšã§ãã
ãã®åé¡ãå æããã«ã¯ã次ã®ããšãè¡ãå¿ èŠããããŸãã
ãã®åé¡ã解決ããããã«ããã©ãŒã ãå
ã
ã©ã®ããã«èšèšããã䜿çšãããããšãæå³ããŠããããæãåºããŠãã ããã ãŠãŒã¶ãŒãã¯ãªãã¯ãããšã <button type="submit" />
å
åŽ<form>
ãåºæ¬çã«ãä»ã®ã¯ããã©ãŒã ã®å€ãè©äŸ¡ããŠã¿ãŸããããã¡ãã£ãšãã®ã¢ã¯ã·ã§ã³ã¯ããŠãŒã¶ãæå³ããŠããããšèšã£ãŠããŸãã
Reactã§æžãããæ¬åœã«åçŽãªSignInFormã®ãã®äŸãèããŠã¿ãŸãããã
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;
éä¿¡ãããšããã©ãŒã ã¯ããã«å¿ããŠå ¥åãã£ãŒã«ããæŽæ°ããã³è©äŸ¡ããŸãã
ããã®æå³ã¯ïŒ
ç§ã®æèŠã§ã¯ãããã¯æãå®çšçãªã¢ãããŒãã§ãããå€ãã®é çã®çš®ãæãã§ãããã ãããå°æ¥ä»ã®äººã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
ç·šéïŒReactã«æ £ããŠããªã人ã®ããã«ããã©ãŒã ã®åºæ¬çãªå®è£ ãšããã€ãã®è¿œå ã®ãžã¥ãŒã·ãŒãªæ å ±ã«ã€ããŠã¯ããã®ãªã³ã¯ãåç §ããŠãã ããïŒ https ïŒ
æè¿ãã®åé¡ã«ééãã人ã«ãšã£ãŠã¯ãã»ãã¥ãªãã£ãªã¹ã¯ãåé¿ããããã«ãã©ãŠã¶ã«ãã£ãŠæå³çã«åŒãèµ·ããããŠããŸãã
ããŒãžãèªã¿èŸŒãŸãããšãã«èªåå ¥åãããå€ã«ã¢ã¯ã»ã¹ã§ããã°ããã£ãã·ã³ã°ãç®çãšãããã©ãŒã ã«æ å ±ãæœåºããæªæã®ããã³ãŒããéåžžã«ç°¡åã«èšè¿°ã§ããããã«ãªããŸãã ãŠãŒã¶ãŒã«åå¿ããæ©äŒãäžããŸããã ããããã
autocomplete="off"
ããã©ãŠã¶ã«ãã£ãŠç¡èŠãããçç±ã®äžéšã§ãããã®åé¡ãå æããã«ã¯ã次ã®ããšãè¡ãå¿ èŠããããŸãã
- DOMããŒããããŠã³ãããããšãã«èªåå ¥åãããå€ã«ã¢ã¯ã»ã¹ã§ããªãïŒãããŠæ±ºããŠã¢ã¯ã»ã¹ããªãïŒãšããäºå®ãåãå ¥ããŸã
- ãã©ãŠã¶ã«ãã£ãŠåŒãèµ·ããããã»ãã¥ãªãã£äžã®æžå¿µãåãå ¥ãã
ãã®åé¡ã解決ããããã«ããã©ãŒã ãå ã ã©ã®ããã«èšèšããã䜿çšãããããšãæå³ããŠããããæãåºããŠãã ããã ãŠãŒã¶ãŒãã¯ãªãã¯ãããšã
<button type="submit" />
å åŽ<form>
ãåºæ¬çã«ãä»ã®ã¯ããã©ãŒã ã®å€ãè©äŸ¡ããŠã¿ãŸããããã¡ãã£ãšãã®ã¢ã¯ã·ã§ã³ã¯ããŠãŒã¶ãæå³ããŠããããšèšã£ãŠããŸããReactã§æžãããæ¬åœã«åçŽãªSignInFormã®ãã®äŸãèããŠã¿ãŸãããã
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;
éä¿¡ãããšããã©ãŒã ã¯ããã«å¿ããŠå ¥åãã£ãŒã«ããæŽæ°ããã³è©äŸ¡ããŸãã
ããã®æå³ã¯ïŒ
- éä¿¡ãã¿ã³ãç¡å¹ã«ããããšã¯ã§ããŸãã
- ãŠãŒã¶ãŒããã®ãã¿ã³ãã¯ãªãã¯ãããšããã¹ãŠã®æ€èšŒãè¡ãããå¿ èŠããããŸã
ç§ã®æèŠã§ã¯ãããã¯æãå®çšçãªã¢ãããŒãã§ãããå€ãã®é çã®çš®ãæãã§ãããã ãããå°æ¥ä»ã®äººã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
ç·šéïŒReactã«æ £ããŠããªã人ã®ããã«ããã©ãŒã ã®åºæ¬çãªå®è£ ãšããã€ãã®è¿œå ã®ãžã¥ãŒã·ãŒãªæ å ±ã«ã€ããŠã¯ããã®ãªã³ã¯ãåç §ããŠãã ããïŒ https ïŒ
èŠçŽãããããšãããããç§ã¯å®å šã«æ··ä¹±ããŠããŸãã ãã©ãŒã ãéä¿¡ãããšããããã«å¿ããŠæŽæ°ãããããšã®ããšã§ãã ããã¯ãéä¿¡ã€ãã³ããçºçãããåã«ãèªåå ¥åããããã£ãŒã«ãããšã«è¿œå ã®å€æŽã€ãã³ããçºçãããããšãæå³ããŸããïŒ ãŸãã¯ãéä¿¡ã€ãã³ããçºçãããšãã«ãå€ãåç §ãä»ããŠèªã¿åãå¯èœã«ãªã£ãããšãæå³ããŸããïŒ åè ã®å Žåã¯ãã¹ããããã«ç€ºãããããªã³ã³ããŒãã³ããäœæã§ããŸãã åŸè ã®å Žåã¯ããã©ãŒã ãåé²ãããããã«åç §ããŒã¹ã®ã¢ãããŒããæ¡çšããå¿ èŠããããŸãã
@thomasjulianstoelenã©ãããæå³ã§ããïŒ
@dwoodwardgb
ç§ã®çµéšã§ã¯ïŒå°ãªããšãChromeã§ã¯ïŒããŠãŒã¶ãŒãããŒãžãæåã«æäœãããšãã®ãã£ãŒã«ãïŒã¯ãªãã¯ããã©ãŒã ã®éä¿¡ãªã©ïŒãæŽæ°ããå€æŽãå ããŠã€ãã³ããéä¿¡ããŠãã¢ãã«å€æ°ãæŽæ°ã§ããããã«ããŸããã ãã ããä»ã®ãã©ãŠã¶ã¯ãŸã ãã¹ãããŠããŸããã
autocomplete = "off"å±æ§ïŒHTML5ïŒãèšå®ããããå ¥åå€ãURLããã·ã¥ã«èšé²ããããšãã§ããŸãã
ãã®åé¡ãããå°ãæãäžããŸããChromiumã¯ããã®ãã°ã¬ããŒãã«åºã¥ããŠãå€æŽããšãå
¥åãã®äž¡æ¹ã®ãã€ãã£ãã€ãã³ããçºè¡ããããã«å€æŽããŸããïŒ https ïŒ onChange
ã€ãã³ããããªã¬ãŒããŸããã ããã¯ãReactã®éè€æé€ããžãã¯ïŒhttps://github.com/facebook/react/issues/10135ïŒããŸãã¯iOSäžã®Chromeã«ãã£ãŠããã°ã©ã ã§çºè¡ãããã€ãã³ãã«isTrusted=false
ãã©ã°ãä»ããŠãããšããäºå®ã«é¢é£ããŠããå¯èœæ§ããããŸãã
ReactããŒã ã®èª°ããReact onChange
ã€ãã³ããã³ãã©ãŒã詳ãã調ã¹ãŠãã€ãã³ããããªã¬ãŒãããªãçç±ãç解ã§ããŸããïŒ @gaearonãŸãã¯@zpao ïŒã©ã³ãã ãªæšæž¬ïŒïŒ
ãããŸã§ã®éããã€ãã£ãã®ãå
¥åãã€ãã³ããçŽæ¥ãªãã¹ã³ããonInput
ã€ãã³ãã䜿çšããŠããŸãã
ãããåäœãå£ããChromeã®ã³ãããã ãšæããŸãïŒ
å€æŽã€ãã³ãããsimulated
ãã©ã°ãåé€ããŸããããã«ãããéè€æé€ããžãã¯ããããã®ã€ãã³ããç¡èŠããå¯èœæ§ããããŸãã
@nfiaccoã®ã³ãããã¯2018幎ããã®ãã®ã§ããã®åé¡ã¯2014幎ã«éãããã®ã§ãè¡šé¢çã«ã¯
2022幎ããåž°ã£ãŠãã
æãåèã«ãªãã³ã¡ã³ã
å ¥åã®ãnameãå±æ§ãå®çŸ©ããããšããŸãããïŒ ãããã«ã¯ã§ããã onChangeã¯ããŠãŒã¶ãŒã®èªåå ¥åæã«ããªã¬ãŒãããŸã