2011-12-18 6 views
9

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

  • क्षण भर के एक नारंगी सीमा पता चलता है और पूरी स्क्रीन पर हाइलाइट करें, और
  • मुझे गलत घटनाएं भेजता है।

नारंगी सीमा सिर्फ एक ही मूल समस्या के संबंधित लक्षण प्रतीत हो रहा है, तो मैं इसके बारे में बहुत चिंतित नहीं हूँ - यह वास्तव में बताने के लिए जब ब्राउज़र बातें पंगा लेना है सक्षम होने के लिए सुविधाजनक है। मैं वास्तव में क्या जानना चाहता हूं, मैं लगातार दो त्वरित नल के लिए सही स्पर्श घटना कैसे प्राप्त कर सकता हूं? मेरा मानना ​​है कि जब उस समस्या को हल किया जाता है, तो नारंगी सीमा भी चली जाएगी।

अब तक किए गए सभी दर्दनाक विवरण क्या हैं।

Here's a page that shows the problem और प्राप्त होने वाली प्रत्येक घटना के विवरण और समय के बारे में बहुत सारी नैदानिक ​​जानकारी प्रदर्शित करता है। यदि आप नीले आयताकार के अंदर टैप करते हैं, तो आप नारंगी फ्लैश/बुरी घटनाओं को प्राप्त करना सुनिश्चित कर लें, फिर जल्दी से काले आयताकार के अंदर टैप करें।

मेरा jQuery कोड सुंदर मानक है। log फ़ंक्शन का कार्यान्वयन महत्वपूर्ण नहीं है; समस्या यह है कि ब्राउजर इसे कॉल नहीं करता है जब इसे करना चाहिए। घटना मैं शुरू में वर्णित पर

el = $('#battle'); 
el.on('touchstart', function(event) { 
    log(event); 
    return event.preventDefault(); 
}); 
el.on('touchend', function(event) { 
    return log(event); 
}); 
el.on('touchcancel', function(event) { 
    return log(event); 
}); 
el.mousedown(function(event) { 
    log(event); 
    return event.preventDefault(); 
}); 
return el.mouseup(function(event) { 
    return log(event); 
}); 

अधिक विवरण:

ऑरेंज सीमा और आकर्षण: यह वही नारंगी सीमा है और प्रकाश डाला है कि ब्राउज़र जब आप इसे क्लिक करें हाइपरलिंक चारों ओर खींचता है। लेकिन पृष्ठ पर कोई हाइपरलिंक्स नहीं है, और ब्राउजर पूरे स्क्रीन के चारों ओर इस नारंगी सीमा को खींचता है - या अधिक विशेष रूप से, बाहरी <div id="battle"> के आस-पास जो मैं jQuery के माध्यम से ईवेंट को हुक कर रहा हूं।

गलत घटनाओं: मेरी touchstart ईवेंट हैंडलर में, मैं event.preventDefault() फोन कर रहा हूँ,, स्क्रॉल करने के लिए नहीं ब्राउज़र को बताने के लिए, माउस घटनाओं के संश्लेषण के लिए नहीं आदि इसलिए, मैं केवल touchstart और touchend घटनाओं प्राप्त करने की उम्मीद। और मैं करता हूं, पहली टैप के लिए। लेकिन दूसरे टैप के लिए touchstart/touchend के बजाय, मुझे दूसरी टैप के लिए टच इवेंट्स, संश्लेषित माउस इवेंट्स और कभी-कभी touchcancel के संयोजनों की संख्या, या पहले टैप के लिए भी दोहराई गई घटनाएं मिलती हैं। नीचे दिए गए विवरण। (~ 200 मि.से से कम)

  • पहले नल कम होना चाहिए:

    यह व्यवहार भी बहुत ही विशेष परिस्थितियों में होता है।

  • दूसरी टैप उसके तुरंत बाद आनी चाहिए (पहले टैप के touchstart के बाद ~ 450ms से कम)।
  • दूसरा टैप पहले टैप से कम से कम 150 पिक्सेल दूर होना चाहिए (पहले टैप के touchstart के निर्देशांक से विकर्ण के साथ मापा गया)।
  • यदि मैं अपना कोड हटा देता हूं जो mousedown और mouseup को हुक करता है, तो नारंगी आयताकार अब प्रकट नहीं होते हैं।हालांकि, स्पर्श घटनाओं को कभी-कभी अभी भी खराब किया जाता है।

जहां तक ​​मुझे घटनाओं से गड़बड़ होने का मतलब है, वही है जो मैं देखता हूं। जब मैं "1:" लिखता हूं, इसका मतलब है कि घटनाएं पहले टैप के निर्देशांक के लिए हैं; "2:" का मतलब दूसरे टैप के निर्देशांक हैं। मैंने देखा की घटनाओं के निम्नलिखित पैटर्न (प्रतिशत से संकेत मिलता है कि कितनी बार हर एक 100 परीक्षणों के बाद आया था):

  • (50%) 1: touchstart 1: touchend 1: mousedown 1: mouseup (कम देरी) 2: mousedown 2: mouseup
  • (35%) 1: touchstart 1: touchend 2: touchstart 1: mousedown 1: mouseup 2: touchend
  • (10%) 1: touchstart 1: touchend 2: touchstart 1: mousedown 1: mouseup 2: स्पर्श करके रद्द (कम देरी) 2: mousedown 2: mouseup
  • (3%) 1: touchstart 1: touchend 2: touchstart 2: touchend (कम देरी) 1: mousedown 1: mouseup
  • (2%) 1: touchstart 1: touchend 1: mousedown 1: mouseup (और कुछ भी नहीं दूसरे टैप के लिए बिल्कुल)

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

  • (40%): 1: touchstart 1: touchend 2: touchstart 2: स्पर्श करके रद्द
  • (35%) 1

    मैं mousedown और mouseup हुक नहीं है, तो वितरण मोटे तौर पर यह है : touchstart 1: touchend 2: touchstart 2: touchend (वास्तविक वांछित व्यवहार)

  • (25%) 1: touchstart 1: touchend (और कुछ भी नहीं सब पर दूसरे टैप के लिए)

तो यदि मैं माउस की घटनाओं को हुक नहीं करता हूं, तो यह समय का एक तिहाई काम करता है; और अगर मैं touchcancel का नाटक करने के लिए तैयार था तो touchend जैसा ही था, मैं इसे 75% तक प्राप्त कर सकता था। लेकिन यह अभी भी बहुत चूसने वाला है।

वैकल्पिक मैं पहले से ही की कोशिश की है:

  • मैं jQuery Mobile के vmousedown and vmouseup events का उपयोग कर की कोशिश की है, लेकिन वे हमेशा दूसरे टैप के लिए शुरू हो रहा नहीं कर रहे हैं, मैं इस एक ही अंतर्निहित घटना weirdness की वजह से संदेह है।
  • मैं केवल स्पर्श घटनाओं को पूरी तरह से भूल सकता हूं और केवल संश्लेषित माउस ईवेंट का उपयोग कर सकता हूं, लेकिन आमतौर पर भौतिक टैप और संश्लेषित माउस ईवेंट के वितरण के बीच लगभग आधा सेकंड देरी होती है, जबकि स्पर्श घटनाएं तत्काल होती हैं अधिक उत्तरदायी हो। मैं स्क्रॉलिंग को भी रोकना चाहता हूं - यह एक पूर्णस्क्रीन गेम के लिए है, और मैं उपयोगकर्ता को गलती से पता बार को वापस देखने और गेम के हिस्से को अवरुद्ध करने की आवश्यकता नहीं रखता - और touchstart पर आमतौर पर प्राप्त करता है (हालांकि कभी-कभी दूसरी टैप वास्तव में मेरे preventDefault के बावजूद स्क्रीन स्क्रॉल करने में सक्षम है ... एक और कारण है कि मैं इस पूरे घटना गड़बड़ी को हल करना चाहता हूं)।
  • मैंने किसी तृतीय-पक्ष वेब ब्राउज़र (Dolphin) को आजमाया है, लेकिन इसमें ईवेंट के साथ समान समस्याएं हैं। तो मैं अनुमान लगा रहा हूं कि अंतर्निहित वेबव्यू स्क्रिप्ट पर ईवेंट वितरित करने के तरीके के साथ शायद यह एक समस्या है।

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

+0

यह मेरी गैलेक्सी टैबलेट (3.0) पर ठीक काम कर रहा है। मुझे छोटे जिंजरब्रेड फोन (2.3.4) पर यह समस्या है। मुझे लगता है कि मैं अपने स्वयं के वेब व्यू का उपयोग करके इसे हल करने में सक्षम था लेकिन समस्या यह है कि मैं टेबल नहीं पढ़ सकता क्योंकि फोन छोटा है; लेकिन निश्चित रूप से, नारंगी अब और नहीं दिख रहा है। क्या आप वेबव्यू का उपयोग करना चाहते हैं या यह कोई विकल्प नहीं है। –

+0

@ शेरिफ, वर्तमान में मैं सिर्फ वेब सर्वर पर फाइल डाल रहा हूं, लेकिन मुझे कुछ बिंदुओं पर फोनगैप ऐप में लाने की कोशिश करने के लिए कुछ अस्पष्ट योजनाएं हैं। क्या यह वेबव्यू के बारे में आपके प्रश्न का उत्तर देता है? (मुझे इस बिंदु पर एंड्रॉइड विकास के बारे में मूल रूप से कुछ भी पता नहीं है - मैं इसे ब्राउज़र में काम करने की कोशिश कर रहा था। लेकिन मैं हमेशा सीख सकता हूं।) –

उत्तर

3

एंड्रॉइड ब्राउज़र में मल्टी-टच एचटीएमएल 5 गेम विकसित करने और अन्य एंड्रॉइड संगत ब्राउज़रों में भी कोशिश करने की कोशिश करने के बाद, मुझे लगता है कि एंड्रॉइड 2.x का ब्राउज़र बस स्पर्श इनपुट का सही ढंग से समर्थन नहीं करता है। शुरुआत करने वालों के लिए, यह मल्टी-टच का समर्थन नहीं करता है जो कुछ प्रकार के गेम को नामुमकिन बनाता है। (जाहिर है फोन मल्टी-टच का समर्थन करता है क्योंकि आप ज़ूम इत्यादि चुटकी कर सकते हैं, लेकिन ब्राउज़र नहीं है।) फिर विलंबता के साथ कई समस्याएं हैं, 'चिपकने' स्पर्श करती हैं और इसी तरह। मैं सचमुच सच मल्टीटाउच के साथ काम नहीं कर रहा स्पर्श इनपुट के लिए फोन के ड्राइवरों के बारे में कुछ पढ़ना याद रखता हूं (यानी यह एक स्पर्श या चुटकी ज़ूम का पता लगा सकता है और यह है), लेकिन मेरे पास इसका कोई संदर्भ नहीं है ...

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

+0

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

+0

मल्टीटच विचाराधीन फ़ोन पर निर्भर करता है, लेकिन उनमें से ज्यादातर सच मल्टीटच – stealthcopter

+0

@JoeWhite है, आप लोगों को अपने Android संस्करण को अपग्रेड करने की उम्मीद नहीं कर सकते। पुराने फोन निर्माता से अपडेट प्राप्त नहीं करते हैं, इसलिए इसे हैक करना ही एकमात्र संभावना है। यह नौसिखिया उपयोगकर्ताओं के लिए कुछ नहीं है! – daan

1

यह एक सिद्धांत है: बड़े पैमाने पर

परीक्षण करने के लिए init function in the soruce code of a webview के अनुसार सक्षम नहीं था, बयान setFocusable(true) हमेशा अपने initialisation के दौरान वेब दृश्य पर कहा जाता है।

जब मैं दृश्य नहीं फ़ोकस करने योग्य अब और का उपयोग कर setFocusable(false) त्रुटि फिर से ऐसा नहीं हुआ की कोशिश की। ऐसा लगता है कि नारंगी बॉक्स प्रकट नहीं होता है। मैं इसका इस्तेमाल एक छोटे से सैमसंग फोन पर 2.3.4 चला रहा था। मुझे यकीन है कि यह नारंगी बॉक्स प्रकट नहीं हुआ था।

यदि यह सच साबित हो जाता है, तो यह अत्यधिक संभावना है कि हम इसे अपने स्वयं के वेबव्यू के बिना हल कर सकते हैं। चीजों को और अधिक जटिल बनाता है यदि फोकस करने योग्य संपत्ति को झूठी ट्रिगर्स को अन्य समस्याओं को ट्रिगर करना है।

अंत में, मुझे नहीं लगता कि हम इस संपत्ति को जावास्क्रिप्ट से नियंत्रित कर सकते हैं (या हम कर सकते हैं?)। हो सकता है कि आप घोषणा कर सकें कि एक विशिष्ट नियंत्रण या पूरा दस्तावेज़ इनपुट या ऐसा कुछ नहीं है? मैं केवल इतनी बेकार फैल रहा हूं कि यह झूठा हो सकता है।

संपादित करें: अपने प्रश्न मैं बस केवल एक वेब-दृश्य है कि गलत पर अपने फ़ोकस करने योग्य संपत्ति करने के बाद अपना यूआरएल को लोड करता है के साथ एक खाली आवेदन बनाया पर अपनी टिप्पणी के बारे में। कृपया, यदि आपके पास इसका परीक्षण करने के लिए अधिक संसाधन हैं, तो मैं इसे आपके लिए प्रयास करने के लिए अपलोड कर दूंगा। Here is the application

+0

अच्छी खबर है, आपके आवेदन को रोकने करता है नारंगी आयताकार। बुरी खबर यह है कि यह घटनाओं को खराब होने से नहीं रोकती है। घटनाओं का पैटर्न उसी तरह दिखता है जब मैं केवल वेब ब्राउजर में हूं, दूसरी बार टैप की समस्या सहित कभी-कभी कोई घटना उत्पन्न नहीं होती है। आह। हालांकि, पार्श्व सोच के लिए +1। –

+0

आखिरकार, मुझे लगता है कि यह सबसे अधिक उत्पादक उत्तर होगा। इस प्रश्न के लिए मैंने किए गए शोध के आधार पर, मुझे लगता है कि मैं शायद स्पर्श और माउस दोनों घटनाओं को सुन सकूंगा, और स्पर्श घटनाओं के डुप्लिकेट वाले माउस ईवेंट को अनदेखा कर दूंगा। तब सबसे बड़ी समस्या नारंगी आयताकार होती है जब माउस ईवेंट संश्लेषित हो जाता है, जो आपका उत्तर मुझे सौदा करने का एक तरीका देता है। –

0

क्या आपने jQuery मोबाइल ईवेंट का उपयोग करने का प्रयास किया है? आप decoupled विजेट/प्लगइन को यहाँ पा सकते हैं:

https://github.com/jquery/jquery-mobile/tree/master/js

आप शायद jquery.mobile.event.js और jquery.mobile.vmouse की आवश्यकता होगी।js

अब आप बस नल करने के लिए बाध्य कर सकते हैं, स्वाइप jQuery के भीतर आदि घटनाओं। या एक टैप की शुरुआत और अंत के बीच अंतर करना आवश्यक है?

+1

जैसा कि मैंने अपने प्रश्न के अंत में उल्लेख किया है ("विकल्प जो मैंने पहले से ही कोशिश की है:"), मैंने jQuery मोबाइल के 'vmousedown' और' vmouseup' ईवेंट की कोशिश की है, और वे एक ही समस्या से पीड़ित हैं - कभी-कभी दूसरी टैप किसी भी घटना को आग नहीं करता है। मुझे लगता है कि 'टैप' ईवेंट उसी कारण से असफल हो जाएगा (और इसके अलावा, मुझे jQuery मोबाइल ऑफ़र से परे कुछ कस्टम इशारे का समर्थन करने की आवश्यकता होगी)। –

0

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

$("...").bind("mousedown touchstart MozTouchDown", function(e) { 
    if(e.originalEvent.touches && e.originalEvent.touches.length) { 
    e = e.originalEvent.touches[0]; 
    } else if(e.originalEvent.changedTouches && e.originalEvent.changedTouches.length) { 
    e = e.originalEvent.changedTouches[0]; 
    } 

// Handle mouse down 
}); 
+0

तो आपका मतलब है, बस 'ऑन' के बजाय 'बाइंड' का उपयोग करें? मैंने अभी कोशिश की, और इससे मदद नहीं मिली। –

0

आप घटना सीधे संलग्न की कोशिश की है?

$(document).ready(function(){ 
    var el, hypot, log, prev, resetTimeout, start, prevTouchX, prevTouchY; 
    var resetTimeout = null; 
    var start = null; 
    var prev = null; 
    var resetTimeout; 

    var hypot = function(x1, y1, x2, y2) { 
     var dx, dy, h; 
     dx = x2 - x1; 
     dy = y2 - y1; 
     h = Math.sqrt(dx * dx + dy * dy); 
     return Math.round(h * 10)/10; 
    }; 


    var logf = function(event) { 
     var div, table, values, x, y, _ref, _ref2, _ref3, _ref4, _ref5, _ref6; 
     if (event.type === "touchend"){ 
      x = prevTouchX; 
      y = prevTouchY; 
     } else { 
      x = event.touches[0].pageX; 
      y = event.touches[0].pageY; 
      prevTouchX = x; 
      prevTouchY = y; 
     } 
     div = $('.log :first'); 
     table = div.find('table'); 
     if (table.length === 0) { 
      $('.log div:gt(1), .log hr:gt(0)').remove(); 
      table = $('<table border style="border-collapse: collapse;"><tr>\n<th rowspan="2">Event</th>\n<th rowspan="2">X</th>\n<th rowspan="2">Y</th>\n<th colspan="4">From start</th>\n<th colspan="4">From prev</th>\n</tr><tr>\n<th>&Delta;T (ms)</th>\n<th>&Delta;X</th>\n<th>&Delta;Y</th>\n<th>Distance</th>\n<th>&Delta;T (ms)</th>\n<th>&Delta;X</th>\n<th>&Delta;Y</th>\n<th>Distance</th>\n</tr></table>'); 
      div.append(table); 
     } 
     values = { 
      time: event.timeStamp, 
      x: x, 
      y: y 
     }; 
     if (start == null) { 
      start = values; 
     } 
     if (prev == null) { 
      prev = values; 
     } 
     table.append("<tr>\n<td>" + event.type + "</td>\n<td>" + x + "</td>\n<td>" + y + "</td>\n<td>" + (event.timeStamp - start.time) + "</td>\n<td>" + (x - start.x) + "</td>\n<td>" + (y - start.y) + "</td>\n<td>" + (hypot(x, y, start.x, start.y)) + "</td>\n<td>" + (event.timeStamp - prev.time) + "</td>\n<td>" + (x - prev.x) + "</td>\n<td>" + (y - prev.y) + "</td>\n<td>" + (hypot(x, y, prev.x, prev.y)) + "</td>\n</tr>"); 
     prev = values; 

     if(resetTimeout !== null){ 
      window.clearTimeout(resetTimeout) 
     } 
     resetTimeout = window.setTimeout(function(){ 
      start = null; 
      prev = null; 
      $('.log').prepend('<hr/>'); 
     }, 1000); 
    }; 
    var battle = document.getElementById("battle"); 
    battle.addEventListener("touchstart",logf, false); 
    battle.addEventListener("touchmove",function(e){logf(e);e.preventDefault();}, false); 
    battle.addEventListener("touchend",logf, false); 
    battle.addEventListener("touchcancel",logf, false); 
}); 

(क्षमा करें यदि कोड वास्तव में खराब है, मैं वास्तव में बहुत ध्यान लॉग कार्य करने के लिए भुगतान नहीं कर रहा था, लेकिन मैं इसे सही ढंग से घटना के रूप में मेरे touchend घटना में फायरिंग नहीं किया गया था के रूप में कुछ मामूली परिवर्तन करने के लिए बनाया .touches [0] .pageX उस बिंदु पर अपरिभाषित है। इसके अलावा, मैंने इसे एक तैयार फ़ंक्शन में लपेट लिया, क्योंकि मैं सिर्फ आलसी था :-P)

चूंकि यह केवल पहले स्पर्श को ट्रैक कर रहा है (event.touches [ 0]), आप संभवत: स्पर्श सरणी पर जाकर बहु ​​स्पर्श का परीक्षण करने के लिए कुछ समायोजन कर सकते हैं। मैंने अपने एंड्रॉइड डिवाइस (जिंजरब्रेड) पर जो खोजा है, वह यह था कि यदि स्क्रीन पर एक साथ दो अंगुलियां नीचे आती हैं, तो टचेंड इवेंट केवल तब ही आग लग जाएगा जब अंतिम स्पर्श जाने दिया जाता है; यानी दूसरी उंगली रिलीज।

इसके अलावा, जब मैं mousedown/mouseup घटना श्रोताओं संलग्न, तो मैं एक ही सटीक बात आप पूरे नारंगी प्रकाश डाला thingy के साथ किया था मिल गया।

डिवाइस मैं पर परीक्षण ओटीए जिंजरब्रेड अद्यतन के साथ एक सैमसंग Droid Charge था।

+0

यह मूल समस्याओं को ठीक नहीं करता है, और एक नया परिचय देता है। कभी-कभी यह अपेक्षित घटनाओं को उत्पन्न करता है, लेकिन आम तौर पर दूसरा टैप या तो कोई घटना उत्पन्न नहीं करता है, या (आपके परिवर्तनों के साथ नया व्यवहार) 'टचस्टार्ट' उत्पन्न करता है जिसमें कोई 'टचस्टैंड' या 'टचकैंकल' नहीं होता है। –

+0

मेरे जावास्क्रिप्ट के साथ टेस्ट पेज मेरे लिए प्रतिस्थापित: http://sandbox.excastle.com/stackoverflow/android-tap-twice-2.html एंड्रॉइड 2.3.2 चलाने वाले मेरे विजिओ वीटीएबी 1008 पर बताई गई समस्याओं का पुनरुत्पादन करता है। –

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