代码之家  ›  专栏  ›  技术社区  ›  R. Kohlisch

防止双击被解释为两次单击?

  •  1
  • R. Kohlisch  · 技术社区  · 6 年前

    我有以下相当简单的React类:

    import React from "react"
    
    export default class DoubleClick extends React.Component {  
    
      constructor(props) {
        super(props);
        this.state = {
        };
        this.handleClick = this.handleClick.bind(this);
        this.handleDoubleClick = this.handleDoubleClick.bind(this);
      }
      handleClick() {
        console.log("Click");
      }
      handleDoubleClick() {
        console.log("Double Click");
      }
      render() {
        return (
          <div style={{backgroundColor: 'pink'}}>
              <div onClick={this.handleClick}> 
                <span onDoubleClick={this.handleDoubleClick}> Hello </span> 
                <span onDoubleClick={this.handleDoubleClick}> world. </span>
              </div>
          </div>
        );
      }
    } 
    

    当有人单击外部div时,我想打电话 handleClick ,当有人双击我要调用的任何内部跨距时 handleDoubleClick ,但不是 把手舔 对于外部div也是如此。

    但是,每当我双击时, handleDoubleClick() 被称为, 但是 把手舔 也称为,即两次。

    我想打电话 handleClick() 仅当我单击时,但确实 双击-这可能吗?

    2 回复  |  直到 3 年前
        1
  •  4
  •   Zach Schneider    6 年前

    我有一个HOC,用于近似您要查找的内容:

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    
    export default class DoubleClick extends Component {
      constructor(props) {
        super(props);
        this.onClick = this.onClick.bind(this);
        this.onDoubleClick = this.onDoubleClick.bind(this);
        this.timeout = null;
      }
    
      onClick(e) {
        e.preventDefault();
    
        if(this.timeout === null) {
          this.timeout = window.setTimeout(() => {
            this.timeout = null;
            this.props.onClick();
          }, 300);
        }
      }
    
      onDoubleClick(e) {
        e.preventDefault();
        window.clearTimeout(this.timeout);
        this.timeout = null;
        this.props.onDoubleClick();
      }
    
      render() {
        const { onClick, onDoubleClick, children, ...childProps } = this.props;
        const props = Object.assign(childProps, { onClick: this.onClick, onDoubleClick: this.onDoubleClick });
        return React.cloneElement(children, props);
      }
    }
    
    DoubleClick.propTypes = {
      onClick: PropTypes.func.isRequired,
      onDoubleClick: PropTypes.func.isRequired,
      children: PropTypes.element.isRequired,
    };
    

    使用方式如下:

    <DoubleClick onClick={clickHandler} onDoubleClick={doubleClickHandler}>
      <button>Click or double click me</button>
    </DoubleClick>
    

    当收到第一次单击时,它会设置300ms超时。如果在300ms内未收到第二次单击,则 onClick 将调用prop。如果在300ms内收到第二次单击,则 onDoubleClick 将调用prop,并取消超时,以便 onClick公司 不会开火。

    不用说,这是一个不完美的近似值,但我发现它在实践中是一个足够令人满意的用户体验。

        2
  •  0
  •   eXcoo    6 年前

    正如其他人所说,在没有超时的情况下(我认为),双击孩子就不可能在家长身上执行单击事件。

    如果您可以牺牲500ms的用户体验部分,直到点击被识别为非双击,那么您可以使用超时。

    constructor(props) {
        super(props);
        this.state = {
        };
        this.handleClick = this.handleClick.bind(this);
        this.handleDoubleClick = this.handleDoubleClick.bind(this);
    
        // hack doubleclick
        this.doubleClickTimeout = 500; // default doubleclick timeout
        this.clickedTimeout = null;
      }
      handleClick(ev) {
        if (!this.clickedTimeout) {
          this.clickedTimeout = setTimeout(() => {
            this.clickedTimeout = null;
            // do your stuff here
            console.log('Clicked');
          }, this.doubleClickTimeout);
        }
    
    
      }
      handleDoubleClick() {
        clearTimeout(this.clickedTimeout);
        this.clickedTimeout = null;
        console.log("Double Click");
    
      }
      render() {
        return (
          <div style={{backgroundColor: 'pink'}}>
              <div onClick={this.handleClick}>
                <span onDoubleClick={this.handleDoubleClick}> Hello </span>
                <span onDoubleClick={this.handleDoubleClick}> world. </span>
              </div>
          </div>
        );
      }