我希望通过键盘处理更改与通过鼠标点击进行的更改不同。为此,我创建了以下组件。我的问题是,当我使用箭头键和空格来选择单选按钮时,它使用父div元素中的onClick方法,然后才使用输入元素中的onChange方法。这种行为的原因是什么?如何正确处理?
class Radio extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onClick = this.onClick.bind(this);
this.state = { checked: false };
}
onChange() {
this.setState({ checked: !this.state.checked });
console.log('onChange');
}
onClick() {
this.onChange();
console.log('onClick');
}
render() {
return (
<div onClick={this.onClick}>
<input
type="radio"
checked={this.state.checked}
onChange={this.onChange}
/>
Click me!
</div>
);
}
}
ReactDOM.render(<Radio />, document.getElementById('root'));
&#13;
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>
&#13;
答案 0 :(得分:3)
如this issue和W3C documentation的这一部分所示,这似乎是默认的浏览器行为。
当用户以非点击方式触发具有已定义激活行为的元素时,交互事件的默认操作必须是对元素执行合成点击激活步骤。
要解决此问题,请在exports.calculator = (event, context, callback) => {
// TODO implement
var i1 = event.key1;
var i2 = event.key2;
var operation = event.key3;
switch(operation){
case '+' : callback(null, i1+i2 );break;
case '-' : callback(null, i1-i2 );break;
case '*' : callback(null, i1*i2 );break;
case '/' : callback(null, i1/i2 );break;
default:callback(null,"Invalid operator entered");break;
}
};
处理程序中添加以下逻辑:
onClick
向GitHub用户Ro Savage致信,指出这一点。
以下是您的完整演示:
if (e.type === 'click' && e.clientX !== 0 && e.clientY !== 0) {
// This is a real click. Do something here
}
class Radio extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onClick = this.onClick.bind(this);
this.state = { checked: false };
}
onChange() {
this.setState({ checked: !this.state.checked });
console.log('onChange');
}
onClick(e) {
if (e.type === 'click' && e.clientX !== 0 && e.clientY !== 0) {
this.onChange();
console.log('onClick');
} else {
console.log('prevented "onClick" on keypress');
}
}
render() {
return (
<div onClick={this.onClick}>
<input
type="radio"
checked={this.state.checked}
onChange={this.onChange}
/>
Click me!
</div>
);
}
}
ReactDOM.render(<Radio />, document.getElementById('root'));
答案 1 :(得分:2)
您可以禁用点击事件的传播:
<input
type="radio"
checked={this.state.checked}
onClick={(e)=>{e.stopPropagation()}}
onChange={this.onChange}
/>
答案 2 :(得分:0)
事件的顺序很重要:点击事件将在更改事件之前触发。
由于事件冒出来,父元素的onClick
- 处理程序将在子元素的onChange
- 处理程序之前被触发。
要解决您的具体问题,您可以听一下容器div上的keydown
- 事件。在点击或更改事件之前应该触发此事件。
class Radio extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onKeyUp = this.onKeyUp.bind(this);
this.state = { checked: false };
}
onChange() {
this.setState({ checked: !this.state.checked });
console.log('onChange');
}
onKeyUp() {
console.log('onKeyUp');
this.onChange();
}
render() {
return (
<div onKeyUp={this.onKeyUp}>
<input
type="radio"
checked={this.state.checked}
onChange={this.onChange}
/>
Click me!
</div>
);
}
}
ReactDOM.render(<Radio />, document.getElementById('root'));
&#13;
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>
&#13;