Дважды щелкните и щелкните компонент ReactJS

У меня есть компонент ReactJS, который я хочу вести по-разному при одном и двойном щелчке.

Я прочитал этот вопрос: onClick работает, но onDoubleClick игнорируется в React компонент

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

И я попробовал это сам, и кажется, что вы не можете зарегистрировать как одиночный, так и двойной щелчок на компоненте ReactJS.

Я не уверен в хорошем решении этой проблемы. Я не хочу использовать таймер, потому что на моей странице будет 8 таких отдельных компонентов.

Было бы хорошим решением иметь еще один внутренний компонент внутри этого, чтобы иметь дело с ситуацией двойного щелчка?

Редактировать:

Я попробовал этот подход, но он не работает в функции рендеринга.

render (

    let props = {};

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

person user1261710    schedule 18.02.2016    source источник
comment
Просто предложение, но двойные щелчки легко обрабатываются с помощью RxJS gist.github.com/anthonybrown/a5ef9148bd101157d922   -  person azium    schedule 18.02.2016
comment
В ответе, на который вы ссылаетесь, уже говорится о том, что привязка к событию click и dbclick для одного элемента dom нецелесообразна. Двойной щелчок не является обычным взаимодействием пользователей в Интернете, поэтому большинство пользователей не знают, что вы можете. Использование другого метода взаимодействия, вероятно, является лучшим подходом.   -  person PetersenDidIt    schedule 19.02.2016
comment
@PetersenDidIt да, я тоже думаю, что это странно, но они хотят, чтобы пользователь знал, что он щелкнул только один раз? Есть настройка двойного клика.   -  person user1261710    schedule 19.02.2016
comment
Я добавил ответ на вопрос, который вы связали, показав, как вы можете это сделать.   -  person Jeff Fairley    schedule 09.08.2016


Ответы (4)


Вот самый быстрый и самый короткий ответ:

КОМПОНЕНТ НА ​​ОСНОВЕ КЛАССА

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>

person Anatol    schedule 01.12.2020

Я знаю, что это старый вопрос, и я только стреляю в темноту (код не тестировал, но я уверен, что он должен работать), но, возможно, это кому-то поможет.

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>
    );
}

Я собираюсь проверить это в ближайшее время и в случае обновления или удаления этого ответа.

Недостатком, без сомнения, является то, что у нас есть определенная «скорость двойного щелчка» в 250 мс, которую должен выполнить пользователь, поэтому это не очень красивое решение и может помешать некоторым людям использовать двойной щелчок.

Конечно, одиночный щелчок работает только с задержкой в ​​250 мс, но иначе это сделать невозможно, вам нужно как-то дождаться двойного щелчка...

person Philipp Wrann    schedule 15.03.2018
comment
Большое спасибо :-). Работал для меня! - person Vikas Chauhan; 18.02.2019

Простой пример, который я делал.

Файл: 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 start — это событие касания, которое срабатывает, когда пользователь касается элемента.
person Ricardo Canelas    schedule 02.12.2020

Почему вы описываете обработчик этих событий внутри функции рендеринга? Попробуйте этот подход:

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>
    );
  }
};
person ShaDeRzz    schedule 11.09.2019
comment
Это зарегистрирует одиночный и двойной щелчок по двойному щелчку. - person azz0r; 24.04.2020