2010-05-23 17 views
34

का उपयोग कर इंटरैक्टिव डोम तत्वों के साथ एक ही पृष्ठ जावास्क्रिप्ट एप्लिकेशन करने में मैंने पाया कि "mouseover-mousemove-mousedown-mouseup-click" अनुक्रम के बाद एक गुच्छा में सभी होता है घटनाओं का अनुक्रम "touchstart-touchmove-touchend"।रोकथाम माउस यंत्रानुकरण घटनाओं (यानी क्लिक करें) मोबाइल सफारी/iPhone में स्पर्श घटनाओं से जावास्क्रिप्ट

मैं यह भी पाया है कि यह touchstart घटना के दौरान एक "event.preventDefault()" करके ऐसा होने से "mouse*-click" घटनाओं को रोकने के लिए संभव है, लेकिन केवल फिर, और नहीं touchmove और touchend दौरान। यह एक अजीब डिज़ाइन है, क्योंकि touchstart के दौरान जानना संभव नहीं है, फिर भी उपयोगकर्ता ड्रैग या स्वाइप करने का इरादा रखता है या आइटम पर टैप/क्लिक करता है।

मैंने किसी टाइमस्टैम्प से कहीं भी "ignore_next_click" झंडा सेट अप करना समाप्त कर दिया, लेकिन यह स्पष्ट रूप से बहुत साफ नहीं है।

क्या कोई इसे करने का बेहतर तरीका जानता है, या क्या हम कुछ खो रहे हैं?

ध्यान दें कि जबकि एक "क्लिक" एक "touchstart-touchend" अनुक्रम के रूप में पहचाना जा सकता है (यानी कोई "touchmove"), इस तरह के कीबोर्ड इनपुट फोकस के रूप में कुछ बातें, कि केवल एक उचित click घटना के दौरान हो सकता है।

+0

मैं iPad सफारी स्पर्श इवेंट भी में दिलचस्पी के रूप में Firefox पर आवश्यक है, लेकिन यह मेरे लिए स्पष्ट क्या विशिष्ट समस्या को हल करने की कोशिश कर रहे है। यदि आप अभी भी इस मुद्दे पर काम कर रहे हैं, या इसे हल किया है, तो विस्तृत करने की देखभाल करें? – Tim

+0

मैं ड्रैग-एंड-ड्रॉप जैसी कुछ घटनाओं को संभालने में सक्षम होना चाहता हूं, और "क्लिक" ईवेंट को संभालने में भी सक्षम हूं। मुझे "क्लिक" ईवेंट को उचित "क्लिक" ईवेंट (टचस्टार्ट/टचचेन्ड के बजाए) के रूप में संभालना होगा क्योंकि कुछ चीजें, जैसे कुंजीपटल इनपुट फोकस * केवल * एक क्लिक इवेंट हैंडलर में सक्रिय हो सकता है। –

+0

यह समस्या बेहद परेशान है और एंड्रॉइड को भी प्रभावित करती है। –

उत्तर

4

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

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

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

function touchHandler(event) { 
    var shouldIgnore = event.target != null 
      && (event.target.tagName.toLowerCase() == "input" || event.target.tagName.toLowerCase() == "textarea"); 

    if(!shouldIgnore) e.preventDefault(); 
} 
+0

मैं आईओएस 5 और एंड्रॉइड 2.2.1 दोनों पर इस समाधान का परीक्षण कर रहा हूं, और समस्या यह है कि अगर मैं 'टचस्टार्ट 'पर डीफॉल्ट को रोकता हूं, तो' क्लिक' आग नहीं होती है, लेकिन मैं पृष्ठ को स्क्रॉल करने में असमर्थ हूं। अगर मैं 'टचेंड' पर डीफॉल्ट को रोकता हूं तो यह आईओएस पर मुफ्त काम करता है (केवल तभी टैप छोटा है) लेकिन एंड्रॉइड पर 'क्लिक' को फायर करता है। क्या आपने यह वही समस्या देखी है? इसे यहां परीक्षण करें: http://jsfiddle.net/3TBVc/ –

+0

हाँ, मैंने इस समस्या में भाग लिया है (कई तरीकों से प्रकट)। यह आईओएस <-> एंड्रॉइड क्रॉस-प्लेटफार्म में बड़ी पीड़ा में से एक प्रतीत होता है। इसमें कुछ बदलाव होता है, लेकिन सही चीजों को रद्द करके आप आमतौर पर वांछित परिणाम प्राप्त कर सकते हैं। http://jsfiddle.net/3TBVc/9/ एंड्रॉइड पर मेरे लिए ठीक काम करने लगता है। इनपुट फ़ील्ड कुछ 'ड्रैग' ईवेंट (एंड्रॉइड पर) खा सकते हैं, लेकिन इसकी कार्यात्मक। –

+0

यह अभी भी मेरे एंड्रॉइड डिवाइस (और पहले बटन के लिए आईफोन पर) पर घटनाओं को फायरिंग कर रहा है। –

2

मैं एक समाधान अपने आप को कर दिया है, के बाद से मैं नहीं मिला है एक पर्याप्त समाधान कहीं और:

var isTouch = ('ontouchstart' in window); 

    function kill(type){ 
    window.document.body.addEventListener(type, function(e){ 
     e.preventDefault(); 
     e.stopPropagation(); 
     return false; 
    }, true); 
    } 

    if(isTouch){ 
    kill('mousedown'); 
    kill('mouseup'); 
    kill('click'); 
    kill('mousemove'); 
    } 

isTouch की जांच माउस-इनपुट उपकरणों पर सामान्य रूप से काम करने देती है लेकिन सफारी/आईओएस पर नकली घटनाओं को मार देती है। यह चाल useCapture = true को addEventListener पर कॉल में उपयोग करने के लिए है ताकि हम पूरे वेब ऐप में कोड को हैक किए बिना पृष्ठ में सभी माउस ईवेंट को स्कूप कर सकें। समारोह यहां के लिये दस्तावेज देखें: https://developer.mozilla.org/en-US/docs/DOM/EventTarget.addEventListener?redirectlocale=en-US&redirectslug=DOM%2Felement.addEventListener

संपादित करें:

अब जब कि इस मुद्दे से निपटने के लिए पुस्तकालयों में बेहतर हैं, तो आप सिर्फ FastClick की तरह कुछ एक विकल्प (https://github.com/ftlabs/fastclick) के रूप में उपयोग कर सकते हैं।

+4

यह एक अच्छा समाधान है जब आप जानते हैं कि डिवाइस या तो स्पर्श या माउस इनपुट हैं। लेकिन जब आपके पास विंडोज 8 लैपटॉप/टैबलेट की तरह कुछ है, तो आपको कुछ और करने की आवश्यकता होगी। – psayre23

+0

इसका हमारा समाधान दोनों क्लिक और टचस्टार्ट/स्टॉप/मूव इवेंट दोनों को सुनना था और 'ऑनटचस्टार्ट' अनुपलब्ध होने पर केवल क्लिक ईवेंट को पंजीकृत करना था। मोबाइल सफारी दोनों स्पर्श और घटनाओं पर क्लिक करते हैं, लेकिन यह विधि केवल उस मामले में स्पर्श ईवेंट पंजीकृत करती है। इसके अलावा, हम एक मूसोम घटना की उपेक्षा के साथ ठीक थे। –

+1

वोट दिया गया क्योंकि सवाल स्पर्श घटनाओं को उपलब्ध होने पर माउस ईवेंट को पूरी तरह से अक्षम नहीं करना था ... – iRaS

0

Creating Fast Buttons for Mobile Web Applications समस्या का समाधान है।

यह भी सावधान रहें कि IE10 preventDefault() का उपयोग करते समय mSPointerDown ईवेंट के बाद भूत/सिंथेटिक/नकली माउस ईवेंट को रोक नहीं है, इसलिए एक वास्तविक क्रॉस-ब्राउज़र समाधान कठिन है।

2

आप उपकरणों जो दोनों माउस और स्पर्श का समर्थन समर्थन करने के लिए है, तो एक और समाधान एक पर कब्जा घटना श्रोता जो सभी माउस की घटनाओं जो स्पर्श घटना के बाद एक देरी के भीतर या तो

  • होते हैं बंद हो जाता है का उपयोग करना है
  • स्पर्श घटना
  • एक ही लक्ष्य तत्व पर स्पर्श EV के स्पर्श घटना

जानकारी (समय, स्थिति या लक्ष्य तत्व) के रूप में के रूप में एक ही स्थान पर एंट एक और कैप्चर इवेंट श्रोता में दर्ज किया जा सकता है।

0

विंडो में अपने माउस-केवल कोड को लपेटना .मैट्समेडिया फ़ंक्शन मुझे सबसे साफ तरीका है।

if (window.matchMedia('(hover: hover), (any-hover: hover), (-moz-touch-enabled: 0)').matches) { 
    el.addEventListener('mouseover', ev => { 
     // mouse handler, no simulated hover 
    } 
} 

यह अनुरूपित होवर को रोकने के लिए काम करता है लेकिन यह भी अनुरूपित क्लिक को रोक देगा।

नोट: -moz-स्पर्श-सक्षम हिस्सा संस्करण 58.

संबंधित मुद्दे