আইফোন এবং অ্যান্ড্রয়েডে জাভাস্ক্রিপ্টের মাধ্যমে একটি আঙুলের সোয়াইপ সনাক্ত করুন


268

আপনি কীভাবে সনাক্ত করতে পারেন যে কোনও ব্যবহারকারী জাভাস্ক্রিপ্টের সাহায্যে কোনও ওয়েবপৃষ্ঠায় কিছু দিক দিয়ে নিজের আঙ্গুলটি সরিয়ে দিয়েছেন?

আমি ভাবছিলাম যে এমন কোনও সমাধান আছে যা আইফোন এবং অ্যান্ড্রয়েড ফোন উভয় ওয়েবসাইটের জন্য কাজ করবে।


1
সোয়াইপ স্বীকৃতির জন্য, আমি হ্যামার.জেএস সুপারিশ করব । এটি বেশ ছোট, এবং এটি অনেকগুলি অঙ্গভঙ্গি সমর্থন করে: - সোয়াইপ - ঘোরানো - চিমটি - টিপুন (দীর্ঘ হোল্ড) - ট্যাপ - প্যান
উইল ব্রিকারার

একটি ইভেন্ট রয়েছে: "টাচমোভ"
ক্লে

@ ক্লে যে একজন এখনও সাফারি তে কাজ করে না তাই কোনও আইফোন নেই।
জাকুজে

উত্তর:


341

সাধারণ ভ্যানিলা জেএস কোড নমুনা:

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;                                             
};

অ্যান্ড্রয়েডে পরীক্ষিত।


1
সৌন্দর্য ঠান্ডা এবং সহজ, কোন ধারণা এই ইভেন্টের জন্য সমর্থন কি touchstart, touchmove?
d.raev

1
এটি বেশ ভাল কাজ করে তবে সোজা চলাচল সনাক্ত করতে সমস্যা আছে। আমি এই বিষয়ে আরও একটি উত্তর পোস্ট করব যা এটিকে JQuery (ডেস্কটপ) সমাধান হিসাবে স্থির করেছে। এটি এই সোয়াইপ ইভেন্টগুলির মাউস সংস্করণ যুক্ত করে এবং সংবেদনশীলতা বিকল্প যুক্ত করে।
কোডবিট

1
অভিশাপ। বিষয় বন্ধ আছে তাই আমার উত্তর যুক্ত করতে পারে না!
কোডবিট

3
এটি দুর্দান্ত কাজ করে তবে বাম / ডান এবং উপরে / নীচে পিছনের দিকে থাকে।
পিটার আইসেন্ট্রাট

4
অরিজিনাল ইভেন্ট একটি জিকুয়ের সম্পত্তি। আপনি যদি JQuery ব্যতীত খাঁটি জাভাস্ক্রিপ্ট চালনা করেন তবে এটি ছেড়ে দেওয়া উচিত। JQuery ব্যতীত চলমান কোডটি একটি ব্যতিক্রম উত্থাপন করে।
জান ডার্ক

31

@ জিভানসের উত্তরের ভিত্তিতে, আপনি এটি দিয়ে এটি করতে পারেন 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();

7
এই কোডটি সম্ভবত কাজ করবে .bindনা কারণ অপরিজ্ঞাত কল করার চেষ্টা করার সময় আপনি একটি ব্যতিক্রম পাবেন কারণ আপনার handleTouchMoveআসলে কিছুই ফেরেনি return এটা যখন সঙ্গে ফাংশন কলিং বেঁধে ডাকতে অকাজের this.কারণ এটি ইতিমধ্যেই বর্তমান প্রসঙ্গ আবদ্ধ
nick.skriabin

3
আমি সবে সরিয়েছি .bind(this);এবং এটি দুর্দান্তভাবে কাজ করেছে। আপনাকে ধন্যবাদ_নিচোলাস_আর
আলী ঘানাভাটিয়ান

অংশটি নিজেই পান উপাদানটিকে আমি ডকুমেন্ট.জেটএলমেন্টবিআইআইডি ('মাই-এলিমেন্ট') এ '#' অপসারণ করেছি এবং এটি ভাল কাজ করেছে। আপনাকে @ মারওলেন :) ধন্যবাদ
ব্লু ট্রাম

4
আপনি যদি সোয়াইপ সমাপ্ত না হওয়া অবধি অপেক্ষা করতে চান (অর্থাত্ তারা তাদের আঙুল বা অনম্যাসআপ উত্থাপনের পরে), তে পরিবর্তন touches[0]করুন changedTouches[0]এবং ইভেন্ট হ্যান্ডলারটি টাইপ handleTouchMoveকরুনhandleTouchEnd
তেত্রদেব

run()দু'বার কল করুন এবং আপনি একটি বাজে মেমরি ফাঁস করুন
মাদুর

20

আমি এখানে কয়েকটি উত্তর একটি স্ক্রিপ্টে একীভূত করেছি যা ডিওএম-এ স্যুইপ করা ইভেন্টগুলিকে ফায়ার করতে কাস্টম এভেন্ট ব্যবহার করে। 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>

সোথ কোডটি গিথুবে পাওয়া যায়


আমি এখানে এসেছি কারণ খাঁটি সোয়াইপ
মোবাইলের

@StefanBob যদি আপনি একটি টিক বাড়াতে GitHub রেপো যথেষ্ট তথ্য আমার সমস্যা পুনর্গঠন করার অনুমতি দেয়, আমি এটা দেখব
জন ডোহার্টি

1
ধন্যবাদ, এটি পুরোপুরি কাজ করে! আমি হ্যামার.জেসগুলিকে আপনার লাইব্রেরির সাথে প্রতিস্থাপন করেছি, কারণ পূর্ববর্তী ব্রাউজার জুমের সাথে কাজ করে না এবং এটি একটি মারাত্মক ব্যবহারযোগ্যতার সমস্যা। এই লাইব্রেরির সাথে জুমটি সঠিকভাবে কাজ করে (অ্যান্ড্রয়েডে পরীক্ষিত)
কলিমার্কো

15

আমি আগে যা ব্যবহার করেছি তা হল আপনাকে মোসডাউন ইভেন্টটি সনাক্ত করতে হবে, এর এক্স, ওয়াই অবস্থান (যা প্রাসঙ্গিক) রেকর্ড করতে হবে তারপরে মাউসআপ ইভেন্টটি সনাক্ত করতে হবে এবং দুটি মানকে বিয়োগ করতে হবে।


28
আমি বিশ্বাস করি যে এটি টাচস্টার্ট, টাচমোভ, টাচক্যান্সেল এবং স্পর্শ করুন যে এটি একটির সাথে কাজ করবে, মোউসডাউন বা মাউসআপ নয়।
ভোলোমাইক


12

আমি জিগ্যান্সের উজ্জ্বল উত্তরটি সোয়াইপ ক্রিয়াগুলি নিবন্ধ করার জন্য একাধিক মোবাইল ব্রাউজার জুড়ে সবচেয়ে নির্ভরযোগ্য এবং সামঞ্জস্যপূর্ণ বলে খুঁজে পেয়েছি।

তবে, আধুনিক কোড ব্যবহার করা মোবাইল ব্রাউজারগুলিতে এটি কার্যকর করার জন্য তার কোডে পরিবর্তন আনতে হবে 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;                                             
};

পরীক্ষিত:

  • অ্যান্ড্রয়েড : ক্রোম, ইউসি ব্রাউজার
  • আইওএস : সাফারি, ক্রোম, ইউসি ব্রাউজার

অরিজিনাল ইভেন্ট একটি জিকুয়ের সম্পত্তি। এটি খাঁটি জাভাস্ক্রিপ্টেও নেই।
জান ডার্ক

1
এই এই উত্তর হিসাবে , ব্রাউজার দ্বারা সমর্থিত যদি একটি স্পর্শ ইভেন্ট প্রকাশ করা হবে event.originalEvent। জিনিসটি event.touchesএখন বিদ্যমান থাকা বন্ধ হয়ে গেছে এবং এর ফলস্বরূপ undefined
ন্যাশচিজ

ইভেন্ট.টুচগুলি কেবল জিকুয়েরি ব্যবহার করার সময় উপস্থিত ছিল না। আপনার কোডটি JQuery ছাড়াই চেষ্টা করুন এবং আপনি একটি ত্রুটি পাবেন যা evt.originalEvent অপরিজ্ঞাত is জিকুয়েরি ইভেন্টটিকে পুরোপুরি নিজের সাথে প্রতিস্থাপন করে এবং নেটিভ ব্রাউজার ইভেন্টটিকে মূল উত্সে রাখে। সংক্ষিপ্ত সংস্করণ: আপনার কোডটি কেবল JQuery এর সাথে কাজ করে। আপনি জাভালিকা সরিয়ে ফেললে এটি জিকুয়ারি ছাড়াই কাজ করে।
জান ডার্ক

1
হ্যাঁ আমি কিছুটা গবেষণা করেছি এবং বুঝতে পেরেছিলাম যে আপনি jquery সক্ষম করার প্রাপ্যতা সম্পর্কে সঠিক ছিলেন event.originalEvent। আমি আমার উত্তর আপডেট করব। ধন্যবাদ! :)
ন্যাশচিজ


6

সংক্ষিপ্ত সোয়াইপগুলির সাথে মোকাবিলা করার জন্য কয়েকটি আধুনিক উত্তর (মন্তব্য করতে পারে না ...)

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;
    }
};

6

ট্র্যাশোল্ড, টাইমআউট সোয়াইপ, সোয়াইপ ব্লকএলেমস যুক্ত করুন।

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;
}

4

যদি কেউ অ্যান্ড্রয়েডে 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;তবে আপনি আমাকে সঠিক দিকে রাখলেন! ধন্যবাদ!
ফিলিপ জি

4

ব্যবহারকারী যখন চারপাশে একটি আঙুল টেনে নিচ্ছিলেন তখন অবিরত স্পর্শের হাতল দিয়ে গুলি চালানোয় আমার সমস্যা হয়েছিল। আমি জানি না যে এটি এমন কোনও কারণে হয়েছে যা আমি ভুল করছি বা না করছি তবে আমি টাচমোভের সাথে চলনগুলি জড়ো করতে এবং পুনরায় স্পর্শ করার জন্য কলব্যাকটিকে আগুনে ছড়িয়ে দিতে পুনরায় এটি করেছি।

আমার কাছে এই সংখ্যার প্রচুর পরিমাণে থাকাও দরকার এবং তাই আমি সক্ষম / অক্ষম পদ্ধতিগুলি যুক্ত করেছি।

এবং একটি প্রান্তিক যেখানে একটি সংক্ষিপ্ত সোয়াইপ আগুন দেয় না। টাচস্টার্ট শূন্য প্রতিবার কাউন্টার।

আপনি ফ্লাইতে লক্ষ্য_নোড পরিবর্তন করতে পারেন। সৃষ্টিতে সক্ষম করা 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);
            }
        }
    }
}

এটি কি ES5 বা ES6 এর জন্য?
1.21 গিগাওয়াটস

@ Gigawatts- এর কথা আমার মনে নেই। যে প্রকল্পটি এটি ব্যবহার করেছে এটি ইতিমধ্যে EOL এ পৌঁছেছে এবং তখন থেকে আমার কোডটির প্রয়োজন নেই। আমি সন্দেহ করি তখন আমি ইএস 6 এর জন্য লিখছিলাম তবে এটি 2 বছর আগে।
ট্রেন্ডাল টিউজ

3

আমি বেশ কয়েকটি উত্তরও একত্রীভূত করেছি, বেশিরভাগই প্রথম এবং দ্বিতীয়টি ক্লাসগুলির সাথে এবং এখানে আমার সংস্করণটি রয়েছে:

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.');
                    }
});

এটি কনসোল ত্রুটিগুলি এড়াতে সহায়তা করে যখন আপনি কেবল কল করতে চান কেবল "অন লেফট" পদ্ধতিটি বলুন।


2

ব্যবহৃত দুটি:

jQuery মোবাইল: বেশিরভাগ ক্ষেত্রে কাজ করুন এবং বিশেষত আপনি যখন অ্যাপ্লিকেশন বিকাশ করেন যা অন্যান্য jQuery প্লাগইন ব্যবহার করে তবে এর জন্য jQuery মোবাইল নিয়ন্ত্রণ ব্যবহার করা আরও ভাল। এটি এখানে দেখুন: https://www.w3schools.com/jquerymobile/jquerymobile_events_touch.asp

হাতুড়ি সময় ! অন্যতম সেরা, লাইটওয়েট এবং দ্রুত জাভাস্ক্রিপ্ট ভিত্তিক লাইব্রেরি। এটি এখানে দেখুন: https://hammerjs.github.io/


2

আপনার যদি কেবল সোয়াইপ দরকার হয় তবে আপনার প্রয়োজনীয় অংশটি ব্যবহার করে আপনি আকারের চেয়ে ভাল 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;


2

আমি কেবল বাম এবং ডানদিকে সোয়াইপ সনাক্ত করতে চেয়েছিলাম, তবে কেবলমাত্র স্পর্শ ইভেন্টটি শেষ হলেই অ্যাকশনটি ট্রিগার করেছিলাম, তাই এটি করার জন্য আমি @ জিভান্সের দুর্দান্ত উত্তরটি কিছুটা সংশোধন করেছি।

কেন করবেন? উদাহরণস্বরূপ, যদি সোয়াইপ করার সময় ব্যবহারকারী লক্ষ্য করে যে অবশেষে তিনি সোয়াইপ করতে চান না, তবে তিনি আঙ্গুলটি মূল অবস্থানে নিয়ে যেতে পারেন (খুব জনপ্রিয় "ডেটিং" ফোন অ্যাপ্লিকেশন এটি করে;)) এবং তারপরে "সোয়াইপ ডান" ইভেন্ট বাতিল করা হয়েছে।

সুতরাং অনুভূমিকভাবে 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;
}

1

অনুভূমিক সোয়াইপের জন্য সরল ভ্যানিলা জেএস উদাহরণ:

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()
})

উল্লম্ব সোয়াইপের জন্য আপনি বেশ একই যুক্তি ব্যবহার করতে পারেন।


1

এখানে এই উত্তর যুক্ত করা হচ্ছে । এই একটি ডেস্কটপে পরীক্ষার জন্য মাউস ইভেন্টগুলির জন্য সমর্থন যোগ করে:

<!--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!') })
});

0

অফসেট দিয়ে কীভাবে ব্যবহার করবেন তার একটি উদাহরণ।

// 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]
}


বর্তমানে এই সংস্করণটি ব্যবহার করা হচ্ছে। পুনরাবৃত্তিটি সোয়াইপ করা হলে আমি কীভাবে এটি একাধিকবার গুলি চালানো থেকে রোধ করব? আমি এটিকে অ্যানিমেট বৈশিষ্ট্যটির সাথে পার্সক্রোলিং ফর্মের জন্য ব্যবহার করি এবং যখন আমি একাধিকবার সোয়াইপ করি তখন জিনিসগুলি কিছুটা স্ক্রু হয়ে যায় এবং দৃশ্যমান অঞ্চলে আমার ডিভগুলি ওভারল্যাপিং শুরু করে start
এনএমএলএএম

0

আপনার মাউসের ইভেন্টগুলি প্রোটোটাইপের সাথে এটি প্রয়োগের জন্য প্রথমে আরও সহজ সময় থাকতে পারে।

শীর্ষগুলি সহ অনেকগুলি উত্তর এখানে সাবধানতার সাথে ব্যবহার করা উচিত কারণ তারা প্রান্তের কেসগুলি বিশেষত বাউন্ডিং বাক্সের আশেপাশে বিবেচনা করে না।

দেখা:

প্রান্তের কেস এবং আচরণগুলি যেমন পয়েন্টারটি উপাদানটির বাইরে চলে যাবার আগে শেষ করার আগে আপনাকে পরীক্ষা করতে হবে।

একটি সোয়াইপ একটি খুব প্রাথমিক অঙ্গভঙ্গি যা কাঁচা ইভেন্টগুলি প্রক্রিয়াকরণ এবং হস্তাক্ষর স্বীকৃতির স্বীকৃতিগুলির মধ্যে মোটামুটিভাবে বসে ইন্টারফেস পয়েন্টার ইন্টারঅ্যাকশন প্রসেসিংয়ের একটি উচ্চ স্তরের।

সোয়াইপ বা ঝাঁকুনির শনাক্তকরণের জন্য সঠিক কোনও পদ্ধতি নেই যদিও কার্যত সকলেই দূরত্ব এবং গতি বা বেগের দ্বার সহ একটি উপাদান জুড়ে একটি গতি সনাক্ত করার প্রাথমিক নীতি অনুসরণ করে। আপনি সহজেই বলতে পারেন যে যদি নির্দিষ্ট সময়ের মধ্যে কোনও প্রদত্ত দিকের পর্দার আকারের 65% জুড়ে কোনও গতিবিধি থাকে তবে এটি একটি সোয়াইপ। ঠিক কোথায় আপনি লাইনটি আঁকেন এবং আপনি এটি কীভাবে গণনা করেন তা আপনার উপর নির্ভর করে।

কেউ কেউ এটিকে কোনও দিকে গতিবেগের দৃষ্টিকোণ থেকেও দেখতে পারে এবং যখন উপাদানটি প্রকাশিত হয় তখন পর্দার বাইরে কতটা ধাক্কা দেওয়া হয়েছিল। এটি স্টিকি সোয়াইপগুলির সাথে পরিষ্কার যেখানে উপাদানটি টেনে আনা যায় এবং তারপরে মুক্তির পরে হয় পিছনে ফিরে আসে বা স্ক্রিনটি উড়ে যায় যেন ইলাস্টিকটি ভেঙে যায়।

আপনি সম্ভবত একটি ধারাবাহিকতার জন্য ব্যবহৃত হয় যা বন্দর বা পুনরায় ব্যবহার করতে পারেন এমন কোনও অঙ্গভঙ্গি গ্রন্থাগারটি সন্ধান করার জন্য এটি সম্ভবত আদর্শ। এখানে উদাহরণগুলির মধ্যে অনেকগুলি অতিরিক্ত সরল, কোনও দিকের সামান্যতম স্পর্শ হিসাবে একটি সোয়াইপ রেজিস্ট্রেশন করে।

অ্যান্ড্রয়েডবিপরীত সমস্যা থাকলেও সুস্পষ্ট পছন্দ হবে, এটি অত্যধিক জটিল।

অনেকে মনে হয় যে কোনও দিককে কোনও আন্দোলন হিসাবে প্রশ্নটির ভুল ব্যাখ্যা করেছেন। একটি সোয়াইপ একটি বিস্তৃত এবং অপেক্ষাকৃত সংক্ষিপ্ত গতি অবিচ্ছিন্নভাবে একটি একক দিকের মধ্যে (যদিও এটি আটকানো হতে পারে এবং নির্দিষ্ট ত্বরণের বৈশিষ্ট্য থাকতে পারে)। একটি ঝাঁকুনি একই রকম হয় যদিও তার গতিবেগের অধীনে একটি আইটেম ন্যায্য দূরত্ব দূরে দূরে চালিত করতে চায় inte

দুটি যথেষ্ট পরিমাণে সমান যে কিছু লাইব্রেরি কেবল ঝাঁকুনি বা সোয়াইপ সরবরাহ করতে পারে যা বিনিময়যোগ্যভাবে ব্যবহার করা যেতে পারে। একটি সমতল স্ক্রিনে দুটি অঙ্গভঙ্গিকে সত্যই পৃথক করা কঠিন এবং সাধারণভাবে বক্তারা লোকেরা উভয়ই করছেন (শারীরিক পর্দাটি স্যুইপ করছে তবে স্ক্রিনে প্রদর্শিত ইউআই উপাদানটি উড়িয়ে দিচ্ছে)।

আপনার সেরা বিকল্পটি এটি নিজে না করা। সাধারণ অঙ্গভঙ্গিগুলি সনাক্ত করার জন্য ইতিমধ্যে প্রচুর জাভাস্ক্রিপ্ট লাইব্রেরি রয়েছে


0

আমি @ জিভান্সের সমাধানটিকে একটি প্রতিক্রিয়া হুক হিসাবে কাজ করতে পুনরায় কাজ করেছি। ইনপুটটি হ'ল কিছু 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);
};
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.