svelte-scrolling icon indicating copy to clipboard operation
svelte-scrolling copied to clipboard

why use touchstart to trigger the jump ?

Open robthepaper opened this issue 9 months ago • 0 comments

whe using touchdevice, and scrolling down with touch, if we touch the link, it will jump to its anchor. I have mad a custom ScrollTo.ts to trigger the jump only on tap

`import { get } from 'svelte/store' import { elements } from 'svelte-scrolling/dist/store' // Adjust based on your project's structure import { getGlobalOptions } from 'svelte-scrolling/dist/internal/globalOptions' // Same here import type { ScrollToOptions } from 'svelte-scrolling/dist/types/options' // Ensure correct type import import { sanitize, getElement, getPosition } from 'svelte-scrolling/dist/shared/utils' // Copy these utilities if needed import scrolling from 'svelte-scrolling/dist/shared/scrolling' // Copy if necessary

const elementsList = get(elements)

// Handle scrolling const handle = async (event: Event, options: ScrollToOptions): Promise => { if (!options.passive) event.preventDefault()

const { ref, onDone, onStart } = options

const duration = options.duration!
const offset = options.offset!
const easing = options.easing!

const element = getElement(elementsList, ref)

if (!element) {
	throw new Error(`Element reference '${ref}' not found`)
}

const endPosition = getPosition(element)

onStart?.({ element, offset, duration, endPosition })

await scrolling(endPosition, { duration, offset, easing })

onDone?.({ element, offset, duration, endPosition })

}

/**

  • Listens for click (touchend) events and scrolls to elements with smooth animation
  • @param options - The element reference or global options */

// Custom scrollTo with touchend const customScrollTo = (node: HTMLElement, options: string | ScrollToOptions) => { if (!options) { throw new Error('scrollTo requires options') }

let opts: ScrollToOptions = {
	ref: '',
	...getGlobalOptions()
}

typeof options === 'string' ? (opts.ref = options) : (opts = Object.assign(opts, options))

opts.ref = sanitize(opts.ref)

if (!opts.ref) {
	throw new Error('scrollTo requires a reference')
}

if (node instanceof HTMLAnchorElement) {
	node.href = `#${opts.ref}`
}

if (node instanceof HTMLAnchorElement === false) {
	node.style.cursor = 'pointer'
}

// Variables to track touch movement
let touchStartX = 0
let touchStartY = 0

const handleTouchStart = (event: TouchEvent) => {
	const touch = event.touches[0]
	touchStartX = touch.clientX
	touchStartY = touch.clientY
}

const handleTouchEnd = (event: TouchEvent) => {
	const touch = event.changedTouches[0]
	const deltaX = Math.abs(touch.clientX - touchStartX)
	const deltaY = Math.abs(touch.clientY - touchStartY)

	// Define a small threshold for movement to detect a "tap"
	const threshold = 10 // pixels

	if (deltaX < threshold && deltaY < threshold) {
		// Minimal movement: treat it as a tap
		handle(event, opts)
	}
}

const handleClick = (event: MouseEvent) => handle(event, opts)

// Attach event listeners
node.addEventListener('click', handleClick, { passive: opts.passive })
node.addEventListener('touchstart', handleTouchStart, { passive: opts.passive })
node.addEventListener('touchend', handleTouchEnd, { passive: opts.passive })

return {
	destroy() {
		node.removeEventListener('click', handleClick)
		node.removeEventListener('touchstart', handleTouchStart)
		node.removeEventListener('touchend', handleTouchEnd)
	}
}

}

export default customScrollTo

`

robthepaper avatar Jan 07 '25 00:01 robthepaper