Wie kann man in ReactJS entweder ein Hover-Ereignis oder ein aktives Ereignis erreichen, wenn man Inline-Styling betreibt?
Ich habe festgestellt, dass die onMouseEnter, onMouseLeave Ansatz fehlerhaft ist, so hoffen, dass es einen anderen Weg, es zu tun ist.
Insbesondere, wenn Sie Maus über eine Komponente sehr schnell, nur das onMouseEnter-Ereignis registriert wird. Die onMouseLeave feuert nie, und somit kann nicht aktualisieren Zustand ... so dass die Komponente zu erscheinen, als ob es noch über schwebte. I've bemerkte die gleiche Sache, wenn Sie versuchen und imitieren die ":active" css Pseudoklasse. Wenn Sie wirklich schnell klicken, wird nur das onMouseDown-Ereignis registriert. Das onMouseUp-Ereignis wird ignoriert... so dass die Komponente aktiv erscheint.
Hier ist ein JSFiddle, das das Problem zeigt:
Video von JSFiddle mit dem Problem: https://vid.me/ZJEO
Der Code:
var Hover = React.createClass({
getInitialState: function() {
return {
hover: false
};
},
onMouseEnterHandler: function() {
this.setState({
hover: true
});
console.log('enter');
},
onMouseLeaveHandler: function() {
this.setState({
hover: false
});
console.log('leave');
},
render: function() {
var inner = normal;
if(this.state.hover) {
inner = hover;
}
return (
<div style={outer}>
<div style={inner}
onMouseEnter={this.onMouseEnterHandler}
onMouseLeave={this.onMouseLeaveHandler} >
{this.props.children}
</div>
</div>
);
}
});
var outer = {
height: '120px',
width: '200px',
margin: '100px',
backgroundColor: 'green',
cursor: 'pointer',
position: 'relative'
}
var normal = {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
backgroundColor: 'red',
opacity: 0
}
var hover = {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
backgroundColor: 'red',
opacity: 1
}
React.render(
<Hover></Hover>,
document.getElementById('container')
)
Haben Sie eine davon ausprobiert?
onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp`
wird auch das Folgende erwähnt:
React normalisiert Ereignisse, damit sie in verschiedenen Browsern konsistente Eigenschaften haben.
Die folgenden Event-Handler werden durch ein Ereignis in der Bubbling-Phase ausgelöst. Um einen Event-Handler für die Capture-Phase zu registrieren, hängen Sie Capture an den Event-Namen an. Anstelle von onClick würden Sie beispielsweise onClickCapture verwenden, um das Click-Ereignis in der Capture-Phase zu behandeln.
Wenn Sie eine kleine Demo produzieren können, die den onMouseEnter / onMouseLeave oder onMouseDown / onMouseUp Bug zeigt, würde es sich lohnen, sie auf der ReactJS's Issues Seite oder Mailingliste zu posten, nur um die Frage aufzuwerfen und zu hören, was die Entwickler dazu zu sagen haben.
In Ihrem Anwendungsfall scheinen Sie anzudeuten, dass die CSS-Zustände :hover und :active für Ihre Zwecke ausreichen würden, also schlage ich vor, sie zu verwenden. CSS ist um Größenordnungen schneller und zuverlässiger als Javascript, weil es direkt im Browser implementiert ist.
Allerdings können die Zustände :hover und :active nicht in Inline-Styles angegeben werden. Was Sie tun können, ist, Ihren Elementen eine ID oder einen Klassennamen zuzuweisen und Ihre Stile entweder in ein Stylesheet zu schreiben, wenn sie in Ihrer Anwendung einigermaßen konstant sind, oder in ein dynamisch generiertes <style>
-Tag.
Hier ist ein Beispiel für die letztere Technik:
Verwenden Sie Radium!
Das folgende Beispiel stammt von ihrer Website:
var Radium = require('radium');
var React = require('react');
var color = require('color');
@Radium
class Button extends React.Component {
static propTypes = {
kind: React.PropTypes.oneOf(['primary', 'warning']).isRequired
};
render() {
// Radium extends the style attribute to accept an array. It will merge
// the styles in order. We use this feature here to apply the primary
// or warning styles depending on the value of the `kind` prop. Since its
// all just JavaScript, you can use whatever logic you want to decide which
// styles are applied (props, state, context, etc).
return (
<button
style={[
styles.base,
styles[this.props.kind]
]}>
{this.props.children}
</button>
);
}
}
// You can create your style objects dynamically or share them for
// every instance of the component.
var styles = {
base: {
color: '#fff',
// Adding interactive state couldn't be easier! Add a special key to your
// style object (:hover, :focus, :active, or @media) with the additional rules.
':hover': {
background: color('#0074d9').lighten(0.2).hexString()
}
},
primary: {
background: '#0074D9'
},
warning: {
background: '#FF4136'
}
};