如何检测用户用JavaScript在网页上向某个方向滑动手指?
我想知道是否有一种解决方案可以同时适用于iPhone和Android手机上的网站。
如何检测用户用JavaScript在网页上向某个方向滑动手指?
我想知道是否有一种解决方案可以同时适用于iPhone和Android手机上的网站。
当前回答
简单的JS代码示例:
document.addEventListener('touchstart', handleTouchStart, false);
document.addEventListener('touchmove', handleTouchMove, false);
var xDown = null;
var yDown = null;
function getTouches(evt) {
return evt.touches || // browser API
evt.originalEvent.touches; // jQuery
}
function handleTouchStart(evt) {
const firstTouch = getTouches(evt)[0];
xDown = firstTouch.clientX;
yDown = firstTouch.clientY;
};
function handleTouchMove(evt) {
if ( ! xDown || ! yDown ) {
return;
}
var xUp = evt.touches[0].clientX;
var yUp = evt.touches[0].clientY;
var xDiff = xDown - xUp;
var yDiff = yDown - yUp;
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
if ( xDiff > 0 ) {
/* right swipe */
} else {
/* left swipe */
}
} else {
if ( yDiff > 0 ) {
/* down swipe */
} else {
/* up swipe */
}
}
/* reset values */
xDown = null;
yDown = null;
};
Android测试。
其他回答
我将这里的一些答案合并到一个脚本中,该脚本使用CustomEvent在DOM中触发滑动事件。添加0.7k的swiped-events.min.js脚本到你的页面,并监听滑动事件:
刷卡
document.addEventListener('swiped', function(e) {
console.log(e.target); // the element that was swiped
console.log(e.detail.dir); // swiped direction
});
swiped-left
document.addEventListener('swiped-left', function(e) {
console.log(e.target); // the element that was swiped
});
swiped-right
document.addEventListener('swiped-right', function(e) {
console.log(e.target); // the element that was swiped
});
swiped-up
document.addEventListener('swiped-up', function(e) {
console.log(e.target); // the element that was swiped
});
swiped-down
document.addEventListener('swiped-down', function(e) {
console.log(e.target); // the element that was swiped
});
你也可以直接附加到一个元素:
document.getElementById('myBox').addEventListener('swiped-down', function(e) {
console.log(e.target); // the element that was swiped
});
可选配置
您可以指定以下属性来调整页面中的滑动交互功能(这些是可选的)。
<div data-swipe-threshold="10"
data-swipe-timeout="1000"
data-swipe-ignore="false">
Swiper, get swiping!
</div>
要在应用程序范围内设置默认值,请在最顶部的元素上设置配置属性:
<body data-swipe-threshold="100" data-swipe-timeout="250">
<div>Swipe me</div>
<div>or me</div>
</body>
源代码可在Github
threshold, timeout swipe, swipeBlockElems添加。
document.addEventListener('touchstart', handleTouchStart, false);
document.addEventListener('touchmove', handleTouchMove, false);
document.addEventListener('touchend', handleTouchEnd, false);
const SWIPE_BLOCK_ELEMS = [
'swipBlock',
'handle',
'drag-ruble'
]
let xDown = null;
let yDown = null;
let xDiff = null;
let yDiff = null;
let timeDown = null;
const TIME_THRESHOLD = 200;
const DIFF_THRESHOLD = 130;
function handleTouchEnd() {
let timeDiff = Date.now() - timeDown;
if (Math.abs(xDiff) > Math.abs(yDiff)) { /*most significant*/
if (Math.abs(xDiff) > DIFF_THRESHOLD && timeDiff < TIME_THRESHOLD) {
if (xDiff > 0) {
// console.log(xDiff, TIME_THRESHOLD, DIFF_THRESHOLD)
SWIPE_LEFT(LEFT) /* left swipe */
} else {
// console.log(xDiff)
SWIPE_RIGHT(RIGHT) /* right swipe */
}
} else {
console.log('swipeX trashhold')
}
} else {
if (Math.abs(yDiff) > DIFF_THRESHOLD && timeDiff < TIME_THRESHOLD) {
if (yDiff > 0) {
/* up swipe */
} else {
/* down swipe */
}
} else {
console.log('swipeY trashhold')
}
}
/* reset values */
xDown = null;
yDown = null;
timeDown = null;
}
function containsClassName (evntarget , classArr) {
for (var i = classArr.length - 1; i >= 0; i--) {
if( evntarget.classList.contains(classArr[i]) ) {
return true;
}
}
}
function handleTouchStart(evt) {
let touchStartTarget = evt.target;
if( containsClassName(touchStartTarget, SWIPE_BLOCK_ELEMS) ) {
return;
}
timeDown = Date.now()
xDown = evt.touches[0].clientX;
yDown = evt.touches[0].clientY;
xDiff = 0;
yDiff = 0;
}
function handleTouchMove(evt) {
if (!xDown || !yDown) {
return;
}
var xUp = evt.touches[0].clientX;
var yUp = evt.touches[0].clientY;
xDiff = xDown - xUp;
yDiff = yDown - yUp;
}
你可以监听touchstart和touchend事件,并根据事件数据计算方向和力(Codepen):
让start = null; 文档。addEventListener('touchstart', e => { const touch = e. changedtouchs[0]; Start = [touch.]clientX touch.clientY); }); 文档。addEventListener('touchend', e => { const touch = e. changedtouchs[0]; Const end = [touch.]clientX touch.clientY); document.body.innerText = " ${结束[0]-[0]开始},${结束[1]-[1]开始}'; }); 点击这里
或者你可以围绕同样的概念构建一个更符合人体工程学的API (Codepen):
const removeListener = addSwipeRightListener(document, (force, e) => {
console.info('Swiped right with force: ' + force);
});
// removeListener()
// swipe.js const { addSwipeLeftListener, addSwipeRightListener, addSwipeUpListener, addSwipeDownListener, } = (function() { // <element, {listeners: [...], handleTouchstart, handleTouchend}> const elements = new WeakMap(); function readTouch(e) { const touch = e.changedTouches[0]; if (touch == undefined) { return null; } return [touch.clientX, touch.clientY]; } function addListener(element, cb) { let elementValues = elements.get(element); if (elementValues === undefined) { const listeners = new Set(); const handleTouchstart = e => { elementValues.start = readTouch(e); }; const handleTouchend = e => { const start = elementValues.start; if (start === null) { return; } const end = readTouch(e); for (const listener of listeners) { listener([end[0] - start[0], end[1] - start[1]], e); } }; element.addEventListener('touchstart', handleTouchstart); element.addEventListener('touchend', handleTouchend); elementValues = { start: null, listeners, handleTouchstart, handleTouchend, }; elements.set(element, elementValues); } elementValues.listeners.add(cb); return () => deleteListener(element, cb); } function deleteListener(element, cb) { const elementValues = elements.get(element); const listeners = elementValues.listeners; listeners.delete(cb); if (listeners.size === 0) { elements.delete(element); element.removeEventListener('touchstart', elementValues.handleTouchstart); element.removeEventListener('touchend', elementValues.handleTouchend); } } function addSwipeLeftListener(element, cb) { return addListener(element, (force, e) => { const [x, y] = force; if (x < 0 && -x > Math.abs(y)) { cb(x, e); } }); } function addSwipeRightListener(element, cb) { return addListener(element, (force, e) => { const [x, y] = force; if (x > 0 && x > Math.abs(y)) { cb(x, e); } }); } function addSwipeUpListener(element, cb) { return addListener(element, (force, e) => { const [x, y] = force; if (y < 0 && -y > Math.abs(x)) { cb(x, e); } }); } function addSwipeDownListener(element, cb) { return addListener(element, (force, e) => { const [x, y] = force; if (y > 0 && y > Math.abs(x)) { cb(x, e); } }); } return { addSwipeLeftListener, addSwipeRightListener, addSwipeUpListener, addSwipeDownListener, } })(); // app.js function print(direction, force) { document.querySelector('#direction').innerText = direction; document.querySelector('#data').innerText = force; } addSwipeLeftListener(document, (force, e) => { print('left', force); }); addSwipeRightListener(document, (force, e) => { print('right', force); }); addSwipeUpListener(document, (force, e) => { print('up', force); }); addSwipeDownListener(document, (force, e) => { print('down', force); }); <h1>Swipe <span id="direction"></span></h1> Force (px): <span id="data"></span>
touchStart和touchEnd的句柄:
var handleSwipe = function(elem,callbackOnRight, callbackOnLeft, callbackOnDown,
callbackOnUp) => {
elem.ontouchstart = handleTouchStart;
elem.ontouchend = handleTouchEnd;
var xDown = null;
var yDown = null;
function getTouches(evt) {
return evt.touches || // browser API
evt.originalEvent.touches; // jQuery
}
function handleTouchStart(evt) {
const firstTouch = getTouches(evt)[0];
xDown = firstTouch.clientX;
yDown = firstTouch.clientY;
};
function handleTouchEnd(evt) {
if (!xDown || !yDown) {
return;
}
var xUp = evt.changedTouches[0].clientX;
var yUp = evt.changedTouches[0].clientY;
var xDiff = xDown - xUp;
var yDiff = yDown - yUp;
var minDif = 30;
console.log(`xDiff:${xDiff}, yDiff:${yDiff}`);
if (Math.abs(xDiff) > Math.abs(yDiff)) {
if (xDiff > minDif) {
if (callbackOnLeft)
callbackOnLeft();
} else if (xDiff < -1 * minDif){
if (callbackOnRight)
callbackOnRight();
}
} else {
if (yDiff > minDif) {
if (callbackOnDown)
callbackOnDown();
} else if (yDiff < -1* minDif){
if (callbackOnUp)
callbackOnUp();
}
}
xDown = null;
yDown = null;
};
}
我重新包装了TouchWipe作为一个简短的jquery插件:detectSwipe