Javascript 你如何在 ReactJS 中悬停?- 在快速悬停期间未注册 onMouseLeave
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29981236/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you Hover in ReactJS? - onMouseLeave not registered during fast hover over
提问by HelpMeStackOverflowMyOnlyHope
How can you achieve either a hover event or active event in ReactJS when you do inline styling?
当您进行内联样式时,如何在 ReactJS 中实现悬停事件或活动事件?
I've found that the onMouseEnter, onMouseLeave approach is buggy, so hoping there is another way to do it.
我发现 onMouseEnter, onMouseLeave 方法有问题,所以希望有另一种方法来做到这一点。
Specifically, if you mouse over a component very quickly, only the onMouseEnter event is registered. The onMouseLeave never fires, and thus can't update state... leaving the component to appear as if it still is being hovered over. I've noticed the same thing if you try and mimic the ":active" css pseudo-class. If you click really fast, only the onMouseDown event will register. The onMouseUp event will be ignored... leaving the component appearing active.
具体来说,如果您非常快速地将鼠标悬停在某个组件上,则只会注册 onMouseEnter 事件。onMouseLeave 永远不会触发,因此无法更新状态......让组件看起来好像它仍然被悬停在上面。如果您尝试模仿 ":active" css 伪类,我会注意到同样的事情。如果您单击非常快,则只会注册 onMouseDown 事件。onMouseUp 事件将被忽略...让组件显示为活动状态。
Here is a JSFiddle showing the problem: https://jsfiddle.net/y9swecyu/5/
这是一个显示问题的 JSFiddle:https://jsfiddle.net/y9swecyu/5/
Video of JSFiddle with problem: https://vid.me/ZJEO
有问题的 JSFiddle 视频:https://vid.me/ZJEO
The 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')
)
回答by Elon Zito
Have you tried any of these?
你试过这些吗?
onMouseDown onMouseEnter onMouseLeave
onMouseMove onMouseOut onMouseOver onMouseUp
onMouseDown onMouseEnter onMouseLeave
onMouseMove onMouseOut onMouseOver onMouseUp
it also mentions the following:
它还提到以下内容:
React normalizes events so that they have consistent properties across different browsers.
React 规范化事件,以便它们在不同的浏览器中具有一致的属性。
The event handlers below are triggered by an event in the bubbling phase. To register an event handler for the capture phase, append Capture to the event name; for example, instead of using onClick, you would use onClickCapture to handle the click event in the capture phase.
下面的事件处理程序由冒泡阶段的事件触发。要为捕获阶段注册事件处理程序,请将 Capture 附加到事件名称;例如,您将使用 onClickCapture 来处理捕获阶段的点击事件,而不是使用 onClick。
回答by dreampulse
The previous answers are pretty confusing. You don't need a react-state to solve this, nor any special external lib. It can be achieved with pure css/sass:
之前的答案很混乱。您不需要反应状态来解决这个问题,也不需要任何特殊的外部库。可以用纯 css/sass 来实现:
The style:
样式:
.hover {
position: relative;
&:hover &__no-hover {
opacity: 0;
}
&:hover &__hover {
opacity: 1;
}
&__hover {
position: absolute;
top: 0;
opacity: 0;
}
&__no-hover {
opacity: 1;
}
}
The React-Component
反应组件
A simple HoverPure-Rendering-Function:
一个简单的Hover纯渲染函数:
const Hover = ({ onHover, children }) => (
<div className="hover">
<div className="hover__no-hover">{children}</div>
<div className="hover__hover">{onHover}</div>
</div>
)
Usage
用法
Then use it like this:
然后像这样使用它:
<Hover onHover={<div> Show this on hover </div>}>
<div> Show on no hover </div>
</Hover>
回答by Behnam Eskandari
you can use onMouseOver={this.onToggleOpen}and onMouseOut={this.onToggleOpen}to muse over and out on component
您可以使用onMouseOver={this.onToggleOpen}和 onMouseOut={this.onToggleOpen}反复思考组件
回答by Tobia
If you can produce a small demo showing the onMouseEnter / onMouseLeave or onMouseDown / onMouseUp bug, it would be worthwhile to post it to ReactJS's issues page or mailing list, just to raise the question and hear what the developers have to say about it.
如果您可以制作一个小演示来显示 onMouseEnter / onMouseLeave 或 onMouseDown / onMouseUp 错误,那么将其发布到 ReactJS 的问题页面或邮件列表中是值得的,只是为了提出问题并听取开发人员对此的看法。
In your use case, you seem to imply that CSS :hover and :active states would be enough for your purposes, so I suggest you use them. CSS is orders of magnitude faster and more reliable than Javascript, because it's directly implemented in the browser.
在您的用例中,您似乎暗示 CSS :hover 和 :active 状态足以满足您的目的,因此我建议您使用它们。CSS 比 Javascript 快和可靠几个数量级,因为它直接在浏览器中实现。
However, :hover and :active states cannot be specified in inline styles. What you can do is assign an ID or a class name to your elements and write your styles either in a stylesheet, if they are somewhat constant in your application, or in a dynamically generated <style>tag.
但是,不能在内联样式中指定 :hover 和 :active 状态。您可以做的是为您的元素分配一个 ID 或一个类名,并在样式表中编写您的样式(如果它们在您的应用程序中有些恒定)或在动态生成的<style>标签中。
Here's an example of the latter technique: https://jsfiddle.net/ors1vos9/
这是后一种技术的示例:https: //jsfiddle.net/ors1vos9/
回答by Beau Smith
Note:This answer was for a previous version of this question where the question asker was trying to use JavaScript to apply css styles… which can simply be done with CSS.
注意:这个答案是针对这个问题的先前版本,其中提问者试图使用 JavaScript 来应用 css 样式……这可以简单地使用 CSS 来完成。
A simple css-only solution.
一个简单的css解决方案。
For applying basic styles, CSS is simpler and more performant that JS solutions 99% of the time. (Though more modern CSS-in-JS solutions — eg. React Components, etc — are arguably more maintainable.)
对于应用基本样式,CSS 在 99% 的情况下都比 JS 解决方案更简单、更高效。(尽管更现代的 CSS-in-JS 解决方案——例如 React 组件等——可以说更易于维护。)
Run this code snippet to see it in action…
运行此代码片段以查看其实际效果……
.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>
回答by Cory Danielson
I've just bumped into this same problem when listening for onMouseLeave events on a disabled button. I worked around it by listening for the native mouseleave event on an element that wraps the disabled button.
在侦听禁用按钮上的 onMouseLeave 事件时,我刚刚遇到了同样的问题。我通过在包装禁用按钮的元素上侦听本机 mouseleave 事件来解决它。
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>
);
}
Here's a fiddle https://jsfiddle.net/qfLzkz5x/8/
回答by Karl Xu
A package called styled-componentscan solve this problem in an ELEGANTway.
一个名为的包styled-components可以以优雅的方式解决这个问题。
Reference
参考
Example
例子
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>
回答by Joshua Robinson
You can't with inline styling alone. Do not recommend reimplementing CSS features in JavaScript we already have a language that is extremely powerful and incredibly fast built for this use case -- CSS. So use it! Made Style Itto assist.
你不能单独使用内联样式。不建议在 JavaScript 中重新实现 CSS 功能,我们已经有一种非常强大且非常快的语言,专为此用例构建——CSS。所以使用它!Made Style It来协助。
npm install style-it --save
npm install style-it --save
Functional Syntax(JSFIDDLE)
函数式语法( 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;
JSX Syntax(JSFIDDLE)
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;
回答by hlkughl
I'd use onMouseOver & onMouseOut. Cause in React
我会使用 onMouseOver 和 onMouseOut。反应中的原因
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.
onMouseEnter 和 onMouseLeave 事件从离开的元素传播到进入的元素,而不是普通的冒泡,并且没有捕获阶段。
Here it is in the React documentationfor mouse events.
这是鼠标事件的 React文档。
回答by fkilaiwi
Use Radium!
使用镭!
The following is an example from their 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'
}
};

