mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
getBoundingClientRect keeps reporting elements the growing document pushed below the emulated viewport, and input coordinates are viewport-relative, so a click below the fold was hit-tested to the document root and the step read as an action that landed. every gesture now scrolls the point back in and reports ErrGestureUndelivered when nothing is under it; a selector that names no node reports ErrSelectorMatchedNothing rather than waiting. swipe dispatches a real touch stream instead of page-synthesized pointer events, scroll is a wheel so its distance is exact rather than a fling, and the second tap of a double tap carries click count 2 so dblclick actually fires.
53 lines
1.7 KiB
HTML
53 lines
1.7 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<style>
|
|
:root { --frame-w: 390; --frame-h: 640; }
|
|
body { margin: 0; font: 16px sans-serif; }
|
|
#row { height: 80px; background: #eef; touch-action: pan-y; }
|
|
#inner { height: 200px; overflow-y: scroll; border: 2px solid #333; }
|
|
#inner div { height: 60px; }
|
|
#filler div { height: 60px; border-bottom: 1px solid #ccc; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="row" data-testid="row">swipe me</div>
|
|
<div id="status" data-testid="status">idle</div>
|
|
<div id="inner" data-testid="inner"></div>
|
|
<div id="filler"></div>
|
|
<script>
|
|
const inner = document.getElementById('inner');
|
|
for (let i = 0; i < 30; i++) {
|
|
const item = document.createElement('div');
|
|
item.textContent = 'inner ' + i;
|
|
inner.appendChild(item);
|
|
}
|
|
const filler = document.getElementById('filler');
|
|
for (let i = 0; i < 40; i++) {
|
|
const item = document.createElement('div');
|
|
item.textContent = 'page ' + i;
|
|
filler.appendChild(item);
|
|
}
|
|
const row = document.getElementById('row');
|
|
const status = document.getElementById('status');
|
|
let startX = 0, startY = 0, tracking = false;
|
|
row.addEventListener('pointerdown', function(e) {
|
|
startX = e.clientX;
|
|
startY = e.clientY;
|
|
tracking = true;
|
|
row.setPointerCapture(e.pointerId);
|
|
});
|
|
row.addEventListener('pointermove', function(e) {
|
|
if (!tracking) return;
|
|
const dx = e.clientX - startX, dy = e.clientY - startY;
|
|
if (Math.abs(dx) <= 40 || Math.abs(dx) <= Math.abs(dy)) return;
|
|
tracking = false;
|
|
status.textContent =
|
|
(dx < 0 ? 'dismissed left' : 'dismissed right') +
|
|
(e.isTrusted ? ' trusted' : ' untrusted');
|
|
});
|
|
row.addEventListener('pointerup', function() { tracking = false; });
|
|
</script>
|
|
</body>
|
|
</html>
|