'टचस्टार्ट' और 'क्लिक' घटनाओं को कैसे बांधें लेकिन दोनों का जवाब नहीं?


198

मैं एक मोबाइल वेब साइट पर काम कर रहा हूं जिसमें विभिन्न उपकरणों पर काम करना है। इस समय मुझे सिरदर्द देने वाले ब्लैकबेरी हैं।

हमें दोनों कीबोर्ड क्लिक के साथ-साथ टच इवेंट का भी समर्थन करने की आवश्यकता है।

आदर्श रूप से मैं सिर्फ उपयोग करूंगा:

$thing.click(function(){...})

लेकिन हम जिस मुद्दे पर चल रहे हैं, वह यह है कि इनमें से कुछ ब्लैकबेरी डिवाइसेस में टच के समय से एक क्लिक को ट्रिगर करने में बहुत कष्टप्रद विलंब होता है।

उपाय इसके बजाय टचस्टार्ट का उपयोग करना है:

$thing.bind('touchstart', function(event){...})

लेकिन मैं दोनों घटनाओं को कैसे बांध सकता हूं, लेकिन केवल एक फायरिंग? मुझे अभी भी कीबोर्ड डिवाइस के लिए क्लिक इवेंट की आवश्यकता है, लेकिन निश्चित रूप से, मैं टच डिवाइस का उपयोग कर रहा हूं, तो क्लिक इवेंट फायरिंग नहीं चाहता।

एक बोनस सवाल: क्या ऐसा करने के लिए और इसके अलावा उन ब्राउज़रों को समायोजित करना है जिनके पास टचस्टार्ट इवेंट भी नहीं है? इस पर शोध करने में, ऐसा लगता है कि ब्लैकबेरी OS5 टचस्टार्ट का समर्थन नहीं करता है, इसलिए उस ब्राउज़र के लिए क्लिक घटनाओं पर भी भरोसा करना होगा।

परिशिष्ट:

शायद एक अधिक व्यापक प्रश्न है:

JQuery के साथ, एक ही बाइंडिंग के साथ टच इंटरैक्शन और माउस इंटरैक्शन दोनों को संभालना संभव / अनुशंसित है?

आदर्श रूप से, इसका उत्तर हां है। यदि नहीं, तो मेरे पास कुछ विकल्प हैं:

1) हम डिवाइस की जानकारी प्राप्त करने के लिए WURFL का उपयोग करते हैं ताकि हमारे स्वयं के मैट्रिक्स का निर्माण हो सके। डिवाइस के आधार पर, हम टचस्टार्ट या क्लिक का उपयोग करेंगे।

2) जेएस के माध्यम से ब्राउज़र में स्पर्श समर्थन का पता लगाएं (मुझे उस पर कुछ और शोध करने की आवश्यकता है, लेकिन ऐसा लगता है कि यह संभव है)।

हालांकि, यह अभी भी एक मुद्दा छोड़ देता है: बीओटीएच का समर्थन करने वाले उपकरणों के बारे में क्या। हमारे द्वारा समर्थित कुछ फोन (अर्थात नोकिआस और ब्लैकबैरीज़) में टच स्क्रीन और कीबोर्ड दोनों हैं । तो उस तरह से मुझे मूल प्रश्न पर वापस पूरा घेरा जाता है ... क्या किसी भी तरह से दोनों के लिए अनुमति देने का एक तरीका है?


2
आप टचस्टार्ट और टचएंड के लिए बाध्यकारी हैं और अपने टच लॉजिक के साथ-साथ अपने स्वयं के क्लिक लॉजिक लिख रहे हैं। बिल्ट-इन-क्लिक कॉलबैक जिसमें स्पर्श का ज्ञान नहीं है।
जस्टिन 808

मुझे यकीन नहीं है कि मैं अनुसरण करता हूं, जस्टिन। क्या मेरे पास अभी भी एक टचस्टार्ट और क्लिक इवेंट नहीं है?
डीए।

@DA - नहीं, आप बिल्कुल भी .click () कॉलबैक के लिए बाध्य नहीं होंगे। मैं कुछ sudo कोड में एक उत्तर लिखने की कोशिश करूँगा। मेरे पास वास्तविक कोड लिखने के लिए टच डिवाइस नहीं है :)
जस्टिन808

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

2
उपयोग .bind('touchstart mouseup')करने से इसका समाधान हो जाएगा (नीचे दी गई टिप्पणियों में से एक पर आधारित)
oriadam

जवाबों:


135

अपडेट : jQuery पॉइंटर इवेंट्स पॉलीफ़िल प्रोजेक्ट देखें, जो आपको माउस और टच के बीच चयन करने के बजाय "पॉइंटर" ईवेंट को बांधने की अनुमति देता है।


दोनों को बांधें, लेकिन एक झंडा बनाएं ताकि फ़ंक्शन केवल एक बार प्रति 100ms या तो फायर हो।

var flag = false;
$thing.bind('touchstart click', function(){
  if (!flag) {
    flag = true;
    setTimeout(function(){ flag = false; }, 100);
    // do something
  }

  return false
});

7
हम्म ... यह हैकिंग लगता है, लेकिन यह काम कर सकता है। पकड़ यह है कि इन उपकरणों में से कुछ पर, यह ध्यान देने योग्य अंतराल है ... शायद लगभग एक सेकंड ... जो एक तेज डिवाइस पर दूसरों के लिए कष्टप्रद होगा।
डीए।

15
clickइसे बदलने का उपयोग करने के बजाय mousedown... शायद लंबे समय के बीच का अंतर है mousedownऔर mouseupयह है कि यह कैसे clickनिर्धारित किया जाता है।
मॉटी

7
यह वह उपाय है जिसके साथ मैं गया था। धन्यवाद! मैं क्या करूँ मैं touchendएक वर्ग को लागू करके एक आइटम को ध्वजांकित करता हूं touched। क्लिक इवेंट कहे जाने से पहले यह आग लग जाती है। मैं तब एक क्लिक ईवेंट जोड़ता हूं जो पहले उस वर्ग के अस्तित्व की जांच करता है। अगर यह वहाँ है, तो हम मान लेते हैं कि स्पर्श की गई घटनाओं को निकाल दिया गया है और हम अगले इंटरेक्शन के लिए इसे 'रीसेट' करने के लिए क्लास नाम को हटाने के अलावा कुछ भी नहीं करते हैं। यदि कक्षा नहीं है, तो हम मान लेते हैं कि उन्होंने आइटम पर क्लिक करने के लिए एक कीबोर्ड का उपयोग किया था, और वहां से फ़ंक्शन को ट्रिगर किया।
डीए।

7
आपको इस बात की जानकारी होनी चाहिए कि क्लिक इवेंट पर अधिकांश फोन ब्राउज़र में 300ms विलंब होता है, इसलिए आपको विलंब को कम से कम 300 तक बढ़ाना चाहिए, इस लेख को 300ms देरी के मुद्दे पर देखें । यह मूल रूप से "डबल क्लिक टू जूम" कार्यक्षमता को सक्षम करने के लिए है जो शुरुआती iPhone दिनों में एक बहुत ही महत्वपूर्ण विशेषता थी, जब अधिकांश वेब साइटों को एक बड़ी डेस्कटॉप स्क्रीन पर देखने के लिए डिज़ाइन किया गया था।
खौफ

12
इस बिंदु पर इस प्रश्न को 100k बार देखा गया है। यह एक असाधारण आम उपयोग मामला / समस्या की तरह लगता है। हालाँकि, यह उत्तर और अन्य इस पर और इसी तरह के प्रश्न सभी हैकिंग लगते हैं। Google समाधान, जबकि अधिक से अधिक पूरी तरह से सोचा, लगता है कि केवल एक अधिक मजबूत हैक। क्लिक हैंडलर के रूप में सरल कुछ के लिए, ऐसा लगता है कि समाधान सरल होना चाहिए। क्या इस समस्या का कोई गैर-हैक समाधान नहीं मिला है?
jinglesthula

73

यह वह फिक्स है जो मैं "बनाता" हूं और यह घोस्टक्लिक को बाहर निकालता है और फास्टक्लिक को लागू करता है। अपने दम पर प्रयास करें और हमें बताएं कि क्या यह आपके लिए काम करता है।

$(document).on('touchstart click', '.myBtn', function(event){
        if(event.handled === false) return
        event.stopPropagation();
        event.preventDefault();
        event.handled = true;

        // Do your magic here

});

2
helgatheviking: jsbin.com/ijizat/25 जावास्क्रिप्ट में TouchClick नामक एक फ़ंक्शन है जो उपरोक्त को शामिल करता है।
मैट पार्किंस

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

7
यह काम नहीं करेगा क्योंकि अनाम फ़ंक्शन में 'ईवेंट' पास करने से यह उस फ़ंक्शन के भीतर एक स्थानीय ऑब्जेक्ट बन जाता है, इसलिए हर बार ईवेंट ट्रिगर होने के event.handledबराबर होगा undefined। यहां एक समाधान है: लक्ष्य तत्व में 'संभाला हुआ' ध्वज को उपयोग करके स्वयं सेट करें jQuery.data()
10

3
आपके पास event.stopPropagation();और event.preventDefault();मेरी समझ (और परीक्षण) से इस घटना को केवल एक बार निकाल दिया जा सकता है। तो जांच भी क्यों if(event.handled !== true)? मेरे लिए यह आवश्यक नहीं है या मुझे कुछ याद नहीं है?
nbar

2
event.handledमूल्य के लिए जाँच नहीं की जानी चाहिए true? जहाँ तक मैं बता सकता हूँ यह कभी नहीं है false। यह शुरू होता है undefined, और फिर आप यह बताना चाहते हैं कि क्या यह निर्धारित किया गया है true
एसीजे

49

आप कुछ इस तरह की कोशिश कर सकते हैं:

var clickEventType=((document.ontouchstart!==null)?'click':'touchstart');
$("#mylink").bind(clickEventType, myClickHandler);

5
मुझे लगता है कि इसके साथ समस्या यह है कि उपयोगकर्ता क्या कर रहा है, इसके बजाय यह डिवाइस क्षमताओं का परीक्षण कर रहा है? चुनौती है कि हमें टच डिवाइस का समर्थन करने की आवश्यकता है जिसमें कीबोर्ड भी हैं (इसलिए वे दोनों का उपयोग कर सकते हैं)
डीए।

8
यह एक अच्छा विचार नहीं है - एक टच स्क्रीन और माउस के साथ उपयोगकर्ता के लिए घटना को तोड़ देगा जब माउस का उपयोग करना होगा (टच स्क्रीन वाले लैपटॉप काफी सामान्य हो रहे हैं)।
क्रिस्टियन जे।

1
इससे संबंधित बेहतरीन लेख: hacks.mozilla.org/2013/04/…
ल्यूक मेलिया

विंडोज 8 हमेशा 'टचस्टार्ट' ईवेंट को वायर करेगा यदि इसका उपयोग किया जाता है क्योंकि 'ओनटुचस्टार्ट' इस ओएस पर 'सही' लौटेगा। तो, शायद सबसे अच्छा जवाब नहीं है जब तक कि आपका कोड केवल सच टचस्क्रीन डिवाइस पर नहीं चल रहा होगा, लेकिन फिर अगर ऐसा है, तो आपको चेक की बिल्कुल भी आवश्यकता नहीं है।
नील मुनरो

टच स्क्रीन वाले लैपटॉप पर उपयोगकर्ता क्रोम में इस कोड का उपयोग करके कुछ भी क्लिक नहीं कर पाएंगे (कम से कम क्रोम 46)। IE 11 हालांकि काम करने लगता है।
डेविड शेरेट

42

आमतौर पर यह भी काम करता है:

$('#buttonId').on('touchstart click', function(e){
    e.stopPropagation(); e.preventDefault();
    //your code here

});

8
यदि आप नए jQuery के संस्करणों का उपयोग कर रहे हैं तो @Jonathan गलत है। लाइव को संस्करण 1.7 में पदावनत किया गया।
माइक बारविक ने

मैंने भी प्रयास किया (और मैंने इसे कहीं और पढ़ा - मेरे विचार से नहीं) e.stopPropagation () के साथ; e.preventDefault (); और यह लगभग (मेरे लिए) काम करता है लेकिन मुझे बाद में पता चला कि वास्तव में यह 20 बार भविष्यवाणी के रूप में काम करता है लेकिन 1 बार नहीं, इसलिए यह बुलेटप्रूफ नहीं है। यहाँ देखें: stackoverflow.com/questions/25671053/… उस मुद्दे पर अपनी टिप्पणियों की सराहना करें!
गरवानी

@MikeBarwick क्या आप अपनी टिप्पणी को स्पष्ट कर सकते हैं या एक लिंक दे सकते हैं जो इसे बताता है? पहले ही, आपका बहुत धन्यवाद।
बिलाल बेगुएरदज

22

इवेंट फ़ंक्शन return false;के अंत में बस जोड़ना on("click touchstart")इस समस्या को हल कर सकता है।

$(this).on("click touchstart", function() {
  // Do things
  return false;
});

.On पर jQuery के प्रलेखन से ()

falseईवेंट हैंडलर से लौटने पर स्वचालित रूप से कॉल आएगा event.stopPropagation()और event.preventDefault()falseहैंडलर के लिए शॉर्टहैंड के रूप में एक मूल्य भी पारित किया जा सकता है function(){ return false; }


2
महान काम करता है, दोनों के साथ उपकरणों पर केवल एक बार आग लग जाती है - यह मेरे लिए सबसे कम से कम हैकी समाधान की तरह लगता है
एडम कूपर

मेरे लिए सबसे अच्छा काम किया और वास्तव में समझ में आया क्यों।
अमीर 5000

यह करने के लिए किसी भी downsides? इस तरह के एक सरल समाधान को व्यापक रूप से क्यों नहीं जाना जाता है?
ईएसआर

10

मुझे भी कुछ ऐसा ही करना था। यहाँ एक सरल संस्करण है जो मेरे लिए काम करता है। यदि एक स्पर्श घटना का पता चला है, तो क्लिक बाइंडिंग को हटा दें।

$thing.on('touchstart click', function(event){
  if (event.type == "touchstart")
    $(this).off('click');

  //your code here
});

मेरे मामले में क्लिक इवेंट एक <a>तत्व से जुड़ा हुआ था इसलिए मुझे क्लिक बाइंडिंग को हटाना पड़ा और एक क्लिक ईवेंट को रिवाइंड करना पड़ा जिससे <a>तत्व के लिए डिफ़ॉल्ट क्रिया को रोक दिया गया ।

$thing.on('touchstart click', function(event){
  if (event.type == "touchstart")
    $(this).off('click').on('click', function(e){ e.preventDefault(); });

  //your code here
});

काश कि यह काम होता, लेकिन ऐसा नहीं है। $ (यह) आपको क्या लगता है कि यह इंगित नहीं करता है।
डेव लोअर्रे

8

मैं निम्नलिखित तरीके से सफल हुआ।

बहुत आसान...

$(this).on('touchstart click', function(e){
  e.preventDefault();
  //do your stuff here
});

4
एक क्लिक और एक टचस्टार्ट दोनों को पंजीकृत करने वाले उपकरणों पर दो बार आग नहीं लगेगी?
डीए।

8
क्षमा करें, मुझे पता है। हाँ आप सही हैं एक टच टचस्टार्ट ईवेंट उत्पन्न करेगा और साथ ही ईवेंट पर भी क्लिक करेगा। इसे घोस्ट क्लिक कहते हैं। Google ने इसके लिए एक समाधान लागू किया है। सीधे आगे नहीं हो सकता है लेकिन पूरी तरह से काम करता है। लिंक यहां दिया गया है। code.google.com/mobile/articles/fast_buttons.html#ghost
हसनवी

2
तुच्छ हो सकता है, लेकिन आप eपैरामीटर गायब कर रहे हैंfunction()
ProblemsOfSumit

@ हसनवी यह एक बहुत बड़ा सुधार था लेकिन मैंने बेहतर परिणाम प्राप्त किए ।on
नील

1
धन्यवाद @ नील। हाँ .on का उपयोग करना एक बेहतर विचार है क्योंकि इसे भविष्य के संस्करण में हटाया जा सकता है। मैंने अपने उदाहरण को बाइंड से बदल दिया है।
हसनवी

5

मेरा मानना ​​है कि सबसे अच्छा अभ्यास अब उपयोग करने के लिए है:

$('#object').on('touchend mouseup', function () { });

touchend

स्पर्श बिंदु को स्पर्श सतह से हटाए जाने पर स्पर्शक घटना को निकाल दिया जाता है।

टचेंड ईवेंट किसी भी माउस ईवेंट को ट्रिगर नहीं करेगा ।


mouseup

जब माउस पॉइंटर तत्व के ऊपर होता है, और माउस बटन छोड़ा जाता है, तो माउसअप ईवेंट किसी तत्व को भेजा जाता है। कोई भी HTML तत्व इस घटना को प्राप्त कर सकता है।

माउसअप ईवेंट किसी भी स्पर्श ईवेंट को ट्रिगर नहीं करेगा ।

उदाहरण

$('#click').on('mouseup', function () { alert('Event detected'); });
$('#touch').on('touchend', function () { alert('Event detected'); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 id="click">Click me</h1>
<h1 id="touch">Touch me</h1>


EDIT (2017)

2017 तक, क्रोम के साथ शुरू होने वाले ब्राउज़र और .on("click")क्लिक के अनुरोध पर टैप ईवेंट द्वारा उत्पन्न विलंब को समाप्त करके क्लिक इवेंट को माउस और टच दोनों के लिए अधिक अनुकूल बनाने की दिशा में कदम बढ़ाते हैं।

इससे यह निष्कर्ष निकलता है कि केवल क्लिक इवेंट का उपयोग करने के लिए वापस लौटना आगे बढ़ने वाला सबसे सरल समाधान होगा।

मैंने अभी तक कोई क्रॉस ब्राउज़र परीक्षण नहीं किया है यह देखने के लिए कि क्या यह व्यावहारिक है।


यह मुझे आशाजनक लग रहा था, इसलिए मैंने इसे एक गुच्छा के साथ गड़बड़ कर दिया, लेकिन अंततः मुझे mouseupअप्रत्याशित परिणाम मिले, खासकर जब एक पारंपरिक माउस के बजाय एक ट्रैकपैड का उपयोग कर रहा था।
स्काईबॉन्डर्स

4

आम तौर पर आप डिफ़ॉल्ट स्पर्श और गैर-स्पर्श (क्लिक) एपि को मिक्स नहीं करना चाहते हैं। एक बार जब आप स्पर्श की दुनिया में चले जाते हैं तो केवल स्पर्श संबंधी कार्यों से निपटना आसान हो जाता है। नीचे कुछ छद्म कोड है जो आप चाहते हैं कि वह क्या करेगा।

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

var touchStartTime;
var touchStartLocation;
var touchEndTime;
var touchEndLocation;

$thing.bind('touchstart'), function() {
     var d = new Date();
     touchStartTime = d.getTime();
     touchStartLocation = mouse.location(x,y);
});

$thing.bind('touchend'), function() {
     var d = new Date();
     touchEndTime= d.getTime();
     touchEndLocation= mouse.location(x,y);
     doTouchLogic();
});

function doTouchLogic() {
     var distance = touchEndLocation - touchStartLocation;
     var duration = touchEndTime - touchStartTime;

     if (duration <= 100ms && distance <= 10px) {
          // Person tapped their finger (do click/tap stuff here)
     }
     if (duration > 100ms && distance <= 10px) {
          // Person pressed their finger (not a quick tap)
     }
     if (duration <= 100ms && distance > 10px) {
          // Person flicked their finger
     }
     if (duration > 100ms && distance > 10px) {
          // Person dragged their finger
     }
}

मुझे लगता है कि यह सवाल का सार है: क्या यह भी एक कोड आधार के साथ दोनों मॉडलों की कोशिश करने और समर्थन करने के लिए समझ में आता है। मैं कुछ और परिदृश्यों के साथ अपने प्रश्न को अपडेट करूंगा।
डीए।

1
"आम तौर पर आप डिफ़ॉल्ट स्पर्श और गैर-स्पर्श का मिश्रण नहीं करना चाहते हैं" इसके माध्यम से जाने के बाद, मैं सहमत हूं। समस्या यह है कि वे कीबोर्ड के साथ टच डिवाइस बनाते रहते हैं, जो हमारे लिए सिरदर्द है।
डीए।

मैं इस बात से सहमत हूं कि शुरुआत में अंतिम जेएस निर्णय स्पर्श या स्पर्श नहीं करना बहुत आसान होगा। इससे आसान दुनिया क्या होगी! लेकिन यह उन शापित उपकरणों के बारे में क्या है जो समझदार क्लिक और स्पर्श करते हैं? क्या उनके कारण उन सभी सिरदर्द होने के लायक है? क्या यह भविष्य मैं खुद से पूछ रहा हूं?
गरवानी

मुझे फ़ंक्शंस की एकाधिक परिभाषाएँ होने का विचार पसंद नहीं है। मेरी कंपनी वर्तमान में एक ऐसी परियोजना पर काम कर रही है जहां एक आईपैड को मोबाइल डिवाइस के रूप में विशेष रूप से नियंत्रित नहीं किया गया है और आपको अभी भी टचडेन इवेंट की आवश्यकता है। लेकिन टचेंड सामान्य डेस्कटॉप संस्करणों पर काम नहीं करता है। तो @mottie का समाधान उस परिदृश्य के लिए बिल्कुल ठीक है।
पीट


3

खैर ... ये सभी सुपर कॉम्प्लेक्स हैं।

यदि आपके पास आधुनिकता है, तो यह बिना दिमाग वाला है।

ev = Modernizr.touch ? 'touchstart' : 'click';

$('#menu').on(ev, '[href="#open-menu"]', function(){
  //winning
});

2
क्या आप बता सकते हैं कि क्या करता है? मेरा मानना ​​है कि यह देखने के लिए जांचता है कि क्या डिवाइस स्पर्श का समर्थन करता है और यदि नहीं, तो क्लिक का उपयोग करता है। पकड़ है (या कम से कम था , जब मैंने सवाल लिखा था) यह था कि कुछ डिवाइस दोनों का समर्थन करते हैं। और उन उपकरणों पर, मुझे अभी भी दोनों घटनाओं को संभालने की आवश्यकता है, क्योंकि ट्रिगर स्पर्श या क्लिक से आ सकता है।
डीए।

2
मैं थोड़ा और स्पष्टीकरण की सलाह देता हूं।
हारून हॉल

2

बेहतर रखरखाव के लिए एक और कार्यान्वयन। हालाँकि, यह तकनीक ईवेंट .stopPropagation () भी करेगी। 100ms के लिए क्लिक करने वाले किसी अन्य तत्व पर क्लिक पकड़ा नहीं गया है।

var clickObject = {
    flag: false,
    isAlreadyClicked: function () {
        var wasClicked = clickObject.flag;
        clickObject.flag = true;
        setTimeout(function () { clickObject.flag = false; }, 100);
        return wasClicked;
    }
};

$("#myButton").bind("click touchstart", function (event) {
   if (!clickObject.isAlreadyClicked()) {
      ...
   }
}

2

बस प्रलेखन उद्देश्यों के लिए, यहाँ मैंने डेस्कटॉप पर सबसे तेज़ / सबसे संवेदनशील क्लिक के लिए क्या किया है / मोबाइल समाधान पर टैप करें जो मैं सोच सकता था:

मैंने jQuery के onफ़ंक्शन को एक संशोधित के साथ बदल दिया है, जब भी ब्राउज़र स्पर्श घटनाओं का समर्थन करता है, तो मेरी सभी क्लिक घटनाओं को टचस्टार्ट से बदल दिया।

$.fn.extend({ _on: (function(){ return $.fn.on; })() });
$.fn.extend({
    on: (function(){
        var isTouchSupported = 'ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch;
        return function( types, selector, data, fn, one ) {
            if (typeof types == 'string' && isTouchSupported && !(types.match(/touch/gi))) types = types.replace(/click/gi, 'touchstart');
            return this._on( types, selector, data, fn);
        };
    }()),
});

उपयोग पहले की तरह ही सटीक होगा, जैसे:

$('#my-button').on('click', function(){ /* ... */ });

लेकिन यह उपलब्ध होने पर टचस्टार्ट का उपयोग करेगा, जब नहीं क्लिक करें। किसी भी तरह की देरी की जरूरत नहीं: डी


1
इसके साथ पकड़ ऐसी डिवाइस होगी जो बीओटीएच टच और कीबोर्ड का समर्थन करती है जहां आपको यह सुनिश्चित करने की आवश्यकता है कि आप दोनों इंटरैक्शन को समायोजित कर रहे हैं।
डीए।

अच्छा अवलोकन @डीए। यदि आपने इसके साथ संयोजन में किसी भी टच इवेंट का उपयोग नहीं कर रहे हैं, तो मैंने केवल क्लिक इवेंट को बदलने के लिए एक चेक जोड़ा। स्टिल हर प्रोजेक्ट के लिए एक समाधान नहीं होगा, लेकिन मुझे यकीन है कि कई लोगों के लिए एक अच्छा फिट होगा।
गर्सन गेलर्ट

2

मैं सिर्फ यह याद करने के लिए आया ontouchstartथा कि क्या कभी ट्रिगर किया गया था। इस मामले में हम एक ऐसे उपकरण पर हैं जो इसका समर्थन करता है और onclickघटना को अनदेखा करना चाहता है । चूंकि मुझे पहलेontouchstart हमेशा ट्रिगर किया जाना चाहिए , मैं इसका उपयोग कर रहा हूं: onclick

<script> touchAvailable = false; </script>
<button ontouchstart="touchAvailable=true; myFunction();" onclick="if(!touchAvailable) myFunction();">Button</button>


1
चूंकि उपयोगकर्ता एक ही पृष्ठ की यात्रा के दौरान स्पर्श और माउस का उपयोग कर सकते हैं, इसलिए इस स्निपेट के साथ समस्या यह है कि यह प्रति घटना के बजाय एक बार टचअवलेप ध्वज को पंजीकृत करता है। से jQuery प्लगइन stackoverflow.com/a/26145343/328272 अपने कोड के रूप में ही है, लेकिन एक माउस घटना के लिए बता सकते हैं कि यह स्पर्श या माउस की एक घटना के आधार पर से शुरू हो रहा था। इतना ही नहीं। पर क्लिक करें, लेकिन यह भी माउसलेयर पर जो सेकंड (या मिनट) ट्रिगर किया जा सकता है माउस के बाद (फ्लाईआउट मेनू के लिए आदर्श है कि माउस इशारों के साथ माउसओवर पर विस्तार करना चाहिए या स्पर्श का उपयोग करते समय क्लिक करें)।
lmeurs

2

आप इस तरह की कोशिश कर सकते हैं:

var clickEvent = (('ontouchstart' in document.documentElement)?'touchstart':'click');
$("#mylink").on(clickEvent, myClickHandler);

स्पर्श और माउस का समर्थन करने वाले उपकरणों के बारे में क्या है
Walle Cyril

2

मेरे मामले में यह पूरी तरह से काम करता है:

jQuery(document).on('mouseup keydown touchend', function (event) {
var eventType = event.type;
if (eventType == 'touchend') {
    jQuery(this).off('mouseup');
}
});

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


1

यह मेरे लिए काम करता है, मोबाइल दोनों को सुनता है, इसलिए एक को रोकें, जो कि स्पर्श घटना है। डेस्कटॉप केवल माउस को सुनें।

 $btnUp.bind('touchstart mousedown',function(e){
     e.preventDefault();

     if (e.type === 'touchstart') {
         return;
     }

     var val = _step( _options.arrowStep );
               _evt('Button', [val, true]);
  });

1

मेरे लिए मोटी द्वारा दिए गए सर्वश्रेष्ठ उत्तर के लिए होने के नाते, मैं बस उनके कोड को अधिक पुन: प्रयोज्य करने की कोशिश कर रहा हूं, इसलिए यह मेरा समर्थन है:

bindBtn ("#loginbutton",loginAction);

function bindBtn(element,action){

var flag = false;
$(element).bind('touchstart click', function(e) {
    e.preventDefault();
    if (!flag) {
        flag = true;
        setTimeout(function() {
            flag = false;
        }, 100);
        // do something
        action();
    }
    return false;
});

0

मैं एक एंड्रॉइड / आईपैड वेब ऐप पर भी काम कर रहा हूं, और ऐसा लगता है कि यदि केवल "टचमवेट" का उपयोग "घटकों को स्थानांतरित करने के लिए" (कोई ज़रूरत नहीं है तो टचस्टार्ट)। टचस्टार्ट को अक्षम करके, आप .click () का उपयोग कर सकते हैं; jQuery से। यह वास्तव में काम कर रहा है क्योंकि इसे टचस्टार्ट द्वारा अधिभारित नहीं किया गया है।

अंत में, आप बिनब कर सकते हैं। ("टचस्टार्ट", फ़ंक्शन (ई) {e.stopPropation ();}); टचस्टार्ट ईवेंट को प्रचारित करने के लिए कहने के लिए, लिविंग रूम को क्लिक करने के लिए () ट्रिगर करने के लिए।

इसने मेरे लिए काम किया।


आप कैसे निष्क्रिय करेंगे touchstart?
punkrockbuddyholly

मेरा मानना ​​है कि आप कुछ ऐसा कर सकते हैं: jQuery ("# ​​my_element")। ('टचस्टार्ट', फंक्शन (e) {e.preventDefault ()});
21

0

इस मुद्दे को हल करने की कोशिश करते समय कई बातों पर विचार करना चाहिए। अधिकांश समाधान या तो स्क्रॉलिंग को तोड़ देते हैं या भूत क्लिक की घटनाओं को ठीक से नहीं संभालते हैं।

पूर्ण समाधान के लिए https://developers.google.com/mobile/articles/fast_buttons देखें

नायब: आप प्रति-तत्व के आधार पर भूत क्लिक की घटनाओं को संभाल नहीं सकते। विलंबित क्लिक को स्क्रीन स्थान से निकाल दिया जाता है, इसलिए यदि आपके स्पर्श ईवेंट पृष्ठ को किसी तरह से संशोधित करते हैं, तो क्लिक इवेंट को पृष्ठ के नए संस्करण में भेजा जाएगा।


0

यह घटनाओं को असाइन करने 'touchstart mousedown'या उपयोग 'touchend mouseup'करने के अवांछित दुष्प्रभावों से बचने के लिए प्रभावी हो सकता है click


0

इस तथ्य का लाभ उठाते हुए कि एक क्लिक हमेशा एक स्पर्श घटना का पालन करेगी , यहां मैंने टाइमआउट या वैश्विक झंडे का उपयोग किए बिना "भूत क्लिक" से छुटकारा पाने के लिए किया था।

$('#buttonId').on('touchstart click', function(event){
    if ($(this).data("already")) {
        $(this).data("already", false);
        return false;
    } else if (event.type == "touchstart") {
        $(this).data("already", true);
    }
    //your code here
});

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


0

JQuery इवेंट API का उपयोग क्यों नहीं किया जाता है?

http://learn.jquery.com/events/event-extensions/

मैंने इस सरल घटना का सफलता के साथ उपयोग किया है। यह साफ सुथरा, नाम बदलने योग्य और लचीले होने के लिए पर्याप्त है।

var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
var eventType = isMobile ? "touchstart" : "click";

jQuery.event.special.touchclick = {
  bindType: eventType,
  delegateType: eventType
};

1
यह उपयोगकर्ता एजेंट सूँघने पर सुविधा का पता लगाने का उपयोग करने के लिए अनुशंसित है।
jinglesthula

पकड़ ऐसे उपकरण हैं जो स्पर्श और क्लिक दोनों का समर्थन करते हैं।
डीए।

0

यदि आप jQuery का उपयोग कर रहे हैं तो निम्नलिखित मेरे लिए बहुत अच्छा काम कर रहा है:

var callback; // Initialize this to the function which needs to be called

$(target).on("click touchstart", selector, (function (func){
    var timer = 0;
    return function(e){
        if ($.now() - timer < 500) return false;
        timer = $.now();
        func(e);
    }
})(callback));

अन्य समाधान भी अच्छे हैं लेकिन मैं एक लूप में कई ईवेंट्स को बाइंड कर रहा था और एक उपयुक्त क्लोजर बनाने के लिए सेल्फ कॉलिंग फ़ंक्शन की आवश्यकता थी। इसके अलावा, मैं बाध्यकारी को निष्क्रिय नहीं करना चाहता था क्योंकि मैं चाहता था कि यह अगले क्लिक / टचस्टार्ट पर इनवोक-सक्षम हो।

ऐसी ही स्थिति में किसी की मदद कर सकते हैं!


0

सरल सुविधाओं के लिए, बस स्पर्श पहचानें या क्लिक करें मैं निम्नलिखित कोड का उपयोग करता हूं:

var element = $("#element");

element.click(function(e)
{
  if(e.target.ontouchstart !== undefined)
  {
    console.log( "touch" );
    return;
  }
  console.log( "no touch" );
});

यदि टचस्टार्ट ईवेंट को परिभाषित किया गया है और "नहीं" तो "टच" वापस आ जाएगा। जैसे मैंने कहा कि यह केवल क्लिक / टैप घटनाओं के लिए एक सरल तरीका है।


0

मैं यह कोशिश कर रहा हूं और अब तक यह काम कर रहा है (लेकिन मैं केवल एंड्रॉइड / फोनगैप पर कैविट एम्प्टर हूं)

  function filterEvent( ob, ev ) {
      if (ev.type == "touchstart") {
          ob.off('click').on('click', function(e){ e.preventDefault(); });
      }
  }
  $('#keypad').on('touchstart click', '.number, .dot', function(event) {
      filterEvent( $('#keypad'), event );
      console.log( event.type );  // debugging only
           ... finish handling touch events...
  }

मुझे यह तथ्य पसंद नहीं है कि मैं हर स्पर्श पर हैंडलर को फिर से बांध रहा हूं, लेकिन सभी चीजों को माना जाता है जो बहुत बार (कंप्यूटर के समय में) नहीं होती हैं!

मेरे पास '#keypad' के लिए एक हैंडलर का एक TON है, इसलिए एक साधारण फ़ंक्शन है जो मुझे बहुत अधिक कोड के बिना समस्या से निपटने देता है इसलिए मैं इस तरह से गया।



0

EDIT: मेरा पूर्व उत्तर (इस थ्रेड में उत्तरों के आधार पर) मेरे लिए जाने का तरीका नहीं था। मैं माउस दर्ज या स्पर्श क्लिक पर विस्तार करने और माउस अवकाश या किसी अन्य स्पर्श क्लिक पर संक्षिप्त करना चाहता था। चूंकि माउस की घटनाओं को सामान्य रूप से स्पर्श घटनाओं के बाद निकाल दिया जाता है, इसलिए इवेंट श्रोताओं को लिखने के लिए यह एक तरह से मुश्किल था जो एक ही समय में टचस्क्रीन और माउस इनपुट दोनों का समर्थन करते हैं।

jQuery प्लगइन: टच या माउस

मैंने " टच ऑर माउस " (897 बाइट्स मिनिफाइज्ड) नामक एक jQuery प्लगइन लिखना समाप्त किया, जो यह पता लगा सकता है कि क्या कोई घटना टचस्क्रीन या माउस (टच सपोर्ट के लिए परीक्षण के बिना!) द्वारा लागू की गई थी। यह एक ही समय में टचस्क्रीन और माउस दोनों के समर्थन को सक्षम करता है और उनकी घटनाओं को पूरी तरह से अलग करता है।

इस तरह ओपी क्लिकों को छूने के लिए touchstartया touchendजल्दी से जवाब देने के clickलिए और केवल माउस द्वारा लगाए गए क्लिक के लिए उपयोग कर सकता है ।

प्रदर्शन

पहले एक यानी बनाना है। शरीर तत्व ट्रैक स्पर्श की घटनाओं:

$(document.body).touchOrMouse('init');

माउस हमारे तत्वों को डिफ़ॉल्ट तरीके से बाध्य करता है और कॉल करके $body.touchOrMouse('get', e)हम पता लगा सकते हैं कि क्या घटना को टचस्क्रीन या माउस द्वारा लागू किया गया था।

$('.link').click(function(e) {
  var touchOrMouse = $(document.body).touchOrMouse('get', e);

  if (touchOrMouse === 'touch') {
    // Handle touch click.
  }
  else if (touchOrMouse === 'mouse') {
    // Handle mouse click.
  }
}

Http://jsfiddle.net/lmeurs/uo4069nh पर प्लग इन देखें ।

व्याख्या

  1. इस प्लगइन को यानी पर बुलाया जाना चाहिए। ट्रैक touchstartऔर touchendईवेंट्स के लिए बॉडी एलिमेंट , इस तरह से touchendईवेंट को ट्रिगर एलिमेंट (यानी एक लिंक या बटन) पर फायर नहीं करना पड़ता है। इन दो स्पर्श घटनाओं के बीच यह प्लगइन किसी भी माउस घटना को स्पर्श द्वारा लागू करने के लिए मानता है।
  2. माउस ईवेंट्स को केवल touchendतब ही निकाल दिया जाता है , जब माउस ईवेंट को ghostEventDelay(विकल्प, डिफ़ॉल्ट रूप से 1000ms) के भीतर निकाल दिया touchendजाता है, यह प्लगइन माउस ईवेंट को स्पर्श द्वारा लागू करने के लिए मानता है।
  3. टचस्क्रीन का उपयोग करते हुए एक तत्व पर क्लिक करने पर, तत्व :activeराज्य को प्राप्त करता है। mouseleaveके बाद तत्व यानी द्वारा इस राज्य खो देता है घटना केवल निकाल दिया जाता है। दूसरे तत्व पर क्लिक करना। चूँकि, इस mouseenterघटना को निकाल दिए जाने के बाद कुछ सेकंड (या मिनट!) हो सकता है , यह प्लगइन किसी तत्व की अंतिम mouseenterघटना पर नज़र रखता है : यदि अंतिम mouseenterघटना को स्पर्श द्वारा लागू किया गया था, तो निम्न mouseleaveघटना को स्पर्श द्वारा भी लागू माना जाता है।

0

यहाँ यह करने के लिए एक सरल तरीका है:

// A very simple fast click implementation
$thing.on('click touchstart', function(e) {
  if (!$(document).data('trigger')) $(document).data('trigger', e.type);
  if (e.type===$(document).data('trigger')) {
    // Do your stuff here
  }
});

आप मूल रूप से jQuery के डेटा ऑब्जेक्ट में 'ट्रिगर' प्रॉपर्टी को ट्रिगर होने वाले पहले ईवेंट प्रकार को सेव करते हैं, जो रूट डॉक्यूमेंट से जुड़ा होता है, और केवल तभी निष्पादित होता है जब ईवेंट प्रकार 'ट्रिगर' में वैल्यू के बराबर होता है। स्पर्श उपकरणों पर, ईवेंट श्रृंखला संभवतः 'टचस्टार्ट' और उसके बाद 'क्लिक' होगी; हालाँकि, 'क्लिक' हैंडलर निष्पादित नहीं किया जाएगा क्योंकि "क्लिक" "ट्रिगर" ("टचस्टार्ट") में सहेजे गए प्रारंभिक ईवेंट प्रकार से मेल नहीं खाता है।

धारणा, और मुझे विश्वास है कि यह एक सुरक्षित है, यह है कि आपका स्मार्टफोन एक टच डिवाइस से बदलकर माउस डिवाइस में नहीं आएगा या फिर नल कभी पंजीकृत नहीं होगा क्योंकि 'ट्रिगर' ईवेंट प्रकार केवल एक बार ही सहेजा जाता है पृष्ठ लोड और "क्लिक" कभी भी "टचस्टार्ट" से मेल नहीं खाता।

यहाँ एक कोडपेन है, जिसे आप एक टच डिवाइस पर बटन पर टैप करने की कोशिश कर सकते हैं - कोई क्लिक देरी नहीं होनी चाहिए): http://codepen.io/thdoan/pen/xVVrOZ

मैंने इसे एक साधारण jQuery प्लगइन के रूप में भी लागू किया जो चयनकर्ता स्ट्रिंग को पार करके jQuery के वंशजों का समर्थन करता है:

// A very simple fast click plugin
// Syntax: .fastClick([selector,] handler)
$.fn.fastClick = function(arg1, arg2) {
  var selector, handler;
  switch (typeof arg1) {
    case 'function':
      selector = null;
      handler = arg1;
      break;
    case 'string':
      selector = arg1;
      if (typeof arg2==='function') handler = arg2;
      else return;
      break;
    default:
      return;
  }
  this.on('click touchstart', selector, function(e) {
    if (!$(document).data('trigger')) $(document).data('trigger', e.type);
    if (e.type===$(document).data('trigger')) handler.apply(this, arguments);
  });
};

कोडपेन: http://codepen.io/thdoan/pen/GZrBdo/


आपने केवल एक चर का उपयोग करने के बजाय दस्तावेज़ पर डेटा संपत्ति का उपयोग क्यों किया?
राफेल श्विकर्ट

@RaphaelSchweikert शायद बस आदत से बाहर है। कोई सही या गलत तरीका नहीं है, लेकिन मैं $.data()उन डेटा को संग्रहीत करने के लिए उपयोग करना पसंद करता हूं, जिन्हें कई कार्यों द्वारा एक्सेस किया जा सकता है जो अभी तक वैश्विक दायरे में नहीं हैं। एक प्लस यह है कि जब से मैं इसे एक तत्व में संग्रहीत कर रहा हूं यह स्वाभाविक रूप से मुझे अधिक संदर्भ प्रदान करता है।
थुडू

0

सबसे अच्छी विधि मुझे मिली है कि स्पर्श घटना लिखना है और उस घटना को सामान्य रूप से सामान्य रूप से क्लिक करने की घटना कहते हैं। इस तरह से आपके पास सभी सामान्य क्लिक ईवेंट हैं और फिर आपको सभी टच इवेंट्स के लिए सिर्फ एक ईवेंट हैंडलर जोड़ने की आवश्यकता है। प्रत्येक नोड के लिए आप स्पर्श करने योग्य बनाना चाहते हैं, बस "हैंडबल" वर्ग को स्पर्श हैंडलर को आमंत्रित करने के लिए इसमें जोड़ें। Jquery के साथ यह एक वास्तविक स्पर्श घटना को सुनिश्चित करने के लिए कुछ तर्क के साथ काम करता है और एक झूठी सकारात्मक नहीं है।

$("body").on("touchstart", ".touchable", function() { //make touchable  items fire like a click event
var d1 = new Date();
var n1 = d1.getTime();
setTimeout(function() {
    $(".touchable").on("touchend", function(event) {
        var d2 = new Date();
        var n2 = d2.getTime();
        if (n2 - n1 <= 300) {
            $(event.target).trigger("click"); //dont do the action here just call real click handler
        }
    });
}, 50)}).on("click", "#myelement", function() {
//all the behavior i originally wanted
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.