【问题标题】:REACT: How could we detect user click on canvas?反应:我们如何检测用户在画布上的点击?
【发布时间】:2018-03-09 13:50:52
【问题描述】:

您好,感谢您阅读此问题。

我有一个用例,我需要在画布上检测鼠标坐标,感谢@Carlos Martinez:getting mouse coordinates in React 它按预期工作。

我试图更进一步,检测用户是否点击了画布,然后将它放在 h2 上,使用状态,并记录它;这是我尝试过的代码:

import React from 'react';


class Canvas extends React.Component {
    //A canvas to display images with a title


    constructor(props) {
        super(props);

        this.state = {x: 0, y: 0, inside: ''};

        this.handleClick = this.handleClick.bind(this);
    }

    _onMouseMove(e) {
        this.setState({x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY});
    }

    componentDidMount() {
        document.addEventListener('click', this.handleClick);
    }

    componentWillUnmount() {
        document.removeEventListener('click', this.handleClick);
    }

    handleClick(e) {
        console.log('INSIDE');
        this.setState({inside: 'inside'});
    }

    render() {

        const {x, y, inside} = this.state;

        return (
            <div className="previewComponent">
                <div className="imgPreview">
                    {this.props.title}
                    <img src={this.props.image} alt="" onMouseMove={this._onMouseMove.bind(this)}
                         onClick={this.handleClick.bind(this)}/>
                    <h1>Mouse coordinates: {x} {y}</h1>
                    <h2>Inside?: {inside}</h2>
                </div>
            </div>
        )
    }
}

export {Canvas};

我希望它只记录一次,并将其放在 h2 标记上。

但是,意外地它记录了 INSIDE,然后又记录了两个 INSIDE:

INSIDE
2 Canvas.js:29 INSIDE

你能解释一下这种行为吗?此外,如果您有一些修复它的提示,并且每次点击只打印一个日志,我们将不胜感激!

编辑:

我尝试过@Or B 的答案,我理解它,但是它看起来仍然显示相同的行为,3 个 INSIDE 日志而不是一个:

代码是:

 handleClick(e) {
        e.stopPropagation();
        console.log('INSIDE');
        this.setState({inside: 'inside'});
    }

【问题讨论】:

    标签: javascript image reactjs canvas click


    【解决方案1】:

    这是由于事件传播以及您在整个文档中监听click 事件的事实。

    单击&lt;img&gt; 不仅会为图像生成click 事件,还会为两个包裹&lt;div&gt; 元素生成事件。这两个被文档捕获,这就是它被记录两次的原因。如果您记录e.target,您可以看到哪个元素触发了该事件。

    为了防止它传播,请使用event.stopPropagation()

    handleClick(e) {
            e.stopPropagation();
            console.log('INSIDE');
            this.setState({inside: 'inside'});
        }
    

    【讨论】:

    • 谢谢@Or B 你的回答帮助了我,我已经编辑了帖子,因为行为仍然相同。
    • @Enoy 如果您打印e.target,会记录什么?您监听整个文档的事件是否有特殊原因?
    【解决方案2】:

    这是因为点击处理程序被调用了两次。一次通过画布onClick 组件,第二次通过componentWillMount 函数内的点击处理程序。此外,由于document.addEventListener 部分,componentWillMount 函数会监听整个文档的点击。我会简单地使用componentWillMount 来设置状态。

    删除document.addEventListener 部分,它应该很好去。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多