双击并单击ReactJS组件

时间:2016-02-18 20:07:59

标签: events reactjs double-click

我有一个ReactJS组件,我希望在单击和双击时有不同的行为。

我读到了这个问题: onClick works but onDoubleClick is ignored on React component

<Component
    onClick={this.onSingleClick}
    onDoubleClick={this.onDoubleClick} />

我自己尝试过,似乎你无法在ReactJS组件上同时注册单击和双击。

我不确定这个问题的解决方案。我不想使用计时器,因为我将在我的页面上有8个这样的单个组件。

在这个内部组件中有另一个内部组件处理双击情况会是一个很好的解决方案吗?

编辑:

我尝试过这种方法,但它在渲染功能中不起作用。

render (

    let props = {};

    if (doubleClick) {
        props.onDoubleClick = function
    } else {
        props.onClick = function
    }
    <Component
        {...props} />
);

4 个答案:

答案 0 :(得分:2)

这是 最快 最短 的答案:

基于类的组件

let timer;

class DoubleClick extends React.Component {
    onClickHandler = event => {
        clearTimeout(timer);
        if (event.detail === 1) {
            timer = setTimeout(this.props.onClick, 200)
        } else if (event.detail === 2) {
            this.props.onDoubleClick()
        }
    }

    render() {
        return (
            <div onClick={this.onClickHandler}>
                {this.props.children}
            </div>
        )
    }
}

功能组件

let timer;

const DoubleClick = ({ onClick = () => { }, onDoubleClick = () => { }, children }) => {
    const onClickHandler = event => {
        clearTimeout(timer);
        if (event.detail === 1) {
            timer = setTimeout(onClick, 200)
        } else if (event.detail === 2) {
            onDoubleClick()
        }
    }

    return (
        <div onClick={onClickHandler}>
            {children}
        </div>
    )
}

演示

var timer;

function onClick(event) {
  clearTimeout(timer);
  
  if (event.detail === 1) {
    timer = setTimeout(() => {
      console.log("SINGLE CLICK");
    }, 200)

  } else if (event.detail === 2) {
    console.log("DOUBLE CLICK");
  }
}

document.querySelector(".demo").onclick = onClick;
.demo {
  padding: 20px 40px;
  background-color: #eee;
  user-select: none;
}
<div class="demo">
  Click OR Double Click Here
</div>

答案 1 :(得分:1)

我知道这是一个老问题,我只是在黑暗中拍摄(没有测试代码,但我确信它应该可以工作)但也许这对某人有帮助。

render() {
    let clicks = [];
    let timeout;

    function singleClick(event) {
        alert("single click");
    }

    function doubleClick(event) {
        alert("doubleClick");
    }

    function clickHandler(event) {
        event.preventDefault();
        clicks.push(new Date().getTime());
        window.clearTimeout(timeout);
        timeout = window.setTimeout(() => {
            if (clicks.length > 1 && clicks[clicks.length - 1] - clicks[clicks.length - 2] < 250) {
                doubleClick(event.target);
            } else {
                singleClick(event.target);
            }
        }, 250);
    }

    return (
        <a onClick={clickHandler}>
            click me
        </a>
    );
}

我将很快对此进行测试,以防更新或删除此答案。

缺点是毫无疑问,我们有一个250ms的定义“双击速度”,用户需要完成,所以它不是一个漂亮的解决方案,可能会阻止一些人使用双点击。

当然,单击只能延迟250毫秒,但不可能这样做,否则你必须等待双击...

答案 2 :(得分:0)

为什么要在渲染函数中描述这些事件处理程序?试试这种方法:

const Component = extends React.Component {

  constructor(props) {
      super(props);
  }

  handleSingleClick = () => {
    console.log('single click');
  }

  handleDoubleClick = () => {
    console.log('double click');
  }

  render() {
    return (
      <div onClick={this.handleSingleClick}  onDoubleClick={this.handleDoubleClick}>
      </div>
    );
  }
};

答案 3 :(得分:0)

我一直在做的简单示例

文件:withSupportDoubleClick.js

let timer
let latestTouchTap = { time: 0, target: null }

export default function withSupportDoubleClick({ onDoubleClick = () => {}, onSingleClick = () => {} }, maxDelay = 300) {
  return (event) => {
    clearTimeout(timer)

    const touchTap = { time: new Date().getTime(), target: event.currentTarget }

    const isDoubleClick =
      touchTap.target === latestTouchTap.target && touchTap.time - latestTouchTap.time < maxDelay

    latestTouchTap = touchTap

    timer = setTimeout(() => {
      if (isDoubleClick) onDoubleClick(event)
      else onSingleClick(event)
    }, maxDelay)
  }
}

文件:YourComponent.js

import React from 'react'
import withSupportDoubleClick from './withSupportDoubleClick'

export default const YourComponent = () => {

  const handleClick = withSupportDoubleClick({
    onDoubleClick: (e) => {
      console.log('double click', e)
    },
    onSingleClick: (e) => {
      console.log('single click', e)
    },
  })

  return (
    <div
      className="cursor-pointer"
      onClick={handleClick}
      onTouchStart={handleClick}
      tabIndex="0"
      role="button"
      aria-pressed="false"
    >
      Your content/button...
    </div>
  )
}
  • onTouchStart开始是当用户触摸元素时触发的触摸事件。