Skip to content

Commit

Permalink
Handle clicks in the container's underlying elements
Browse files Browse the repository at this point in the history
  • Loading branch information
wstaeblein committed Apr 5, 2023
1 parent d6c88f1 commit bdbe04d
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 19 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ This action expects that a container has a fixed height and a direct child that
This is so simple that it doesn't need a NPM package. Just copy the file ``/src/kineticscroll.js`` to your project's appropriate folder and import it where needed. All other files are just there for the sake of the example.


## Notes

To avoid problems with underlying click events, this class temporarily suspends pointer events on the container element's children. This is done via the pointer-events CSS selector. You may experience some problems should you be manipulating this selector on your container's children and using this class at the same time. The class will do a pointer-events: 'none' when a drag has moved and a pointer-events: 'auto' at the mouseup event.

## Example

Download this code, extract it and run:
Expand Down
2 changes: 1 addition & 1 deletion public/countries.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ const countries = [
{name: 'Reunion', code: 'RE'},
{name: 'Romania', code: 'RO'},
{name: 'Russian Federation', code: 'RU'},
{name: 'RWANDA', code: 'RW'},
{name: 'Rwanda', code: 'RW'},
{name: 'Saint Helena', code: 'SH'},
{name: 'Saint Kitts and Nevis', code: 'KN'},
{name: 'Saint Lucia', code: 'LC'},
Expand Down
17 changes: 14 additions & 3 deletions public/kineticscroll.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

// Svelte action to transform a container into a momentum scroller
// Vanilla JS module and Svelte action to transform a container into a momentum scroller
// By Walter Staeblein - 2022
export function kineticscroll(node, cfgs) {
'use strict';
Expand Down Expand Up @@ -122,6 +122,7 @@ export function kineticscroll(node, cfgs) {
if (isWheel) { wheeling = true; } else { pressed = true; }
reference = ypos(e);

node.style.cursor = 'ns-resize';
velocity = amplitude = 0;
frame = offset;
timestamp = Date.now();
Expand All @@ -139,9 +140,11 @@ export function kineticscroll(node, cfgs) {
if (pressed) {
y = ypos(e);
delta = reference - y;
if (delta > 2 || delta < -2) {
if (Math.abs(delta) > 5) {
reference = y;
scroll(offset + delta);

Array.from(node.children).forEach((ele) => { ele.style.pointerEvents = 'none' });
}
}
e.preventDefault();
Expand All @@ -150,10 +153,15 @@ export function kineticscroll(node, cfgs) {
}

function preRelease(e) {
e.stopPropagation();
e.preventDefault();
if (e.buttons == 1) { release(e); }
}

function release(e) {
e.stopPropagation();
e.preventDefault();

pressed = false;
wheeling = false;
clearInterval(ticker);
Expand All @@ -166,7 +174,10 @@ export function kineticscroll(node, cfgs) {
requestAnimationFrame(autoScroll);
}
e.preventDefault();
e.stopPropagation();
e.stopPropagation();

Array.from(node.children).forEach((ele) => { ele.style.pointerEvents = 'auto' });
node.style.cursor = 'auto';
return false;
}

Expand Down
31 changes: 24 additions & 7 deletions public/vanilla.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<title>Kinetic Scroll - Vanilla JS</title>
<meta charset="UTF-8">
<link rel="icon" type="image/png" href="./favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="global.css" rel="stylesheet">

Expand All @@ -24,6 +25,7 @@
text-align: center;
margin: 0 0 1em;
}

.container {
border: 1px solid #eee;
width: fit-content;
Expand All @@ -32,6 +34,7 @@
overflow: hidden;
transform: scale(1);
}

ul {
width: fit-content;
text-align: left;
Expand All @@ -47,8 +50,14 @@
display: flex;
align-items: center;
gap: 10px;
transition: background-color 0.4s ease;
cursor: pointer;
}


ul > li.sel {
background-color: #fff;
}

ul > li > img {
width: 40px;
height: 32px;
Expand All @@ -59,8 +68,6 @@
border-bottom: none;
}



h1 {
color: #ff3e00;
text-transform: uppercase;
Expand All @@ -86,9 +93,7 @@
}

@media (min-width: 640px) {
main {
max-width: none;
}
main { max-width: none; }
}
</style>
</head>
Expand All @@ -114,14 +119,20 @@ <h3>Example</h3>
import countries from './countries.js';
import { kineticscroll } from './kineticscroll.js';

let selected = '';
let list;

document.addEventListener('DOMContentLoaded', async function(event) {
let list = document.querySelector('.container > ul');
list = document.querySelector('.container > ul');

countries.forEach(country => {
let li = document.createElement('li');
let img = document.createElement('img');
let span = document.createElement('span');

li.setAttribute('code', country.code.toLowerCase());
li.addEventListener('click', handleClick);

img.setAttribute('src', `./flags/${country.code.toLowerCase()}.png`);
img.setAttribute('loading', 'lazy');
img.setAttribute('alt', country.name);
Expand All @@ -133,5 +144,11 @@ <h3>Example</h3>
});
kineticscroll(list, { indicator: 'indic', snap: true });
});

function handleClick(e) {
e.stopPropagation();
[...list.querySelectorAll('li')].forEach(ele => ele.classList.remove('sel'));
e.currentTarget.classList.add('sel');
}
</script>
</html>
24 changes: 16 additions & 8 deletions src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<script>
import countries from '../public/countries.js';
import { kineticscroll } from '../public/kineticscroll.js';
let selected = '';
</script>

<main>
Expand All @@ -13,15 +15,17 @@
<div id="indic"></div>
<ul use:kineticscroll={{ indicator: 'indic', snap: true }}>
{#each countries as country}
<li><img src="./flags/{country.code.toLowerCase()}.png" loading="lazy" alt="{country.name}" /><span>{country.name}</span></li>
<li on:click={() => selected = country.code} class:sel={selected == country.code}>
<img src="./flags/{country.code.toLowerCase()}.png" loading="lazy" alt="{country.name}" />
<span>{country.name}</span>
</li>
{/each}
</ul>
</div>

</main>

<style>
#indic {
position: absolute;
left: 1px;
Expand All @@ -39,6 +43,7 @@
text-align: center;
margin: 0 0 1em;
}
.container {
border: 1px solid #eee;
width: fit-content;
Expand All @@ -47,6 +52,7 @@
overflow: hidden;
transform: scale(1);
}
ul {
width: fit-content;
text-align: left;
Expand All @@ -62,9 +68,15 @@
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
transition: background-color 0.4s ease;
}
ul > li > img {
ul > li.sel {
background-color: #fff;
}
ul > li img {
width: 40px;
height: 32px;
object-fit: contain;
Expand All @@ -74,8 +86,6 @@
border-bottom: none;
}
h1 {
color: #ff3e00;
text-transform: uppercase;
Expand All @@ -101,8 +111,6 @@
}
@media (min-width: 640px) {
main {
max-width: none;
}
main { max-width: none; }
}
</style>

0 comments on commit bdbe04d

Please sign in to comment.