¿Cómo puede lograr un evento de desplazamiento o un evento activo en ReactJS cuando realiza un estilo en línea?
Descubrí que el enfoque onMouseEnter, onMouseLeave tiene errores, por lo que espero que haya otra forma de hacerlo.
Específicamente, si pasa el mouse sobre un componente muy rápidamente, solo se registra el evento onMouseEnter. El onMouseLeave nunca se dispara y, por lo tanto, no puede actualizar el estado ... dejando que el componente parezca que todavía se está desplazando. He notado lo mismo si intentas imitar la pseudoclase ": active" css. Si hace clic muy rápido, solo se registrará el evento onMouseDown. El evento onMouseUp será ignorado ... dejando el componente activo.
Aquí hay un JSFiddle que muestra el problema: https://jsfiddle.net/y9swecyu/5/
Video de JSFiddle con problema: https://vid.me/ZJEO
El código:
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')
)
fuente
Respuestas:
¿Has probado alguno de estos?
onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp
Evento sintético
también menciona lo siguiente:
React normaliza los eventos para que tengan propiedades consistentes en diferentes navegadores.
Los controladores de eventos siguientes se activan mediante un evento en la fase de propagación. Para registrar un controlador de eventos para la fase de captura, agregue Capture al nombre del evento; por ejemplo, en lugar de usar onClick, usaría onClickCapture para manejar el evento de clic en la fase de captura.
fuente
The onMouseEnter and onMouseLeave events propagate from the element being left to the one being entered instead of ordinary bubbling and do not have a capture phase.
Las respuestas anteriores son bastante confusas. No necesita un estado de reacción para resolver esto, ni ninguna biblioteca externa especial. Se puede lograr con css / sass puro:
El estilo:
.hover { position: relative; &:hover &__no-hover { opacity: 0; } &:hover &__hover { opacity: 1; } &__hover { position: absolute; top: 0; opacity: 0; } &__no-hover { opacity: 1; } }
El componente React
Una simple función
Hover
de renderizado puro:const Hover = ({ onHover, children }) => ( <div className="hover"> <div className="hover__no-hover">{children}</div> <div className="hover__hover">{onHover}</div> </div> )
Uso
Entonces úsalo así:
<Hover onHover={<div> Show this on hover </div>}> <div> Show on no hover </div> </Hover>
fuente
puede usar
onMouseOver={this.onToggleOpen}
yonMouseOut={this.onToggleOpen}
reflexionar sobre el componentefuente
Si puede producir una pequeña demostración que muestre el error onMouseEnter / onMouseLeave o onMouseDown / onMouseUp, valdría la pena publicarlo en la página de problemas de ReactJS o en la lista de correo, solo para plantear la pregunta y escuchar lo que los desarrolladores tienen que decir al respecto.
En su caso de uso, parece dar a entender que los estados CSS: hover y: active serían suficientes para sus propósitos, por lo que le sugiero que los use. CSS es órdenes de magnitud más rápido y confiable que Javascript, porque se implementa directamente en el navegador.
Sin embargo, los estados: hover y: active no se pueden especificar en estilos en línea. Lo que puede hacer es asignar un ID o un nombre de clase a sus elementos y escribir sus estilos en una hoja de estilo, si son algo constantes en su aplicación, o en una
<style>
etiqueta generada dinámicamente .Aquí hay un ejemplo de la última técnica: https://jsfiddle.net/ors1vos9/
fuente
Un simple
css
solución .Para aplicar estilos básicos, CSS es más simple y más eficaz que las soluciones JS el 99% del tiempo. (Aunque las soluciones CSS-in-JS más modernas, por ejemplo, React Components, etc., son posiblemente más fáciles de mantener).
Ejecute este fragmento de código para verlo en acción…
.hover-button .hover-button--on, .hover-button:hover .hover-button--off { display: none; } .hover-button:hover .hover-button--on { display: inline; }
<button class='hover-button'> <span class='hover-button--off'>Default</span> <span class='hover-button--on'>Hover!</span> </button>
fuente
more performant that JS solutions 99% of the time
no es verdad. lea artículos que desacrediten este mito. tienes alguna fuente?Me acabo de encontrar con este mismo problema al escuchar eventos onMouseLeave en un botón deshabilitado. Lo solucioné escuchando el evento nativo mouseleave en un elemento que envuelve el botón deshabilitado.
componentDidMount() { this.watchForNativeMouseLeave(); }, componentDidUpdate() { this.watchForNativeMouseLeave(); }, // onMouseLeave doesn't work well on disabled elements // https://github.com/facebook/react/issues/4251 watchForNativeMouseLeave() { this.refs.hoverElement.addEventListener('mouseleave', () => { if (this.props.disabled) { this.handleMouseOut(); } }); }, render() { return ( <span ref='hoverElement' onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} > <button disabled={this.props.disabled}>Submit</button> </span> ); }
Aquí hay un violín https://jsfiddle.net/qfLzkz5x/8/
fuente
onMouseLeave
-Evento confiableUn paquete llamado
styled-components
puede solucionar este problema de forma ELEGANTE manera .Referencia
Ejemplo
const styled = styled.default const Square = styled.div` height: 120px; width: 200px; margin: 100px; background-color: green; cursor: pointer; position: relative; &:hover { background-color: red; }; ` class Application extends React.Component { render() { return ( <Square> </Square> ) } } /* * Render the above component into the div#app */ ReactDOM.render(<Application />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script> <script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script> <div id='app'></div>
fuente
No puedes con el estilo en línea solo. No recomiendo volver a implementar las funciones de CSS en JavaScript, ya tenemos un lenguaje que es extremadamente poderoso e increíblemente rápido construido para este caso de uso: CSS. ¡Úsalo! Made Style It para ayudar.
npm install style-it --save
Sintaxis funcional ( JSFIDDLE )
import React from 'react'; import Style from 'style-it'; class Intro extends React.Component { render() { return Style.it(` .intro:hover { color: red; } `, <p className="intro">CSS-in-JS made simple -- just Style It.</p> ); } } export default Intro;
Sintaxis JSX ( JSFIDDLE )
import React from 'react'; import Style from 'style-it'; class Intro extends React.Component { render() { return ( <Style> {` .intro:hover { color: red; } `} <p className="intro">CSS-in-JS made simple -- just Style It.</p> </Style> } } export default Intro;
fuente
¡Utilice radio !
El siguiente es un ejemplo de su sitio web:
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' } };
fuente
Usaría onMouseOver y onMouseOut. Causa en React
Aquí está en la documentación de React para eventos de mouse.
fuente
Tuve un problema similar cuando se llamó a onMouseEnter, pero a veces no se disparó el evento onMouseLeave correspondiente, aquí hay una solución que funciona bien para mí (se basa parcialmente en jQuery):
var Hover = React.createClass({ getInitialState: function() { return { hover: false }; }, onMouseEnterHandler: function(e) { this.setState({ hover: true }); console.log('enter'); $(e.currentTarget).one("mouseleave", function (e) { this.onMouseLeaveHandler(); }.bind(this)); }, 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} > {this.props.children} </div> </div> ); } });
Ver en jsfiddle: http://jsfiddle.net/qtbr5cg6/1/
Por qué estaba sucediendo (en mi caso): estoy ejecutando una animación de desplazamiento de jQuery (a través
$('#item').animate({ scrollTop: 0 })
) al hacer clic en el elemento. Entonces, el cursor no deja el elemento "naturalmente", sino durante una animación impulsada por JavaScript ... y en este caso, el onMouseLeave no fue activado correctamente por React (React 15.3.0, Chrome 51, Desktop)fuente
Sé que ha pasado un tiempo desde que se hizo esta pregunta, pero me encontré con el mismo problema de inconsistencia con onMouseLeave () Lo que hice fue usar onMouseOut () para la lista desplegable y dejar el mouse para todo el menú, es confiable y funciona cada vez que lo he probado. Vi los eventos aquí en los documentos: https://facebook.github.io/react/docs/events.html#mouse-events aquí hay un ejemplo usando https://www.w3schools.com/bootstrap/bootstrap_dropdowns.asp :
handleHoverOff(event){ //do what ever, for example I use it to collapse the dropdown let collapsing = true; this.setState({dropDownCollapsed : collapsing }); } render{ return( <div class="dropdown" onMouseLeave={this.handleHoverOff.bind(this)}> <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example <span class="caret"></span></button> <ul class="dropdown-menu" onMouseOut={this.handleHoverOff.bind(this)}> <li><a href="#">bla bla 1</a></li> <li><a href="#">bla bla 2</a></li> <li><a href="#">bla bla 3</a></li> </ul> </div> ) }
fuente
Yo personalmente uso Style It para el estilo en línea en React o mantengo mi estilo por separado en un CSS o SASS archivo ...
Pero si está realmente interesado en hacerlo en línea, mire la biblioteca, comparto algunos de los usos a continuación:
En el componente :
import React from 'react'; import Style from 'style-it'; class Intro extends React.Component { render() { return ( <Style> {` .intro { font-size: 40px; } `} <p className="intro">CSS-in-JS made simple -- just Style It.</p> </Style> ); } } export default Intro;
Salida :
<p class="intro _scoped-1"> <style type="text/css"> ._scoped-1.intro { font-size: 40px; } </style> CSS-in-JS made simple -- just Style It. </p>
También puede usar variables de JavaScript con hover en su CSS como se muestra a continuación:
import React from 'react'; import Style from 'style-it'; class Intro extends React.Component { render() { const fontSize = 13; return Style.it(` .intro { font-size: ${ fontSize }px; // ES2015 & ES6 Template Literal string interpolation } .package { color: blue; } .package:hover { color: aqua; } `, <p className="intro">CSS-in-JS made simple -- just Style It.</p> ); } } export default Intro;
Y el resultado de la siguiente manera:
<p class="intro _scoped-1"> <style type="text/css"> ._scoped-1.intro { font-size: 13px; } ._scoped-1 .package { color: blue; } ._scoped-1 .package:hover { color: aqua; } </style> CSS-in-JS made simple -- just Style It. </p>
fuente