আপনি কীভাবে সনাক্ত করতে পারেন যে কোনও ব্যবহারকারী জাভাস্ক্রিপ্টের সাহায্যে কোনও ওয়েবপৃষ্ঠায় কিছু দিক দিয়ে নিজের আঙ্গুলটি সরিয়ে দিয়েছেন?
আমি ভাবছিলাম যে এমন কোনও সমাধান আছে যা আইফোন এবং অ্যান্ড্রয়েড ফোন উভয় ওয়েবসাইটের জন্য কাজ করবে।
আপনি কীভাবে সনাক্ত করতে পারেন যে কোনও ব্যবহারকারী জাভাস্ক্রিপ্টের সাহায্যে কোনও ওয়েবপৃষ্ঠায় কিছু দিক দিয়ে নিজের আঙ্গুলটি সরিয়ে দিয়েছেন?
আমি ভাবছিলাম যে এমন কোনও সমাধান আছে যা আইফোন এবং অ্যান্ড্রয়েড ফোন উভয় ওয়েবসাইটের জন্য কাজ করবে।
উত্তর:
সাধারণ ভ্যানিলা জেএস কোড নমুনা:
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;
};
অ্যান্ড্রয়েডে পরীক্ষিত।
touchstart
, touchmove
?
@ জিভানসের উত্তরের ভিত্তিতে, আপনি এটি দিয়ে এটি করতে পারেন 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
আসলে কিছুই ফেরেনি return এটা যখন সঙ্গে ফাংশন কলিং বেঁধে ডাকতে অকাজের this.
কারণ এটি ইতিমধ্যেই বর্তমান প্রসঙ্গ আবদ্ধ
.bind(this);
এবং এটি দুর্দান্তভাবে কাজ করেছে। আপনাকে ধন্যবাদ_নিচোলাস_আর
touches[0]
করুন changedTouches[0]
এবং ইভেন্ট হ্যান্ডলারটি টাইপ handleTouchMove
করুনhandleTouchEnd
run()
দু'বার কল করুন এবং আপনি একটি বাজে মেমরি ফাঁস করুন
আমি এখানে কয়েকটি উত্তর একটি স্ক্রিপ্টে একীভূত করেছি যা ডিওএম-এ স্যুইপ করা ইভেন্টগুলিকে ফায়ার করতে কাস্টম এভেন্ট ব্যবহার করে। 0.7k যোগ দিয়েছেন কিনা-events.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
});
আপনার পৃষ্ঠায় সোয়াইপ ইন্টারঅ্যাকশন কার্যকারিতা (এইগুলি optionচ্ছিক) কীভাবে আপনি টুইঙ্ক করতে নীচের বৈশিষ্ট্যগুলি নির্দিষ্ট করতে পারেন ।
<div data-swipe-threshold="10"
data-swipe-timeout="1000"
data-swipe-ignore="false">
Swiper, get swiping!
</div>
আমি আগে যা ব্যবহার করেছি তা হল আপনাকে মোসডাউন ইভেন্টটি সনাক্ত করতে হবে, এর এক্স, ওয়াই অবস্থান (যা প্রাসঙ্গিক) রেকর্ড করতে হবে তারপরে মাউসআপ ইভেন্টটি সনাক্ত করতে হবে এবং দুটি মানকে বিয়োগ করতে হবে।
jQuery মোবাইল এছাড়াও সোয়াইপ সমর্থন অন্তর্ভুক্ত: http://api.jquerymobile.com/swipe/
উদাহরণ
$("#divId").on("swipe", function(event) {
alert("It's a swipe!");
});
আমি জিগ্যান্সের উজ্জ্বল উত্তরটি সোয়াইপ ক্রিয়াগুলি নিবন্ধ করার জন্য একাধিক মোবাইল ব্রাউজার জুড়ে সবচেয়ে নির্ভরযোগ্য এবং সামঞ্জস্যপূর্ণ বলে খুঁজে পেয়েছি।
তবে, আধুনিক কোড ব্যবহার করা মোবাইল ব্রাউজারগুলিতে এটি কার্যকর করার জন্য তার কোডে পরিবর্তন আনতে হবে 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;
}
};
ট্র্যাশোল্ড, টাইমআউট সোয়াইপ, সোয়াইপ ব্লকএলেমস যুক্ত করুন।
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 মোবাইল ব্যবহার করার চেষ্টা করছেন এবং জিকিউএম সোয়াইপ সনাক্তকরণে সমস্যা রয়েছে
(এক্সপিরিয়া জেড 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
}
খুব দীর্ঘ, সুনির্দিষ্ট এবং দ্রুত সোয়াইপ না করা থাকলে অ্যান্ড্রয়েডে সোয়াইপ সনাক্ত করা যায়নি।
এই দুটি লাইন দিয়ে এটি সঠিকভাবে কাজ করে
$.event.special.swipe.scrollSupressionThreshold = 8;
তবে আপনি আমাকে সঠিক দিকে রাখলেন! ধন্যবাদ!
ব্যবহারকারী যখন চারপাশে একটি আঙুল টেনে নিচ্ছিলেন তখন অবিরত স্পর্শের হাতল দিয়ে গুলি চালানোয় আমার সমস্যা হয়েছিল। আমি জানি না যে এটি এমন কোনও কারণে হয়েছে যা আমি ভুল করছি বা না করছি তবে আমি টাচমোভের সাথে চলনগুলি জড়ো করতে এবং পুনরায় স্পর্শ করার জন্য কলব্যাকটিকে আগুনে ছড়িয়ে দিতে পুনরায় এটি করেছি।
আমার কাছে এই সংখ্যার প্রচুর পরিমাণে থাকাও দরকার এবং তাই আমি সক্ষম / অক্ষম পদ্ধতিগুলি যুক্ত করেছি।
এবং একটি প্রান্তিক যেখানে একটি সংক্ষিপ্ত সোয়াইপ আগুন দেয় না। টাচস্টার্ট শূন্য প্রতিবার কাউন্টার।
আপনি ফ্লাইতে লক্ষ্য_নোড পরিবর্তন করতে পারেন। সৃষ্টিতে সক্ষম করা alচ্ছিক।
/** 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.');
}
});
এটি কনসোল ত্রুটিগুলি এড়াতে সহায়তা করে যখন আপনি কেবল কল করতে চান কেবল "অন লেফট" পদ্ধতিটি বলুন।
ব্যবহৃত দুটি:
jQuery মোবাইল: বেশিরভাগ ক্ষেত্রে কাজ করুন এবং বিশেষত আপনি যখন অ্যাপ্লিকেশন বিকাশ করেন যা অন্যান্য jQuery প্লাগইন ব্যবহার করে তবে এর জন্য jQuery মোবাইল নিয়ন্ত্রণ ব্যবহার করা আরও ভাল। এটি এখানে দেখুন: https://www.w3schools.com/jquerymobile/jquerymobile_events_touch.asp
হাতুড়ি সময় ! অন্যতম সেরা, লাইটওয়েট এবং দ্রুত জাভাস্ক্রিপ্ট ভিত্তিক লাইব্রেরি। এটি এখানে দেখুন: https://hammerjs.github.io/
আপনার যদি কেবল সোয়াইপ দরকার হয় তবে আপনার প্রয়োজনীয় অংশটি ব্যবহার করে আপনি আকারের চেয়ে ভাল better এটি কোনও স্পর্শ ডিভাইসে কাজ করা উচিত।
এটি জিপিপ সংক্ষেপণ, মিনিফিকেশন, বাবেল ইত্যাদির পরে ~ 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;
আমি কেবল বাম এবং ডানদিকে সোয়াইপ সনাক্ত করতে চেয়েছিলাম, তবে কেবলমাত্র স্পর্শ ইভেন্টটি শেষ হলেই অ্যাকশনটি ট্রিগার করেছিলাম, তাই এটি করার জন্য আমি @ জিভান্সের দুর্দান্ত উত্তরটি কিছুটা সংশোধন করেছি।
কেন করবেন? উদাহরণস্বরূপ, যদি সোয়াইপ করার সময় ব্যবহারকারী লক্ষ্য করে যে অবশেষে তিনি সোয়াইপ করতে চান না, তবে তিনি আঙ্গুলটি মূল অবস্থানে নিয়ে যেতে পারেন (খুব জনপ্রিয় "ডেটিং" ফোন অ্যাপ্লিকেশন এটি করে;)) এবং তারপরে "সোয়াইপ ডান" ইভেন্ট বাতিল করা হয়েছে।
সুতরাং অনুভূমিকভাবে 3px পার্থক্য থাকার কারণে একটি "সোয়াইপ রাইট" ইভেন্ট এড়ানোর জন্য, আমি একটি প্রান্তিক অংশ যুক্ত করেছি যার অধীনে একটি ইভেন্টটি বাতিল করা হয়েছে: "সোয়াইপ রাইট" ইভেন্টের জন্য, ব্যবহারকারীকে কমপক্ষে সোয়াইপ করতে হবে ব্রাউজারের প্রস্থের 1/3 অংশ (অবশ্যই আপনি এটি সংশোধন করতে পারেন)।
এই সমস্ত ছোট বিবরণ ব্যবহারকারীর অভিজ্ঞতা বাড়ায়। এখানে (ভ্যানিলা জেএস) কোডটি রয়েছে:
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% জুড়ে কোনও গতিবিধি থাকে তবে এটি একটি সোয়াইপ। ঠিক কোথায় আপনি লাইনটি আঁকেন এবং আপনি এটি কীভাবে গণনা করেন তা আপনার উপর নির্ভর করে।
কেউ কেউ এটিকে কোনও দিকে গতিবেগের দৃষ্টিকোণ থেকেও দেখতে পারে এবং যখন উপাদানটি প্রকাশিত হয় তখন পর্দার বাইরে কতটা ধাক্কা দেওয়া হয়েছিল। এটি স্টিকি সোয়াইপগুলির সাথে পরিষ্কার যেখানে উপাদানটি টেনে আনা যায় এবং তারপরে মুক্তির পরে হয় পিছনে ফিরে আসে বা স্ক্রিনটি উড়ে যায় যেন ইলাস্টিকটি ভেঙে যায়।
আপনি সম্ভবত একটি ধারাবাহিকতার জন্য ব্যবহৃত হয় যা বন্দর বা পুনরায় ব্যবহার করতে পারেন এমন কোনও অঙ্গভঙ্গি গ্রন্থাগারটি সন্ধান করার জন্য এটি সম্ভবত আদর্শ। এখানে উদাহরণগুলির মধ্যে অনেকগুলি অতিরিক্ত সরল, কোনও দিকের সামান্যতম স্পর্শ হিসাবে একটি সোয়াইপ রেজিস্ট্রেশন করে।
অ্যান্ড্রয়েডবিপরীত সমস্যা থাকলেও সুস্পষ্ট পছন্দ হবে, এটি অত্যধিক জটিল।
অনেকে মনে হয় যে কোনও দিককে কোনও আন্দোলন হিসাবে প্রশ্নটির ভুল ব্যাখ্যা করেছেন। একটি সোয়াইপ একটি বিস্তৃত এবং অপেক্ষাকৃত সংক্ষিপ্ত গতি অবিচ্ছিন্নভাবে একটি একক দিকের মধ্যে (যদিও এটি আটকানো হতে পারে এবং নির্দিষ্ট ত্বরণের বৈশিষ্ট্য থাকতে পারে)। একটি ঝাঁকুনি একই রকম হয় যদিও তার গতিবেগের অধীনে একটি আইটেম ন্যায্য দূরত্ব দূরে দূরে চালিত করতে চায় inte
দুটি যথেষ্ট পরিমাণে সমান যে কিছু লাইব্রেরি কেবল ঝাঁকুনি বা সোয়াইপ সরবরাহ করতে পারে যা বিনিময়যোগ্যভাবে ব্যবহার করা যেতে পারে। একটি সমতল স্ক্রিনে দুটি অঙ্গভঙ্গিকে সত্যই পৃথক করা কঠিন এবং সাধারণভাবে বক্তারা লোকেরা উভয়ই করছেন (শারীরিক পর্দাটি স্যুইপ করছে তবে স্ক্রিনে প্রদর্শিত ইউআই উপাদানটি উড়িয়ে দিচ্ছে)।
আপনার সেরা বিকল্পটি এটি নিজে না করা। সাধারণ অঙ্গভঙ্গিগুলি সনাক্ত করার জন্য ইতিমধ্যে প্রচুর জাভাস্ক্রিপ্ট লাইব্রেরি রয়েছে ।
আমি @ জিভান্সের সমাধানটিকে একটি প্রতিক্রিয়া হুক হিসাবে কাজ করতে পুনরায় কাজ করেছি। ইনপুটটি হ'ল কিছু eventচ্ছিক ইভেন্ট শ্রোতা, আউটপুট একটি কার্যকরী রেফ (ফাংশনাল হওয়া দরকার যাতে / যখন রেফ পরিবর্তন হয় তবে হুকটি আবার চালাতে পারে)।
উল্লম্ব / অনুভূমিক সোয়াইপ থ্রেশহোল্ড প্যারামেও যুক্ত করা হয়েছে, যাতে ছোট গতিগুলি ঘটনাক্রমে ইভেন্ট শ্রোতাদের ট্রিগার না করে তবে মূল উত্তরটি আরও ঘনিষ্ঠভাবে নকল করতে 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);
};