आप कैसे पता लगा सकते हैं कि एक उपयोगकर्ता ने जावास्क्रिप्ट के साथ एक वेब पेज पर किसी दिशा में अपनी उंगली को स्वाइप किया?
मैं सोच रहा था कि क्या एक समाधान है जो आईफोन और एंड्रॉइड फोन दोनों पर वेबसाइटों के लिए काम करेगा।
आप कैसे पता लगा सकते हैं कि एक उपयोगकर्ता ने जावास्क्रिप्ट के साथ एक वेब पेज पर किसी दिशा में अपनी उंगली को स्वाइप किया?
मैं सोच रहा था कि क्या एक समाधान है जो आईफोन और एंड्रॉइड फोन दोनों पर वेबसाइटों के लिए काम करेगा।
जवाबों:
सरल वेनिला जेएस कोड नमूना:
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 ) {
/* left swipe */
} else {
/* right swipe */
}
} else {
if ( yDiff > 0 ) {
/* up swipe */
} else {
/* down swipe */
}
}
/* reset values */
xDown = null;
yDown = null;
};
Android में परीक्षण किया गया।
touchstart
, touchmove
?
@ Givanse के उत्तर के आधार पर, यह है कि आप इसे कैसे कर सकते हैं classes
:
class Swipe {
constructor(element) {
this.xDown = null;
this.yDown = null;
this.element = typeof(element) === 'string' ? document.querySelector(element) : element;
this.element.addEventListener('touchstart', function(evt) {
this.xDown = evt.touches[0].clientX;
this.yDown = evt.touches[0].clientY;
}.bind(this), false);
}
onLeft(callback) {
this.onLeft = callback;
return this;
}
onRight(callback) {
this.onRight = callback;
return this;
}
onUp(callback) {
this.onUp = callback;
return this;
}
onDown(callback) {
this.onDown = callback;
return this;
}
handleTouchMove(evt) {
if ( ! this.xDown || ! this.yDown ) {
return;
}
var xUp = evt.touches[0].clientX;
var yUp = evt.touches[0].clientY;
this.xDiff = this.xDown - xUp;
this.yDiff = this.yDown - yUp;
if ( Math.abs( this.xDiff ) > Math.abs( this.yDiff ) ) { // Most significant.
if ( this.xDiff > 0 ) {
this.onLeft();
} else {
this.onRight();
}
} else {
if ( this.yDiff > 0 ) {
this.onUp();
} else {
this.onDown();
}
}
// Reset values.
this.xDown = null;
this.yDown = null;
}
run() {
this.element.addEventListener('touchmove', function(evt) {
this.handleTouchMove(evt).bind(this);
}.bind(this), false);
}
}
आप इसे इस तरह से उपयोग कर सकते हैं:
// Use class to get element by string.
var swiper = new Swipe('#my-element');
swiper.onLeft(function() { alert('You swiped left.') });
swiper.run();
// Get the element yourself.
var swiper = new Swipe(document.getElementById('#my-element'));
swiper.onLeft(function() { alert('You swiped left.') });
swiper.run();
// One-liner.
(new Swipe('#my-element')).onLeft(function() { alert('You swiped left.') }).run();
.bind
अपरिभाषित कॉल करने की कोशिश करते समय एक अपवाद मिलेगा क्योंकि आपके handleTouchMove
वास्तव में कुछ भी वापस नहीं आया। जब this.
यह पहले से ही वर्तमान संदर्भ के लिए बाध्य है, तो कॉलिंग बाइंड को कॉल करने के लिए बेकार है
.bind(this);
और इसने इनायत से काम किया। @nicholas_r धन्यवाद
touches[0]
करने के लिए changedTouches[0]
और ईवेंट हैंडलर प्रकार handleTouchMove
के लिएhandleTouchEnd
run()
दो बार और आप एक बुरा स्मृति रिसाव मिल
मैंने कुछ उत्तरों को यहाँ एक स्क्रिप्ट में मर्ज किया है जो DOM में स्वाइप की गई घटनाओं को आग लगाने के लिए CustomEvent का उपयोग करता है । अपने पृष्ठ में 0.7k स्वाइप किए गए ईवेंट .min.js स्क्रिप्ट जोड़ें और स्वाइप किए गए ईवेंट के लिए सुनें :
document.addEventListener('swiped-left', function(e) {
console.log(e.target); // the element that was swiped
});
document.addEventListener('swiped-right', function(e) {
console.log(e.target); // the element that was swiped
});
document.addEventListener('swiped-up', function(e) {
console.log(e.target); // the element that was swiped
});
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>
स्रोत कोड Github पर उपलब्ध है
इससे पहले कि आपने मूसडाउन ईवेंट का पता लगाया है, उसका एक्स, वाई लोकेशन (जो भी प्रासंगिक हो) रिकॉर्ड करें, फिर माउसअप ईवेंट का पता लगाएं, और दो मानों को घटाएं।
jQuery मोबाइल में स्वाइप सपोर्ट भी शामिल है: http://api.jquerymobile.com/swipe/
उदाहरण
$("#divId").on("swipe", function(event) {
alert("It's a swipe!");
});
मैंने स्वाइप क्रियाओं को पंजीकृत करने के लिए कई मोबाइल ब्राउज़रों में सबसे विश्वसनीय और संगत होने के लिए @givanse शानदार उत्तर पाया है।
हालाँकि, आधुनिक मोबाइल ब्राउज़र में काम करने के लिए उसके कोड में बदलाव करना आवश्यक है जो उपयोग कर रहे हैं jQuery
।
event.touches
यदि jQuery
इसका उपयोग किया जाता है और परिणाम इसके undefined
द्वारा प्रतिस्थापित किया जाना चाहिए और मौजूद नहीं है event.originalEvent.touches
। बिना jQuery
, event.touches
ठीक काम करना चाहिए।
तो समाधान बन जाता है,
document.addEventListener('touchstart', handleTouchStart, false);
document.addEventListener('touchmove', handleTouchMove, false);
var xDown = null;
var yDown = null;
function handleTouchStart(evt) {
xDown = evt.originalEvent.touches[0].clientX;
yDown = evt.originalEvent.touches[0].clientY;
};
function handleTouchMove(evt) {
if ( ! xDown || ! yDown ) {
return;
}
var xUp = evt.originalEvent.touches[0].clientX;
var yUp = evt.originalEvent.touches[0].clientY;
var xDiff = xDown - xUp;
var yDiff = yDown - yUp;
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
if ( xDiff > 0 ) {
/* left swipe */
} else {
/* right swipe */
}
} else {
if ( yDiff > 0 ) {
/* up swipe */
} else {
/* down swipe */
}
}
/* reset values */
xDown = null;
yDown = null;
};
पर परीक्षण किया गया:
event.originalEvent
। बात event.touches
अब समाप्त हो गई है और परिणाम में है undefined
।
event.originalEvent
। मैं अपना जवाब अपडेट करूंगा। धन्यवाद! :)
मैंने TouchWipe
एक छोटे jquery प्लगइन के रूप में फिर से वापसी की है :detectSwipe
शॉर्ट स्वेप्स से निपटने के लिए कुछ बड़े उत्तर (कुछ भी टिप्पणी नहीं कर सकते ...)
document.addEventListener('touchstart', handleTouchStart, false);
document.addEventListener('touchmove', handleTouchMove, false);
var xDown = null;
var yDown = null;
function handleTouchStart(evt) {
xDown = evt.touches[0].clientX;
yDown = evt.touches[0].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 )>150){ //to deal with to short swipes
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
if ( xDiff > 0 ) {/* left swipe */
alert('left!');
} else {/* right swipe */
alert('right!');
}
} else {
if ( yDiff > 0 ) {/* up swipe */
alert('Up!');
} else { /* down swipe */
alert('Down!');
}
}
/* reset values */
xDown = null;
yDown = null;
}
};
trashold, टाइमआउट स्वाइप, 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_TRASHOLD = 200;
const DIFF_TRASHOLD = 130;
function handleTouchEnd() {
let timeDiff = Date.now() - timeDown;
if (Math.abs(xDiff) > Math.abs(yDiff)) { /*most significant*/
if (Math.abs(xDiff) > DIFF_TRASHOLD && timeDiff < TIME_TRASHOLD) {
if (xDiff > 0) {
// console.log(xDiff, TIME_TRASHOLD, DIFF_TRASHOLD)
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_TRASHOLD && timeDiff < TIME_TRASHOLD) {
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;
}
अगर कोई भी एंड्रॉइड पर jQuery मोबाइल का उपयोग करने की कोशिश कर रहा है और उसे JQM स्वाइप डिटेक्शन की समस्या है
(मेरे पास एक्सपीरिया जेड 1, गैलेक्सी एस 3, नेक्सस 4 और कुछ वाइको फोन भी थे) यह उपयोगी हो सकते हैं:
//Fix swipe gesture on android
if(android){ //Your own device detection here
$.event.special.swipe.verticalDistanceThreshold = 500
$.event.special.swipe.horizontalDistanceThreshold = 10
}
Android पर स्वाइप का पता नहीं चला जब तक कि यह बहुत लंबा, सटीक और तेज़ स्वाइप न हो।
इन दो पंक्तियों के साथ यह सही ढंग से काम करता है
$.event.special.swipe.scrollSupressionThreshold = 8;
लेकिन आपने मुझे सही दिशा में लगा दिया! धन्यवाद!
मुझे लगातार टच करने वाले हैंडलर फायरिंग से परेशानी थी जबकि उपयोगकर्ता चारों ओर उंगली खींच रहा था। मुझे नहीं पता कि ऐसा कुछ होने के कारण मैं गलत कर रही हूं या नहीं, लेकिन मैंने इसे टचवेव के साथ चालें जमा करने के लिए फिर से शुरू किया और टचेंड वास्तव में कॉलबैक को आग लगाता है।
मुझे भी इन उदाहरणों की एक बड़ी संख्या की आवश्यकता थी और इसलिए मैंने सक्षम / अक्षम तरीके जोड़े।
और एक दहलीज जहां एक छोटी स्वाइप आग नहीं है। टचस्टार्ट शून्य के काउंटर हर बार।
आप फ्लाई पर target_node को बदल सकते हैं। निर्माण पर सक्षम वैकल्पिक है।
/** Usage: */
touchevent = new Modules.TouchEventClass(callback, target_node);
touchevent.enable();
touchevent.disable();
/**
*
* Touch event module
*
* @param method set_target_mode
* @param method __touchstart
* @param method __touchmove
* @param method __touchend
* @param method enable
* @param method disable
* @param function callback
* @param node target_node
*/
Modules.TouchEventClass = class {
constructor(callback, target_node, enable=false) {
/** callback function */
this.callback = callback;
this.xdown = null;
this.ydown = null;
this.enabled = false;
this.target_node = null;
/** move point counts [left, right, up, down] */
this.counts = [];
this.set_target_node(target_node);
/** Enable on creation */
if (enable === true) {
this.enable();
}
}
/**
* Set or reset target node
*
* @param string/node target_node
* @param string enable (optional)
*/
set_target_node(target_node, enable=false) {
/** check if we're resetting target_node */
if (this.target_node !== null) {
/** remove old listener */
this.disable();
}
/** Support string id of node */
if (target_node.nodeName === undefined) {
target_node = document.getElementById(target_node);
}
this.target_node = target_node;
if (enable === true) {
this.enable();
}
}
/** enable listener */
enable() {
this.enabled = true;
this.target_node.addEventListener("touchstart", this.__touchstart.bind(this));
this.target_node.addEventListener("touchmove", this.__touchmove.bind(this));
this.target_node.addEventListener("touchend", this.__touchend.bind(this));
}
/** disable listener */
disable() {
this.enabled = false;
this.target_node.removeEventListener("touchstart", this.__touchstart);
this.target_node.removeEventListener("touchmove", this.__touchmove);
this.target_node.removeEventListener("touchend", this.__touchend);
}
/** Touchstart */
__touchstart(event) {
event.stopPropagation();
this.xdown = event.touches[0].clientX;
this.ydown = event.touches[0].clientY;
/** reset count of moves in each direction, [left, right, up, down] */
this.counts = [0, 0, 0, 0];
}
/** Touchend */
__touchend(event) {
let max_moves = Math.max(...this.counts);
if (max_moves > 500) { // set this threshold appropriately
/** swipe happened */
let index = this.counts.indexOf(max_moves);
if (index == 0) {
this.callback("left");
} else if (index == 1) {
this.callback("right");
} else if (index == 2) {
this.callback("up");
} else {
this.callback("down");
}
}
}
/** Touchmove */
__touchmove(event) {
event.stopPropagation();
if (! this.xdown || ! this.ydown) {
return;
}
let xup = event.touches[0].clientX;
let yup = event.touches[0].clientY;
let xdiff = this.xdown - xup;
let ydiff = this.ydown - yup;
/** Check x or y has greater distance */
if (Math.abs(xdiff) > Math.abs(ydiff)) {
if (xdiff > 0) {
this.counts[0] += Math.abs(xdiff);
} else {
this.counts[1] += Math.abs(xdiff);
}
} else {
if (ydiff > 0) {
this.counts[2] += Math.abs(ydiff);
} else {
this.counts[3] += Math.abs(ydiff);
}
}
}
}
मैंने कुछ उत्तरों को भी विलय कर दिया है, जिनमें से ज्यादातर पहले और दूसरे वर्ग के साथ हैं, और यहाँ मेरा संस्करण है:
export default class Swipe {
constructor(options) {
this.xDown = null;
this.yDown = null;
this.options = options;
this.handleTouchStart = this.handleTouchStart.bind(this);
this.handleTouchMove = this.handleTouchMove.bind(this);
document.addEventListener('touchstart', this.handleTouchStart, false);
document.addEventListener('touchmove', this.handleTouchMove, false);
}
onLeft() {
this.options.onLeft();
}
onRight() {
this.options.onRight();
}
onUp() {
this.options.onUp();
}
onDown() {
this.options.onDown();
}
static getTouches(evt) {
return evt.touches // browser API
}
handleTouchStart(evt) {
const firstTouch = Swipe.getTouches(evt)[0];
this.xDown = firstTouch.clientX;
this.yDown = firstTouch.clientY;
}
handleTouchMove(evt) {
if ( ! this.xDown || ! this.yDown ) {
return;
}
let xUp = evt.touches[0].clientX;
let yUp = evt.touches[0].clientY;
let xDiff = this.xDown - xUp;
let yDiff = this.yDown - yUp;
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
if ( xDiff > 0 && this.options.onLeft) {
/* left swipe */
this.onLeft();
} else if (this.options.onRight) {
/* right swipe */
this.onRight();
}
} else {
if ( yDiff > 0 && this.options.onUp) {
/* up swipe */
this.onUp();
} else if (this.options.onDown){
/* down swipe */
this.onDown();
}
}
/* reset values */
this.xDown = null;
this.yDown = null;
}
}
बाद में इसे निम्नलिखित के रूप में उपयोग कर सकते हैं:
let swiper = new Swipe({
onLeft() {
console.log('You swiped left.');
}
});
यह सांत्वना त्रुटियों से बचने में मदद करता है जब आप केवल कॉल करना चाहते हैं चलो "onLeft" विधि कहते हैं।
उपयोग दो:
jQuery मोबाइल: ज्यादातर मामलों में काम करते हैं और विशेष रूप से जब आप एप्लीकेसन विकसित कर रहे होते हैं जो अन्य jQuery प्लगइन का उपयोग करता है तो इसके लिए jQuery मोबाइल नियंत्रण का उपयोग करना बेहतर होता है। इसे यहां देखें: https://www.w3schools.com/jquerymobile/jquerymobile_events_touch.asp
हथौड़ा समय ! सबसे अच्छे, हल्के और तेज़ जावास्क्रिप्ट आधारित पुस्तकालय में से एक। इसे यहां देखें: https://hammerjs.github.io/
यदि आपको केवल स्वाइप की आवश्यकता है, तो आप केवल उस भाग का उपयोग करना बेहतर समझदार हैं, जिसकी आपको आवश्यकता है। यह किसी भी टच डिवाइस पर काम करना चाहिए।
यह ~ 450 बाइट्स 'गज़िप कंप्रेशन, मिनिफिकेशन, बैबल आदि के बाद है।
मैंने अन्य उत्तरों के आधार पर नीचे की कक्षा लिखी है, यह पिक्सेल के बजाय स्थानांतरित प्रतिशत का उपयोग करता है, और एक घटना डिस्पैचर पैटर्न को हुक / अप्रकाशित चीजों को हुक करने के लिए करता है।
इसका इस्तेमाल ऐसे करें:
const dispatcher = new SwipeEventDispatcher(myElement);
dispatcher.on('SWIPE_RIGHT', () => { console.log('I swiped right!') })
export class SwipeEventDispatcher {
constructor(element, options = {}) {
this.evtMap = {
SWIPE_LEFT: [],
SWIPE_UP: [],
SWIPE_DOWN: [],
SWIPE_RIGHT: []
};
this.xDown = null;
this.yDown = null;
this.element = element;
this.options = Object.assign({ triggerPercent: 0.3 }, options);
element.addEventListener('touchstart', evt => this.handleTouchStart(evt), false);
element.addEventListener('touchend', evt => this.handleTouchEnd(evt), false);
}
on(evt, cb) {
this.evtMap[evt].push(cb);
}
off(evt, lcb) {
this.evtMap[evt] = this.evtMap[evt].filter(cb => cb !== lcb);
}
trigger(evt, data) {
this.evtMap[evt].map(handler => handler(data));
}
handleTouchStart(evt) {
this.xDown = evt.touches[0].clientX;
this.yDown = evt.touches[0].clientY;
}
handleTouchEnd(evt) {
const deltaX = evt.changedTouches[0].clientX - this.xDown;
const deltaY = evt.changedTouches[0].clientY - this.yDown;
const distMoved = Math.abs(Math.abs(deltaX) > Math.abs(deltaY) ? deltaX : deltaY);
const activePct = distMoved / this.element.offsetWidth;
if (activePct > this.options.triggerPercent) {
if (Math.abs(deltaX) > Math.abs(deltaY)) {
deltaX < 0 ? this.trigger('SWIPE_LEFT') : this.trigger('SWIPE_RIGHT');
} else {
deltaY > 0 ? this.trigger('SWIPE_UP') : this.trigger('SWIPE_DOWN');
}
}
}
}
export default SwipeEventDispatcher;
मैं केवल बाएं और दाएं स्वाइप का पता लगाना चाहता था, लेकिन टच इवेंट समाप्त होने पर ही कार्रवाई को ट्रिगर करता हूं, इसलिए मैंने ऐसा करने के लिए @ givanse के शानदार उत्तर को थोड़ा संशोधित किया।
वह क्यों करें? यदि उदाहरण के लिए, स्वाइप करते समय, उपयोगकर्ता नोटिस करता है कि वह आखिरकार स्वाइप नहीं करना चाहता है, तो वह अपनी उंगली को मूल स्थिति में स्थानांतरित कर सकता है (एक बहुत लोकप्रिय "डेटिंग" फोन एप्लिकेशन ऐसा करता है;)), और फिर "स्वाइप राइट"; ईवेंट रद्द कर दिया गया है।
तो "स्वाइप राइट" ईवेंट से बचने के लिए सिर्फ इसलिए कि क्षैतिज रूप से 3px अंतर है, मैंने एक दहलीज जोड़ा जिसके तहत एक ईवेंट को छोड़ दिया गया है: "स्वाइप राइट" इवेंट के लिए, उपयोगकर्ता को कम से कम स्वाइप करना होगा ब्राउज़र चौड़ाई का 1/3 (बेशक आप इसे संशोधित कर सकते हैं)।
ये सभी छोटे विवरण उपयोगकर्ता अनुभव को बढ़ाते हैं। यहाँ (वेनिला JS) कोड है:
var xDown = null, yDown = null, xUp = null, yUp = null;
document.addEventListener('touchstart', touchstart, false);
document.addEventListener('touchmove', touchmove, false);
document.addEventListener('touchend', touchend, false);
function touchstart(evt) { const firstTouch = (evt.touches || evt.originalEvent.touches)[0]; xDown = firstTouch.clientX; yDown = firstTouch.clientY; }
function touchmove(evt) { if (!xDown || !yDown ) return; xUp = evt.touches[0].clientX; yUp = evt.touches[0].clientY; }
function touchend(evt) {
var xDiff = xUp - xDown, yDiff = yUp - yDown;
if ((Math.abs(xDiff) > Math.abs(yDiff)) && (Math.abs(xDiff) > 0.33 * document.body.clientWidth)) {
if (xDiff < 0)
document.getElementById('leftnav').click();
else
document.getElementById('rightnav').click();
}
xDown = null, yDown = null;
}
क्षैतिज स्वाइप के लिए सरल वेनिला जेएस उदाहरण:
let touchstartX = 0
let touchendX = 0
const slider = document.getElementById('slider')
function handleGesure() {
if (touchendX < touchstartX) alert('swiped left!')
if (touchendX > touchstartX) alert('swiped right!')
}
slider.addEventListener('touchstart', e => {
touchstartX = e.changedTouches[0].screenX
})
slider.addEventListener('touchend', e => {
touchendX = e.changedTouches[0].screenX
handleGesure()
})
ऊर्ध्वाधर स्वाइप के लिए आप बहुत ही तर्क का उपयोग कर सकते हैं।
इस उत्तर को यहाँ जोड़ना । यह डेस्कटॉप पर परीक्षण के लिए माउस की घटनाओं के लिए समर्थन जोड़ता है:
<!--scripts-->
class SwipeEventDispatcher {
constructor(element, options = {}) {
this.evtMap = {
SWIPE_LEFT: [],
SWIPE_UP: [],
SWIPE_DOWN: [],
SWIPE_RIGHT: []
};
this.xDown = null;
this.yDown = null;
this.element = element;
this.isMouseDown = false;
this.listenForMouseEvents = true;
this.options = Object.assign({ triggerPercent: 0.3 }, options);
element.addEventListener('touchstart', evt => this.handleTouchStart(evt), false);
element.addEventListener('touchend', evt => this.handleTouchEnd(evt), false);
element.addEventListener('mousedown', evt => this.handleMouseDown(evt), false);
element.addEventListener('mouseup', evt => this.handleMouseUp(evt), false);
}
on(evt, cb) {
this.evtMap[evt].push(cb);
}
off(evt, lcb) {
this.evtMap[evt] = this.evtMap[evt].filter(cb => cb !== lcb);
}
trigger(evt, data) {
this.evtMap[evt].map(handler => handler(data));
}
handleTouchStart(evt) {
this.xDown = evt.touches[0].clientX;
this.yDown = evt.touches[0].clientY;
}
handleMouseDown(evt) {
if (this.listenForMouseEvents==false) return;
this.xDown = evt.clientX;
this.yDown = evt.clientY;
this.isMouseDown = true;
}
handleMouseUp(evt) {
if (this.isMouseDown == false) return;
const deltaX = evt.clientX - this.xDown;
const deltaY = evt.clientY - this.yDown;
const distMoved = Math.abs(Math.abs(deltaX) > Math.abs(deltaY) ? deltaX : deltaY);
const activePct = distMoved / this.element.offsetWidth;
if (activePct > this.options.triggerPercent) {
if (Math.abs(deltaX) > Math.abs(deltaY)) {
deltaX < 0 ? this.trigger('SWIPE_LEFT') : this.trigger('SWIPE_RIGHT');
} else {
deltaY > 0 ? this.trigger('SWIPE_UP') : this.trigger('SWIPE_DOWN');
}
}
}
handleTouchEnd(evt) {
const deltaX = evt.changedTouches[0].clientX - this.xDown;
const deltaY = evt.changedTouches[0].clientY - this.yDown;
const distMoved = Math.abs(Math.abs(deltaX) > Math.abs(deltaY) ? deltaX : deltaY);
const activePct = distMoved / this.element.offsetWidth;
if (activePct > this.options.triggerPercent) {
if (Math.abs(deltaX) > Math.abs(deltaY)) {
deltaX < 0 ? this.trigger('SWIPE_LEFT') : this.trigger('SWIPE_RIGHT');
} else {
deltaY > 0 ? this.trigger('SWIPE_UP') : this.trigger('SWIPE_DOWN');
}
}
}
}
// add a listener on load
window.addEventListener("load", function(event) {
const dispatcher = new SwipeEventDispatcher(document.body);
dispatcher.on('SWIPE_RIGHT', () => { console.log('I swiped right!') })
dispatcher.on('SWIPE_LEFT', () => { console.log('I swiped left!') })
});
ऑफसेट के साथ उपयोग करने का एक उदाहरण।
// at least 100 px are a swipe
// you can use the value relative to screen size: window.innerWidth * .1
const offset = 100;
let xDown, yDown
window.addEventListener('touchstart', e => {
const firstTouch = getTouch(e);
xDown = firstTouch.clientX;
yDown = firstTouch.clientY;
});
window.addEventListener('touchend', e => {
if (!xDown || !yDown) {
return;
}
const {
clientX: xUp,
clientY: yUp
} = getTouch(e);
const xDiff = xDown - xUp;
const yDiff = yDown - yUp;
const xDiffAbs = Math.abs(xDown - xUp);
const yDiffAbs = Math.abs(yDown - yUp);
// at least <offset> are a swipe
if (Math.max(xDiffAbs, yDiffAbs) < offset ) {
return;
}
if (xDiffAbs > yDiffAbs) {
if ( xDiff > 0 ) {
console.log('left');
} else {
console.log('right');
}
} else {
if ( yDiff > 0 ) {
console.log('up');
} else {
console.log('down');
}
}
});
function getTouch (e) {
return e.changedTouches[0]
}
आपके पास एक आसान समय हो सकता है पहले इसे माउस घटनाओं के साथ प्रोटोटाइप में लागू करें।
यहां कई उत्तर दिए गए हैं, जिनमें शीर्ष भी शामिल हैं, उन्हें सावधानी के साथ इस्तेमाल किया जाना चाहिए क्योंकि वे विशेष रूप से बाउंडिंग बॉक्स के आसपास के किनारे मामलों पर विचार नहीं करते हैं।
देख:
आपको किनारे के मामलों और व्यवहारों को पकड़ने के लिए प्रयोग करने की आवश्यकता होगी जैसे कि सूचक समाप्त होने से पहले तत्व के बाहर घूम रहा है।
एक स्वाइप एक बहुत ही बुनियादी इशारा है जो कच्चे घटनाओं और लिखावट की पहचान के बीच मोटे तौर पर बैठकर इंटरफेस पॉइंटर इंटरैक्शन प्रोसेसिंग का एक उच्च स्तर है।
स्वाइप या फ़्लिंग का पता लगाने के लिए कोई सटीक तरीका नहीं है, हालांकि लगभग सभी आम तौर पर दूरी और गति या वेग की सीमा के साथ एक तत्व में गति का पता लगाने के एक बुनियादी सिद्धांत का पालन करते हैं। आप बस यह कह सकते हैं कि यदि किसी निश्चित समय के भीतर स्क्रीन आकार में 65% की गति है, तो यह एक स्वाइप है। ठीक उसी तरह जहां आप रेखा खींचते हैं और आप इसकी गणना कैसे करते हैं यह आपके ऊपर है।
कुछ इसे एक दिशा में गति के दृष्टिकोण से भी देख सकते हैं और तत्व जारी होने पर इसे स्क्रीन से कितनी दूर धकेल दिया गया है। यह चिपचिपा स्वाइप्स के साथ स्पष्ट है जहां तत्व को खींचा जा सकता है और फिर रिलीज पर या तो वापस उछल जाएगा या स्क्रीन से उड़ जाएगा जैसे कि लोचदार टूट गया।
यह संभवतः एक इशारा पुस्तकालय खोजने की कोशिश करने के लिए आदर्श है जिसे आप या तो पोर्ट कर सकते हैं या पुन: उपयोग कर सकते हैं जो आमतौर पर स्थिरता के लिए उपयोग किया जाता है। यहां कई उदाहरण अत्यधिक सरलीकृत हैं, किसी भी दिशा में मामूली स्पर्श के रूप में स्वाइप को पंजीकृत करना।
एंड्रॉइड स्पष्ट पसंद होगा हालांकि विपरीत समस्या है, यह अत्यधिक जटिल है।
कई लोग इस सवाल का गलत मतलब निकाल रहे हैं कि वे किसी भी दिशा में आंदोलन कर रहे हैं। स्वाइप एक व्यापक और अपेक्षाकृत संक्षिप्त गति है जो एक ही दिशा में (हालांकि हो सकता है और कुछ त्वरण गुण हो)। एक फ्लिंग के समान है, हालांकि अपने स्वयं के गति के तहत उचित दूरी पर किसी वस्तु को लापरवाही से चलाने का इरादा रखता है।
दोनों पर्याप्त रूप से समान हैं कि कुछ पुस्तकालय केवल फ़्लिंग या स्वाइप प्रदान कर सकते हैं, जिसका उपयोग पारस्परिक रूप से किया जा सकता है। एक फ्लैट स्क्रीन पर यह वास्तव में दो इशारों को अलग करना मुश्किल है और आम तौर पर बोलने वाले लोग दोनों कर रहे हैं (भौतिक स्क्रीन को स्वाइप करना लेकिन स्क्रीन पर प्रदर्शित यूआई तत्व को फ़्लिप करना)।
आप सबसे अच्छा विकल्प यह है कि आप इसे स्वयं न करें। सरल इशारों का पता लगाने के लिए पहले से ही बड़ी संख्या में जावास्क्रिप्ट लाइब्रेरी हैं ।
मैं एक प्रतिक्रिया हुक के रूप में कार्य करने के लिए @givanse के समाधान को फिर से काम करता हूं । इनपुट कुछ वैकल्पिक ईवेंट श्रोताओं है, आउटपुट एक कार्यात्मक रेफरी है (कार्यात्मक होने की आवश्यकता है ताकि हुक जब / फिर से बदल जाए तो हुक फिर से चल सके)।
वर्टिकल / हॉरिजॉन्टल स्वाइप थ्रेशोल्ड परम में भी जोड़ा गया है, ताकि छोटी गतियां गलती से ईवेंट श्रोताओं को ट्रिगर न करें, लेकिन ये मूल उत्तर को अधिक बारीकी से नकल करने के लिए 0 पर सेट किया जा सकता है।
टिप: सर्वश्रेष्ठ प्रदर्शन के लिए, इवेंट श्रोता इनपुट फ़ंक्शंस को याद किया जाना चाहिए।
function useSwipeDetector({
// Event listeners.
onLeftSwipe,
onRightSwipe,
onUpSwipe,
onDownSwipe,
// Threshold to detect swipe.
verticalSwipeThreshold = 50,
horizontalSwipeThreshold = 30,
}) {
const [domRef, setDomRef] = useState(null);
const xDown = useRef(null);
const yDown = useRef(null);
useEffect(() => {
if (!domRef) {
return;
}
function handleTouchStart(evt) {
const [firstTouch] = evt.touches;
xDown.current = firstTouch.clientX;
yDown.current = firstTouch.clientY;
};
function handleTouchMove(evt) {
if (!xDown.current || !yDown.current) {
return;
}
const [firstTouch] = evt.touches;
const xUp = firstTouch.clientX;
const yUp = firstTouch.clientY;
const xDiff = xDown.current - xUp;
const yDiff = yDown.current - yUp;
if (Math.abs(xDiff) > Math.abs(yDiff)) {/*most significant*/
if (xDiff > horizontalSwipeThreshold) {
if (onRightSwipe) onRightSwipe();
} else if (xDiff < -horizontalSwipeThreshold) {
if (onLeftSwipe) onLeftSwipe();
}
} else {
if (yDiff > verticalSwipeThreshold) {
if (onUpSwipe) onUpSwipe();
} else if (yDiff < -verticalSwipeThreshold) {
if (onDownSwipe) onDownSwipe();
}
}
};
function handleTouchEnd() {
xDown.current = null;
yDown.current = null;
}
domRef.addEventListener("touchstart", handleTouchStart, false);
domRef.addEventListener("touchmove", handleTouchMove, false);
domRef.addEventListener("touchend", handleTouchEnd, false);
return () => {
domRef.removeEventListener("touchstart", handleTouchStart);
domRef.removeEventListener("touchmove", handleTouchMove);
domRef.removeEventListener("touchend", handleTouchEnd);
};
}, [domRef, onLeftSwipe, onRightSwipe, onUpSwipe, onDownSwipe, verticalSwipeThreshold, horizontalSwipeThreshold]);
return (ref) => setDomRef(ref);
};