REACT:我们如何在画布上检测到用户点击?

时间:2018-03-09 13:50:53

标签: javascript image reactjs canvas click

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

我有一个用例需要在画布上检测鼠标坐标,感谢@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而不是1个日志:

enter image description here

代码是:

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

2 个答案:

答案 0 :(得分:1)

这是由于事件传播以及您正在整个文档上收听click事件而发生的。

点击<img>不仅会为图片生成click事件,还会为两个包装<div>元素生成事件。文档捕获了这两个,这就是它被记录两次的原因。如果您记录e.target,您可以看到哪个元素触发了事件。

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

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

答案 1 :(得分:1)

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

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