IPhone और Android पर जावास्क्रिप्ट के माध्यम से एक उंगली कड़ी चोट का पता लगाएं


268

आप कैसे पता लगा सकते हैं कि एक उपयोगकर्ता ने जावास्क्रिप्ट के साथ एक वेब पेज पर किसी दिशा में अपनी उंगली को स्वाइप किया?

मैं सोच रहा था कि क्या एक समाधान है जो आईफोन और एंड्रॉइड फोन दोनों पर वेबसाइटों के लिए काम करेगा।


1
स्वाइप पहचान के लिए, मैं Hammer.js की सिफारिश करूंगा । यह काफी छोटा है, और यह कई इशारों का समर्थन करता है: - स्वाइप - रोटेट - पिंच - प्रेस (लंबी होल्ड) - टैप - पैन
विल ब्रिकनर

एक घटना है: "टचमोव"
क्ले

@Clay करें कि कोई अभी भी सफारी में काम नहीं करता है इसलिए आईफोन नहीं।
जकूजी

जवाबों:


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

Android में परीक्षण किया गया।


1
दिखता शांत और सरल है, किसी भी विचार इस घटनाओं के लिए समर्थन है क्या touchstart, touchmove?
d.raev

1
यह बहुत अच्छी तरह से काम करता है, लेकिन सीधे आंदोलनों का पता लगाने में समस्या है। मैं इस विषय पर एक और उत्तर पोस्ट करूंगा जिसने इसे JQuery (डेस्कटॉप) समाधान के रूप में तय किया। यह इन स्वाइप घटनाओं के माउस संस्करण को भी जोड़ता है और एक संवेदनशीलता विकल्प जोड़ता है।
कोडबीट

1
अरे नहीं। विषय बंद हो गया है इसलिए मेरा उत्तर नहीं जोड़ा जा सकता है!
कोडबीट

3
यह महान काम करता है, लेकिन बाएं / दाएं और ऊपर / नीचे पीछे हैं।
पीटर आइजेंट्राट

4
originalEvent एक JQuery प्रॉपर्टी है। यदि आप JQuery के बिना शुद्ध जावास्क्रिप्ट चलाते हैं तो इसे छोड़ दिया जाना चाहिए। JQuery के बिना चलने पर वर्तमान कोड एक अपवाद उठाता है।
Jan Derk

31

@ 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();

7
यह कोड संभवतः काम नहीं करेगा क्योंकि आपको .bindअपरिभाषित कॉल करने की कोशिश करते समय एक अपवाद मिलेगा क्योंकि आपके handleTouchMoveवास्तव में कुछ भी वापस नहीं आया। जब this.यह पहले से ही वर्तमान संदर्भ के लिए बाध्य है, तो कॉलिंग बाइंड को कॉल करने के लिए बेकार है
nic.skriabin

3
मैंने अभी हटा दिया .bind(this);और इसने इनायत से काम किया। @nicholas_r धन्यवाद
अली Ghanavatian

भाग को तत्व मिलता है अपने आप को मैं सिर्फ दस्तावेज़ में '#' हटाता हूं ।EgetById ('my-element') और यह अच्छा काम करता है। धन्यवाद @Marwelln :)
ब्लू ट्राम

4
आप कड़ी चोट के समाप्त होने तक इंतजार करना चाहते हैं (जिसका अर्थ है के बाद वे onmouseup उनकी अंगुली उठाने या), परिवर्तन touches[0]करने के लिए changedTouches[0]और ईवेंट हैंडलर प्रकार handleTouchMoveके लिएhandleTouchEnd
TetraDev

फोन run()दो बार और आप एक बुरा स्मृति रिसाव मिल
चटाई

20

मैंने कुछ उत्तरों को यहाँ एक स्क्रिप्ट में मर्ज किया है जो 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 पर उपलब्ध है


मैं यहां आया क्योंकि शुद्ध-स्वाइप मेरे लिए मोबाइल पर काम नहीं कर रहा था
स्टेफनबाक

@Stefan याकूब यदि आप पर्याप्त जानकारी के साथ गीथूब रेपो पर एक टिक बढ़ाते हैं तो मुझे इस मुद्दे को फिर से प्रस्तुत करने की अनुमति मिलेगी, मैं इसे
जॉन डोहर्टी

1
धन्यवाद, यह पूरी तरह से काम करता है! मैंने Hammer.js को आपकी लाइब्रेरी से बदल दिया, क्योंकि पूर्व ब्राउज़र ज़ूम के साथ काम नहीं करता है और यह एक गंभीर प्रयोज्य समस्या है। इस पुस्तकालय के साथ ज़ूम ठीक से काम करता है (एंड्रॉइड पर परीक्षण किया गया)
collimarco

15

इससे पहले कि आपने मूसडाउन ईवेंट का पता लगाया है, उसका एक्स, वाई लोकेशन (जो भी प्रासंगिक हो) रिकॉर्ड करें, फिर माउसअप ईवेंट का पता लगाएं, और दो मानों को घटाएं।


28
मेरा मानना ​​है कि यह टचस्टार्ट, टचमूव, टचस्केल और टचडाउन है जो किसी के साथ काम करेगा, न कि मूसडाउन या माउसअप।
Volomike


12

मैंने स्वाइप क्रियाओं को पंजीकृत करने के लिए कई मोबाइल ब्राउज़रों में सबसे विश्वसनीय और संगत होने के लिए @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;                                             
};

पर परीक्षण किया गया:

  • एंड्रॉइड : क्रोम, यूसी ब्राउज़र
  • आईओएस : सफारी, क्रोम, यूसी ब्राउज़र

originalEvent एक JQuery प्रॉपर्टी है। यह शुद्ध जावास्क्रिप्ट में भी मौजूद नहीं है।
Jan Derk

1
इस SO उत्तर के अनुसार , ब्राउज़र द्वारा समर्थित एक टच ईवेंट के माध्यम से उजागर किया जाएगा event.originalEvent। बात event.touchesअब समाप्त हो गई है और परिणाम में है undefined
nashcheez

jQuery का उपयोग करते समय Event.touches का अस्तित्व ही समाप्त हो गया। JQuery के बिना अपना कोड आज़माएं और आपको एक त्रुटि मिलेगी कि evt.originalEvent अपरिभाषित है। JQuery पूरी तरह से ईवेंट को अपने साथ बदल देता है और मूल ब्राउज़र इवेंट को मूल रूप में रखता है। लघु संस्करण: आपका कोड केवल JQuery के साथ काम करता है। यदि आप ओरिजिनल को हटा दें तो यह JQuery के बिना काम करता है।
Jan Derk

1
हाँ, मैंने थोड़ा शोध किया और महसूस किया कि आप सक्षम करने वाली जेकरी की उपलब्धता के बारे में सही थे 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

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

4

अगर कोई भी एंड्रॉइड पर 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;लेकिन आपने मुझे सही दिशा में लगा दिया! धन्यवाद!
फिलिप जी

4

मुझे लगातार टच करने वाले हैंडलर फायरिंग से परेशानी थी जबकि उपयोगकर्ता चारों ओर उंगली खींच रहा था। मुझे नहीं पता कि ऐसा कुछ होने के कारण मैं गलत कर रही हूं या नहीं, लेकिन मैंने इसे टचवेव के साथ चालें जमा करने के लिए फिर से शुरू किया और टचेंड वास्तव में कॉलबैक को आग लगाता है।

मुझे भी इन उदाहरणों की एक बड़ी संख्या की आवश्यकता थी और इसलिए मैंने सक्षम / अक्षम तरीके जोड़े।

और एक दहलीज जहां एक छोटी स्वाइप आग नहीं है। टचस्टार्ट शून्य के काउंटर हर बार।

आप फ्लाई पर 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);
            }
        }
    }
}

क्या यह ES5 या ES6 के लिए है?
1.21 गीगावाट

@gigawatts मुझे याद नहीं है। जो प्रोजेक्ट इस्तेमाल किया गया है, वह ईओएल तक पहले ही पहुंच चुका है और मुझे उस कोड की जरूरत नहीं है। मुझे उस समय शक हुआ जब मैं ईएस 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.');
                    }
});

यह सांत्वना त्रुटियों से बचने में मदद करता है जब आप केवल कॉल करना चाहते हैं चलो "onLeft" विधि कहते हैं।


2

उपयोग दो:

jQuery मोबाइल: ज्यादातर मामलों में काम करते हैं और विशेष रूप से जब आप एप्लीकेसन विकसित कर रहे होते हैं जो अन्य jQuery प्लगइन का उपयोग करता है तो इसके लिए jQuery मोबाइल नियंत्रण का उपयोग करना बेहतर होता है। इसे यहां देखें: https://www.w3schools.com/jquerymobile/jquerymobile_events_touch.asp

हथौड़ा समय ! सबसे अच्छे, हल्के और तेज़ जावास्क्रिप्ट आधारित पुस्तकालय में से एक। इसे यहां देखें: https://hammerjs.github.io/


2

यदि आपको केवल स्वाइप की आवश्यकता है, तो आप केवल उस भाग का उपयोग करना बेहतर समझदार हैं, जिसकी आपको आवश्यकता है। यह किसी भी टच डिवाइस पर काम करना चाहिए।

यह ~ 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

मैं केवल बाएं और दाएं स्वाइप का पता लगाना चाहता था, लेकिन टच इवेंट समाप्त होने पर ही कार्रवाई को ट्रिगर करता हूं, इसलिए मैंने ऐसा करने के लिए @ 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;
}

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


वर्तमान में इस संस्करण का उपयोग कर रहा है। अगर पुनरावृत्ति में स्वाइप किया जाता है तो मैं इसे कई बार फायरिंग से कैसे रोकूंगा? मैं इसे एक फॉर्मक्रॉसिंग फॉर्म के लिए एक चेतन सुविधा के साथ उपयोग करता हूं और जब मैं कई बार स्वाइप करता हूं, तो चीजें थोड़ी खराब हो जाती हैं और मेरे डिव दिखाई क्षेत्र में ओवरलैप होने लगते हैं।
एनएमएएलएम

0

आपके पास एक आसान समय हो सकता है पहले इसे माउस घटनाओं के साथ प्रोटोटाइप में लागू करें।

यहां कई उत्तर दिए गए हैं, जिनमें शीर्ष भी शामिल हैं, उन्हें सावधानी के साथ इस्तेमाल किया जाना चाहिए क्योंकि वे विशेष रूप से बाउंडिंग बॉक्स के आसपास के किनारे मामलों पर विचार नहीं करते हैं।

देख:

आपको किनारे के मामलों और व्यवहारों को पकड़ने के लिए प्रयोग करने की आवश्यकता होगी जैसे कि सूचक समाप्त होने से पहले तत्व के बाहर घूम रहा है।

एक स्वाइप एक बहुत ही बुनियादी इशारा है जो कच्चे घटनाओं और लिखावट की पहचान के बीच मोटे तौर पर बैठकर इंटरफेस पॉइंटर इंटरैक्शन प्रोसेसिंग का एक उच्च स्तर है।

स्वाइप या फ़्लिंग का पता लगाने के लिए कोई सटीक तरीका नहीं है, हालांकि लगभग सभी आम तौर पर दूरी और गति या वेग की सीमा के साथ एक तत्व में गति का पता लगाने के एक बुनियादी सिद्धांत का पालन करते हैं। आप बस यह कह सकते हैं कि यदि किसी निश्चित समय के भीतर स्क्रीन आकार में 65% की गति है, तो यह एक स्वाइप है। ठीक उसी तरह जहां आप रेखा खींचते हैं और आप इसकी गणना कैसे करते हैं यह आपके ऊपर है।

कुछ इसे एक दिशा में गति के दृष्टिकोण से भी देख सकते हैं और तत्व जारी होने पर इसे स्क्रीन से कितनी दूर धकेल दिया गया है। यह चिपचिपा स्वाइप्स के साथ स्पष्ट है जहां तत्व को खींचा जा सकता है और फिर रिलीज पर या तो वापस उछल जाएगा या स्क्रीन से उड़ जाएगा जैसे कि लोचदार टूट गया।

यह संभवतः एक इशारा पुस्तकालय खोजने की कोशिश करने के लिए आदर्श है जिसे आप या तो पोर्ट कर सकते हैं या पुन: उपयोग कर सकते हैं जो आमतौर पर स्थिरता के लिए उपयोग किया जाता है। यहां कई उदाहरण अत्यधिक सरलीकृत हैं, किसी भी दिशा में मामूली स्पर्श के रूप में स्वाइप को पंजीकृत करना।

एंड्रॉइड स्पष्ट पसंद होगा हालांकि विपरीत समस्या है, यह अत्यधिक जटिल है।

कई लोग इस सवाल का गलत मतलब निकाल रहे हैं कि वे किसी भी दिशा में आंदोलन कर रहे हैं। स्वाइप एक व्यापक और अपेक्षाकृत संक्षिप्त गति है जो एक ही दिशा में (हालांकि हो सकता है और कुछ त्वरण गुण हो)। एक फ्लिंग के समान है, हालांकि अपने स्वयं के गति के तहत उचित दूरी पर किसी वस्तु को लापरवाही से चलाने का इरादा रखता है।

दोनों पर्याप्त रूप से समान हैं कि कुछ पुस्तकालय केवल फ़्लिंग या स्वाइप प्रदान कर सकते हैं, जिसका उपयोग पारस्परिक रूप से किया जा सकता है। एक फ्लैट स्क्रीन पर यह वास्तव में दो इशारों को अलग करना मुश्किल है और आम तौर पर बोलने वाले लोग दोनों कर रहे हैं (भौतिक स्क्रीन को स्वाइप करना लेकिन स्क्रीन पर प्रदर्शित यूआई तत्व को फ़्लिप करना)।

आप सबसे अच्छा विकल्प यह है कि आप इसे स्वयं न करें। सरल इशारों का पता लगाने के लिए पहले से ही बड़ी संख्या में जावास्क्रिप्ट लाइब्रेरी हैं


0

मैं एक प्रतिक्रिया हुक के रूप में कार्य करने के लिए @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);
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.