当你进行内联样式时,如何在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')
)
你试过这些吗?
onMouseDown onMouseEnter onMouseLeave
onMouseMove onMouseOut onMouseOver onMouseUp
https://facebook.github.io/react/docs/events.html
它还提到了以下内容:
React规范化事件,以便它们在不同的浏览器中具有一致的属性。
下面的事件处理程序由冒泡阶段的事件触发。要为捕获阶段注册事件处理程序,请将Capture附加到事件名称;例如,您可以使用onClickCapture来处理捕获阶段中的click事件,而不是使用onClick。
调用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驱动的动画期间...并且在这种情况下,React没有正确地触发onMouseLeave(React 15.3.0,Chrome 51,桌面)
我知道已经有一段时间了,因为这个问题被问到但是我遇到了与onMouseLeave()不一致的问题。我所做的是使用onMouseOut()作为下拉列表和鼠标离开整个菜单,它是我每次测试都可靠并且可以工作。我在文档中看到了这里的事件: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>
)
}
我个人在React中使用Style It作为内联样式,或者将我的样式分别保存在CSS或SASS文件中......
但是,如果你真的有兴趣在线实现,看看图书馆,我分享下面的一些用法:
在组件中:
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中的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>
我可以建议你一个容易让我理解的例子,我在React JS中使用情感来给出样式。在这里你可以找到它的更多信息https://emotion.sh/docs/introduction希望这对你有所帮助。
const secondStyle = css`
background: blue;
height: 20px;
width: 20px;
:hover {
cursor: pointer;
background: red;
`
function myComponent() {
return (
<div className={firstStyle}>
<button className={secondStyle}>Submit<button>
)
}
以前的答案非常令人困惑。您不需要react-state来解决这个问题,也不需要任何特殊的外部库。它可以通过纯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>
如果您可以生成一个显示onMouseEnter / onMouseLeave或onMouseDown / onMouseUp错误的小型演示,那么将它发布到ReactJS的问题页面或邮件列表是值得的,只是为了提出问题并听取开发人员对此有何看法。
在您的用例中,您似乎暗示CSS:hover和:active状态足以满足您的目的,因此我建议您使用它们。 CSS比Javascript更快,更可靠,因为它直接在浏览器中实现。
但是,:hover和:无法在内联样式中指定活动状态。您可以做的是为元素分配ID或类名,并在样式表中编写样式,如果它们在您的应用程序中有些不变,或者在动态生成的<style>
标记中。
这是后一种技术的一个例子:https://jsfiddle.net/ors1vos9/
你可以使用onMouseOver={this.onToggleOpen}
和onMouseOut={this.onToggleOpen}
来反复思考组件
我刚刚在禁用按钮上监听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>
);
}
一个名为styled-components
的包可以以ELEGANT的方式解决这个问题。
参考
例
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
-only solution.对于应用基本样式,CSS解决方案更简单,更高效,JS解决方案99%的时间。 (虽然更现代的CSS-in-JS解决方案 - 例如React Components等 - 可以说更易于维护。)
运行此代码段以查看其运行情况...
.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>
你不能单独使用内联样式。不建议在JavaScript中重新实现CSS功能,我们已经拥有一种非常强大的语言,并且非常快速地构建了这个用例 - CSS。所以用吧!让Style It协助。
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;
使用Radium!
以下是他们网站上的一个例子:
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'
}
};