Skip to content
This repository has been archived by the owner on May 5, 2022. It is now read-only.

Clickable slide: don't allow clit during "sliding" #70

Open
kiuKisas opened this issue Jun 9, 2021 · 1 comment
Open

Clickable slide: don't allow clit during "sliding" #70

kiuKisas opened this issue Jun 9, 2021 · 1 comment

Comments

@kiuKisas
Copy link

kiuKisas commented Jun 9, 2021

Hey, I have a slider made of a link. When I grab the slider to move it, it click on my slide when I release. It shouldn't

@ErickRuano
Copy link

Hello @kiuKisas. I got this exact same issue while using on:click on the carousel slides.

This svelte-carousel is a wrapper for a vanilla js library called Siema. Sadly, Siema is no longer under development/maintenance by the author. I came up with a simple solution which I hope works for you too.

Quick solution:

1. Create a preciseClick.js file with the following code:

export default (node, threshold = 8) => {
  // Set initial values
  let moved = false,
    initialPosition = { x: null, y: null };

  const handleMousedown = (e) => {
    console.log("mousedown");
    e.preventDefault();
    initialPosition.x = e.x;
    initialPosition.y = e.y;
    moved = false;
  };

  const handleMouseup = (e) => {
    console.log("mouseup");
    if (
      !(initialPosition.x + threshold >= e.x) ||
      !(initialPosition.x - threshold <= e.x)
    ) {
      moved = true;
    }

    if (
      !(initialPosition.y + threshold >= e.y) ||
      !(initialPosition.y - threshold <= e.y)
    ) {
      moved = true;
    }
  };

  const handleClick = (e) => {
    if (moved) {
      e.preventDefault();
    } else {
      const preciseClickEvent = new CustomEvent("preciseClick", {
        detail: { moved, initialPosition },
      });
      node.dispatchEvent(preciseClickEvent);
    }
  };

  node.addEventListener("click", handleClick);
  node.addEventListener("mousedown", handleMousedown);
  node.addEventListener("mouseup", handleMouseup);

  return {
    destroy() {
      node.removeEventListener("click", handleClick);
      node.removeEventListener("mousedown", handleMousedown);
      node.removeEventListener("mouseup", handleMouseup);
    },
  };
};

2. Then use on your carousel slides like this:

<script>
	 import Carousel from '@beyonk/svelte-carousel'
	 import preciseClick from './preciseClick.js'
</script>
<Carousel dots={false}>
	<!-- Default threshold is 8	 -->
  <a href="https://google.com" class="slide-content" use:preciseClick>Slide 1</a>
	<!-- You can set a different value for threshold like this	 -->
  <a href="https://google.com" class="slide-content" use:preciseClick={24}>Slide 2</a>
	<!--  It should work on	a <a> contained in slide-content too -->
  <div class="slide-content">
		<a href="https://google.com" use:preciseClick>Slide 4</a>
	</div>
	<!-- if you want to do something when the click is between the threshold listen to this custom event instead of 'click' 	-->
	<div class="slide-content" use:preciseClick on:preciseClick={()=>{ alert('clicked') }}>
		Some content
	</div>
</Carousel>

How it works

I created a Svelte action that listens to the mousedown and mouseup events over a certain element, i.e. a carousel slide. On mousedown it will set a boolean 'moved' flag to false and will store the x and y position of the event.

On mouseup it will check if the cursor moved by a variable amount of pixels. If it did, the 'moved' flag is set to true, else it will remain false.

This flag is then evaluated to decide whether an event should be emitted:

  • If the flag was set to true when the click event happens then the default click behavior will be prevented
  • If the flag was set to false, the click behavior will be as expected. Also a custom 'preciseClick' event will fire in case you need to do something when the click is between the threshold.

REPL demo:
https://svelte.dev/repl/ac2a89e08f1d4600a88da743dcede207?version=3.38.3

I might submit a pull request with a built-in implementation of this solution later although I'm not sure if this is part of the intended scope or responsibility of this svelte-carousel component. For the time being you could use this action.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants