akiran / react-slick

React carousel component
http://react-slick.neostack.com/
MIT License
11.73k stars 2.1k forks source link

Drag Auto Trigger Click Event #1952

Open xunkaisummer opened 3 years ago

xunkaisummer commented 3 years ago

Actively trigger a click event which I add on the img element when I drag the img element. I hope It can not trigger a click event when I drag, but the distance of dragging is small

VadimSvirdoff commented 3 years ago

Hi, @xunkaisummer, could you attach code snippet or video with reproduced problem.

xunkaisummer commented 3 years ago

Hi, @xunkaisummer, could you attach code snippet or video with reproduced problem.

hi @VadimSvirdoff , code is here, When I drag the img which I add click event on, It trigger a click event

` import React, { Component } from 'react'; import Slider from 'react-animated-slider'; import 'react-animated-slider/build/horizontal.css';

const content = [ { image: 'https://i.imgur.com/ZXBtVw7.jpg' }, { image: 'https://i.imgur.com/DCdBXcq.jpg' }, { image: 'https://i.imgur.com/DvmN8Hx.jpg' } ]; class App extends Component { render() { return (

{content.map((item, index) => (
{ console.log('click'); }} > {''}
      ))}
    </Slider>
  </div>
);

} }

export default App; `

reeezaaa commented 3 years ago

hi @xunkaisummer you can set onClick and onMouseDown to div live example: codesandbox or

  <div
      key={index}
      onMouseDown={(e) => handleOnMouseDown(e)}
      onClick={(e) => handleOnClick(e)}
  >

  const [ClientXonMouseDown, setClientXonMouseDown] = useState();
  const [ClientYonMouseDown, setClientYonMouseDown] = useState();
  const handleOnMouseDown = (e) => {
    e.preventDefault();
    setClientXonMouseDown(e.clientX);
    setClientYonMouseDown(e.clientY);
  };

  const handleOnClick = (e) => {
    e.stopPropagation();
    if (ClientXonMouseDown !== e.clientX || ClientYonMouseDown !== e.clientY) {
      e.preventDefault();
    }
  }; 
jc3lee commented 3 years ago

hi @xunkaisummer , I was working on the same issue tonight and I think I found a solution using built-in slick functions. I had the same idea as @artuswo443 on issue #1956 to use onSwipe to detect when the swipe start. But there's no swipe end function. What I found that worked for me was to use afterChange to detect end of swipe.

Result here (twitter post)

Code:

  let isSwiping = false

  function updateSwipeState(state) {
    isSwiping = state
  }

  function handleClick() {
    if (isSwiping) {
      return
    }
    // do something onClick
  }

  return (
      <Slider  afterChange={ () => updateSwipeState(false) } onSwipe: { () => updateSwipeState(true) }>
        {
          posts.map(p => getBlogComponent(p, handleClick))
        }
      </Slider>
    </div>
  )
  1. create a isSwiping boolean.
  2. onSwipe updates isSwiping to true
  3. afterChange updates isSwiping to false
  4. in onClick add a condition to return if isSwiping is true
mihanizm56 commented 3 years ago

seems like the lib need one more method processing this (actualy very popular) case =)

tigrr commented 2 years ago

The simplest case when this happens is if you have links inside sliders. Not arbitrary elements with onClick listeners, but plain old links. Dragging should prevent the "mouseup" event (as it obviously does with "touchend") from within the slider without any extra setup.

mihaiblaga89 commented 3 months ago

had the same issue, @jc3lee idea isn't working anymore, onSwipe now only fires after the swipe. However I managed to find an undocumented prop that is perfect for this, swipeEvent. Replace onSwipe with swipeEvent and it should work.

hi @xunkaisummer , I was working on the same issue tonight and I think I found a solution using built-in slick functions. I had the same idea as @artuswo443 on issue #1956 to use onSwipe to detect when the swipe start. But there's no swipe end function. What I found that worked for me was to use afterChange to detect end of swipe.

Result here (twitter post)

Code:

  let isSwiping = false

  function updateSwipeState(state) {
    isSwiping = state
  }

  function handleClick() {
    if (isSwiping) {
      return
    }
    // do something onClick
  }

  return (
      <Slider  afterChange={ () => updateSwipeState(false) } onSwipe: { () => updateSwipeState(true) }>
        {
          posts.map(p => getBlogComponent(p, handleClick))
        }
      </Slider>
    </div>
  )
  1. create a isSwiping boolean.
  2. onSwipe updates isSwiping to true
  3. afterChange updates isSwiping to false
  4. in onClick add a condition to return if isSwiping is true