你如何在ReactJS中盘旋? - onMouseLeave在快速悬停期间未注册

Hel*_*ope 78 javascript css mouseevent dom-events 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')
)
Run Code Online (Sandbox Code Playgroud)

Elo*_*ito 64

你试过这些吗?

onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp

https://facebook.github.io/react/docs/events.html

它还提到了以下内容:

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

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

  • 只是提到 onMouseEnter 和 onMouseLeave,来自文档:`onMouseEnter 和 onMouseLeave 事件从被留下的元素传播到被输入的元素,而不是普通的冒泡,并且没有捕获阶段。` (9认同)

dre*_*lse 35

以前的答案非常令人困惑.您不需要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;
  }
}
Run Code Online (Sandbox Code Playgroud)

反应组件

一个简单的Hover纯渲染功能:

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

用法

然后像这样使用它:

    <Hover onHover={<div> Show this on hover </div>}>
        <div> Show on no hover </div>
    </Hover>
Run Code Online (Sandbox Code Playgroud)

  • 这是这个问题的最佳答案。 (3认同)

小智 15

您可以使用onMouseOver={this.onToggleOpen}onMouseOut={this.onToggleOpen}在组件上反复 使用


Tob*_*bia 11

如果您可以生成一个显示onMouseEnter/onMouseLeave或onMouseDown/onMouseUp错误的小型演示,那么将它发布到ReactJS的问题页面或邮件列表是值得的,只是为了提出问题并听取开发人员对此有何看法.

在您的用例中,您似乎暗示CSS:hover和:active状态足以满足您的目的,因此我建议您使用它们.CSS比Javascript更快,更可靠,因为它直接在浏览器中实现.

但是,:hover和:无法在内联样式中指定活动状态.您可以做的是为元素分配ID或类名,并在样式表中编写样式,如果它们在应用程序中有些不变,或者在动态生成的<style>标记中.

以下是后一种技术的示例:https://jsfiddle.net/ors1vos9/


Cor*_*son 9

我刚刚在禁用按钮上监听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>
    );
}
Run Code Online (Sandbox Code Playgroud)

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


Bea*_*ith 8

注意:此答案是针对此问题的先前版本的,在该版本中,问题询问者正在尝试使用JavaScript来应用CSS样式……这可以通过CSS轻松完成。

一个简单的css解决方案。

对于应用基本样式,CSS比99%的解决方案更简单,性能更高。(尽管更现代的CSS-in-JS解决方案(例如React组件等)可以说更具维护性。)

运行此代码段以查看实际效果…

.hover-button .hover-button--on,
.hover-button:hover .hover-button--off {
  display: none;
}

.hover-button:hover .hover-button--on {
  display: inline;
}
Run Code Online (Sandbox Code Playgroud)
<button class='hover-button'>
  <span class='hover-button--off'>Default</span>
  <span class='hover-button--on'>Hover!</span>
</button>
Run Code Online (Sandbox Code Playgroud)

  • 这不能回答问题。 (10认同)

hlk*_*hl 7

我会使用 onMouseOver 和 onMouseOut。React 中的原因:

onMouseEnter 和 onMouseLeave 事件从离开的元素传播到进入的元素,而不是普通的冒泡,并且没有捕获阶段。

这是鼠标事件的 React文档


Kar*_* Xu 5

叫一个包styled-components可以在解决这个问题的优雅方式。

参考

  1. Glen Maddern-使用样式化组件对React Apps进行样式化

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'));
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)