如何悬停在 ReactJS?-在鼠标离开没有注册在快速悬停

在执行内联样式时,如何在 ReactJS 中实现悬停事件或活动事件?

我发现 onMouseEnter,onMouseleave 方法有问题,所以希望有其他方法可以解决这个问题。

具体来说,如果您非常快速地将鼠标移到一个组件上,则只注册 onMouseEnter 事件。OnMouseleave 从不触发,因此不能更新状态... ... 让组件看起来好像仍然悬停在上面。如果尝试模仿“ : active”css 伪类,我注意到了同样的情况。如果单击速度非常快,则只注册 onMouseDown 事件。OnMouseUp 事件将被忽略... ... 使组件看起来是活动的。

下面的 JSFiddle 显示了这个问题: https://jsfiddle.net/y9swecyu/5/

有问题的 JSFiddle 视频: https://vid.me/ZJEO

密码:

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')
)
381401 次浏览

如果你可以制作一个小的演示,展示 onMouseEnter/onMouseleave 或 onMouseDown/onMouseUp bug,那么将它发布到 ReactJS 的问题页面或邮件列表上是值得的,只是为了提出问题,并听听开发人员对此有什么看法。

在您的用例中,您似乎暗示 CSS: hover 和: active 状态对于您的目的来说已经足够了,所以我建议您使用它们。CSS 的数量级比 Javascript 更快更可靠,因为它是直接在浏览器中实现的。

但是,不能以内联样式指定: hover 和: active 状态。您可以为元素分配一个 ID 或类名称,并在样式表中编写样式(如果它们在应用程序中是常量的话) ,或者在动态生成的 <style>标记中编写样式。

下面是后一种技术的一个例子: https://jsfiddle.net/ors1vos9/

你试过这些吗?

输入 OnMouseMove onMouseOut onMouseOver onMouseUp

合成事件

它还提到了以下内容:

React 规范化事件,使它们在不同的浏览器中具有一致的属性。

下面的事件处理程序由冒泡阶段的事件触发。要为捕获阶段注册事件处理程序,请将 Capture 附加到事件名称; 例如,不使用 onClick,而是使用 onClickCapture 在捕获阶段处理 click 事件。

使用

以下是他们网站上的一个例子:

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'
}
};

当我在一个禁用按钮上侦听 onMouseleave 事件时,也遇到了同样的问题。我通过侦听包装禁用按钮的元素上的本机滑鼠离开事件来解决这个问题。

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>
);
}

这是小提琴 https://jsfiddle.net/qfLzkz5x/8/

我在调用 onMouseEnter 时遇到过类似的问题,但有时相应的 onMouseleave 事件没有被激活,这里有一个对我很有用的解决方案(它部分依赖于 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>
);
}
});

参见 jsfiddle: http://jsfiddle.net/qtbr5cg6/1/


为什么会发生这种情况(在我的例子中) : 当单击这个项目时,我正在运行一个 jQuery 滚动动画(通过 $('#item').animate({ scrollTop: 0 }))。因此,光标不会“自然地”离开项目,而是在 JavaScript 驱动的动画中... ... 在这种情况下,onMouseleave 没有被 React (React 15.3.0,Chrome51,Desktop)正确地激活

您不能单独使用内联样式。不建议在 JavaScript 中重新实现 CSS 特性,我们已经有了一种为这个用例构建的非常强大、非常快速的语言—— CSS。那就好好利用!让 风格协助。

npm install style-it --save

功能语法 (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 语法 (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;

以前的答案很令人困惑。您不需要反应状态来解决这个问题,也不需要任何特殊的外部库。它可以通过纯 css/sass 来实现:

风格:

.hover {
position: relative;


&:hover &__no-hover {
opacity: 0;
}


&:hover &__hover {
opacity: 1;
}


&__hover {
position: absolute;
top: 0;
opacity: 0;
}


&__no-hover {
opacity: 1;
}
}

反应组件

一个简单的 Hover纯渲染函数:

const Hover = ({ onHover, children }) => (
<div className="hover">
<div className="hover__no-hover">{children}</div>
<div className="hover__hover">{onHover}</div>
</div>
)

用法

然后像这样使用它:

    <Hover onHover={<div> Show this on hover </div>}>
<div> Show on no hover </div>
</Hover>

我知道自从这个问题被提出已经有一段时间了,但是我遇到了与 onMouseleave ()不一致的相同问题 我所做的就是在整个菜单中使用 onMouseOut ()和 onmouseleave,它是可靠的,并且每次我测试它时都能正常工作。 我在文件里看到了事件: https://facebook.github.io/react/docs/events.html#mouse-events 下面是一个使用 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>
)
}

我个人使用 风格的内联风格在反应或保持我的风格单独在一个 CSSSASS文件..。

但是如果你真的有兴趣在线做这件事,看看这个库,我分享了下面的一些用法:

在组件 :

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;

产出 :

    <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>


你也可以在 CSS 中使用 JavaScript 变量,如下所示:

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;

结果如下:

<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>

一个称为 styled-components的软件包可以用 优雅的方式解决这个问题。

参考文献

  1. Glen Maddern-Styling React Apps with Styled Component

例子

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>

注意: 这个回答是针对这个问题的前一个版本,问题提出者试图使用 JavaScript 来应用 CSS 样式... 这可以简单地用 CSS 来完成。

一个简单的仅 css解决方案。

对于应用基本样式,CSS 在99% 的情况下比 JS 解决方案更简单、性能更好。(尽管比较现代的 CSS-in-JS 解决方案,例如。反应元件等ーー可以说更容易维护。)

运行此代码片段以查看它的运行情况..。

.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>

您可以使用 onMouseOver={this.onToggleOpen}onMouseOut={this.onToggleOpen}对组件进行反复思考

我会使用 onMouseOver & onMouseOut:

OnMouseEnter 和 onMouseleave 事件从左边的元素传播到正在输入的元素,而不是普通的冒泡,并且没有捕获阶段。

这里是鼠标事件的 React 文件

悬停是一个 CSS的功能,它与 CSS一边的应用程序,所以做它的正确方式是如此之多的乐趣。简单地说,当我需要对 React 应用程序中的元素进行悬停时,首先在 CSS文件中创建一个类,然后将创建的类添加到元素的 className 中。我遵循的步骤是:

  1. 创建一个 CSS文件,除非您有 index.css

  2. 创建一个启用了 hover伪类的类

    . hover _ _ effect: hover {}

  3. 添加您需要的效果

    . hover _ _ effect: hover { 背景色: rgb (255,255,255) ; 颜色: rgb (0,0,0) ; }

  4. 然后将 hover__effect添加到类的组件中,当鼠标指针悬停在该组件上时,该组件应该是不同的

    盘旋

请检查我的 沙盒为一个现场演示。