2012-05-18 18 views
9

मेरे पास एक एएसपीनेट वेबसाइट है जिसे मैं आईपैड पर समर्थित होने के लिए तैयार कर रहा हूं। जब मैं एक इनपुट तत्व पर ध्यान केंद्रित करता हूं और कीबोर्ड पॉप अप करता है, तो स्थिति निश्चित हेडर div (जो सामान्य रूप से पृष्ठ के साथ स्क्रॉल करता है) पृष्ठ को पॉप अप करेगा जो कुंजीपटल लेता है और वहां की अवधि के लिए फ्रीज करता है इनपुट प्रक्रिया। एक बार कीबोर्ड को वापस गिरा दिया जाता है, तो div वापस जगह पर आ जाता है और सामान्य रूप से फिर से व्यवहार करता है। मैं आईओएस 5 पर परीक्षण कर रहा हूं इसलिए स्थिति: तय किया जाना चाहिए।पेज (आईपैड) पर निश्चित स्थिति div फ्रीज

क्या यह ज्ञात मुद्दा है? क्या कोई इस पर आ गया है और इससे पहले इसका सामना किया है? मुझे इस पर कुछ भी नहीं मिल रहा है।

उत्तर

15

आईओएस 5/आईओएस 6/आईओएस 7 पर फिक्स्ड पोजीशनिंग टूट गई है।

संपादित करें 3: आईओएस 8 के लिए इस उत्तर के अंत में एक कामकाजी फिक्स के लिंक देखें।

स्थिति:

क) पेज

या

ख ज़ूम इन करता है) कुंजीपटल (एक इनपुट हो रही फोकस की वजह से iPad/iPhone के पर चलता): तय टूटी हुई है जब या तो है।

लिंक और ज़ूमिंग या इनपुट फोकस देकर आप jsbin.com/icibaz/3 में स्वयं को बग देख सकते हैं। आप edit the html स्वयं को संपादित कर सकते हैं।

कीड़े (क) और के बारे में

नोट्स (ख):

  1. top: 0px; left: 0px; साथ एक निश्चित div (ऊपर या स्क्रीन के ऊपर से नीचे) गलत स्थिति में दिखाई देंगे जब एक इनपुट ध्यान केंद्रित हो जाता है और कीबोर्ड शो

  2. समस्या स्क्रीन पर इनपुट के ऑटो-सेंटरिंग के साथ कुछ करने के लिए प्रतीत होती है (window.pageYOffset बदलना)।

  3. यह एक गणना गलती है, और नहीं एक redraw गलती प्रतीत होता है: अगर आप को बदलने के लिए top: मजबूर (जैसे 0px के बीच स्विच और 1px) Onscroll घटना पर, आप एक पिक्सेल द्वारा तय div चाल देख सकते हैं, लेकिन यह गलत जगह पर बना हुआ है।

  4. एक समाधान जिसका मैंने पहले उपयोग किया था hide the fixed div when an input gets focus - मैंने जो अन्य उत्तर लिखा है उसे देखें।

  5. निश्चित div उस पृष्ठ पर उसी पूर्ण स्थिति पर अटक जाता है जब कीबोर्ड खोला गया था।

  6. तो शायद इनपुट में फोकस होने पर div को पूर्ण स्थिति में बदल दें? संपादित करें 3: इस समाधान का उपयोग कर नीचे टिप्पणी देखें। या शायद कुंजीपटल खोले जाने से पहले पेजएक्स ऑफसेट/पेज वाई ऑफसेट वैल्यू को सेव करें, और ऑनक्रॉल इवेंट में उन मानों और वर्तमान पेज एक्सऑफसेट/पेज वाई ऑफसेट वैल्यू (कीबोर्ड को खोले जाने के बाद चालू) के बीच अंतर की गणना करें, और उस अंतर से निश्चित div को ऑफ़सेट करें।

  7. पृष्ठ ज़ूम होने पर निश्चित स्थिति के साथ एक अलग समस्या प्रतीत होती है - here (इसे अच्छी तरह से here टिप्पणियों में निश्चित के लिए एंड्रॉइड समर्थन के बारे में अच्छी जानकारी दें)।

संपादित करें 1: उपयोग jsbin (jsfiddle नहीं) पुन: पेश और jsbin की (संपादित करें पृष्ठ नहीं) फुलस्क्रीन दृश्य का उपयोग करने। Jsfiddle से बचें (और jsbin के दृश्य को संपादित करें) क्योंकि वे कोड को आईफ्रेम के अंदर डालते हैं जो निश्चित स्थिति और पेज वाई ऑफसेट के साथ हस्तक्षेप का कारण बनता है।

संपादित करें 2: iOS 6 और iOS 7 मोबाइल सफारी position:fixed; अब भी उन्हीं समस्याओं है - शायद वे डिजाइन द्वारा कर रहे हैं !.

संपादित करें 3: (बी) के लिए एक समाधान समाधान है जब इनपुट फोकस हो जाता है, शीर्षलेख को पूर्ण स्थिति में बदलता है और फिर पृष्ठ स्क्रॉल ईवेंट for example पर शीर्षलेख शीर्ष सेट करता है। यह समाधान:

  • इनपुट केंद्रित नहीं होने पर निश्चित स्थिति का उपयोग करता है (window.onscroll का उपयोग करके भयानक जिटर है)।
  • चुटकी-ज़ूम की अनुमति न दें (उपरोक्त बग (ए) से बचें)।
  • पूर्ण स्थिति का उपयोग करता है और window.pageYOffset एक बार एक इनपुट ध्यान केंद्रित हो जाता है (ताकि हैडर सही ढंग से रखा जाता है)।
  • हैं, तो स्क्रॉल इनपुट ध्यान केंद्रित है, जबकि बराबर pageYOffset को style.top सेट (हेडर कुछ हद तक भी iOS8 पर Onscroll घटना देरी की वजह से घबराना जाएगा)।
  • तो iOS8 पर ऐप्स के भीतर UIWebView का उपयोग कर, या का उपयोग कर < = iOS7, अगर स्क्रॉल जब इनपुट ध्यान केंद्रित किया, हेडर सुपर चिड़चिड़ा हो जाएगा क्योंकि Onscroll स्क्रॉल खत्म होने तक निकाल दिया नहीं है।
  • वापस स्थिर स्थिति हैडर के लिए एक बार इनपुट ध्यान केंद्रित खो देता है जाओ (उदाहरण input.onblur का उपयोग करता है, लेकिन शायद document.body.onfocus उपयोग करने के लिए tider)।
  • उपयोगिता से सावधान रहें विफल रहता है कि यदि हेडर बहुत बड़ा है, तो इनपुट को अवरुद्ध/कवर किया जा सकता है।
  • मैं जब कीबोर्ड दिखाया जा रहा है आईओएस पेज/व्यूपोर्ट ऊंचाई में कीड़े की वजह से एक पाद लेख के लिए काम करने के लिए नहीं मिल सका।
  • संपादित http://jsbin.com/xujofoze/4/edit और दृश्य का उपयोग कर उदाहरण http://output.jsbin.com/xujofoze/4/quiet
+0

यह पता चला है यह है एक iOS बग, मैं इस छोड़ना होगा अभी के लिए जारी करें, लेकिन आपके सुझाव मान्य हैं इसलिए मैं इस उत्तर को सही – jas

+0

जेस चिह्नित करूंगा, क्या आईओएस बग समस्या यूआरएल के लिए लिंक देना संभव है? – robocat

+0

मैंने देखा नहीं है कि आईओएस 6 में क्या तय किया गया है, लेकिन कम से कम एक अतिरिक्त बग जोड़ा गया है: http://igstudio.blogspot.com/2012/09/positionfixed-in-ios-6.html (मैं भी संदेह है कि निश्चित div को एक सीएसएस प्रॉपर्टी दे रही है जो इसे हार्डवेयर त्वरित कंपोजिट करने के लिए मजबूर कर सकती है)। – robocat

0

मेरी जरूरतों के लिए उपयोग कर रहा है, मैं यह आसान, एक निरपेक्ष तैनात शीर्ष लेख का उपयोग स्क्रॉल से पहले इसे छिपाने के लिए और यह दिखाने जब खत्म स्क्रॉल (मैं समर्थन करने के लिए एक ही कोड की जरूरत करने के लिए मिला आईओएस 4 और एंड्रॉइड)।

मेरी प्रयोजनों के लिए, मैं एक touchstart घटना पर हैडर छुपाने के लिए, और touchend या scroll घटना पर फिर से यह दिखाने के (प्लस कुछ टाइमर जवाबदेही में सुधार/अस्थिर कम करने के लिए)। यह चमकता है, लेकिन मुझे लगता है कि सबसे अच्छा समझौता है। एक touchmove घटना (jQuery करता है) का उपयोग कर स्क्रॉल के शुरू होने से पता लगा सकते हैं, लेकिन मैंने पाया क्योंकि touchmove मेरे लिए के रूप में अच्छी काम नहीं किया:

  1. नियमित रूप से iPad स्क्रॉल से पहले एक रीपेंट करने के लिए विफल रहता है (यानी पूर्ण शीर्षलेख अटक गया है - भले ही top स्क्रॉलिंग शुरू होने से पहले बदला गया था)।

  2. जब एक इनपुट तत्व ध्यान केंद्रित, आईपैड ऑटो केन्द्रों तत्व हो जाता है, लेकिन scrollstart गतिविधि सक्रिय नहीं प्राप्त करता है (क्योंकि कोई touchmove अगर सिर्फ click एक इनपुट ing)।

iOS5 पर एक निश्चित हैडर को लागू तय की और पूर्ण स्थिति के एक संकर दृष्टिकोण का उपयोग करके सुधार किया जा सकता:

  • iOS5 के लिए इस्तेमाल किया तय स्थिति जब तक एक इनपुट ध्यान केंद्रित हो जाता है।

  • जब इनपुट इनपुट (कीबोर्ड दिखा रहा है), आईओएस 4 पूर्ण स्थिति कोड में बदलें।

  • जब कीबोर्ड बंद हो जाता है, तो निश्चित स्थिति पर वापस बदलें। जब कुंजीपटल (जैसे कीबोर्ड छिपाने कुंजी का उपयोग) बंद कर दिया है पता लगाने के लिए

कोड document तत्व पर DOMFocusOut घटना रजिस्टर और निम्न कोड की तरह कुछ करने के लिए है। टाइमआउट की आवश्यकता है क्योंकि DOMFocusOut घटना तब होती है जब एक तत्व फोकस प्राप्त करता है और दूसरा इसे खो देता है।

function document_DOMFocusOut() { 
    clearTimeout(touchBlurTimer); 
    touchBlurTimer = setTimeout(function() { 
     if (document.activeElement == document.body) { 
      handleKeyboardHide(); 
     } 
    }.bind(this), 400); 
} 

मेरे तय हैडर कोड है कुछ की तरह:

{ 
    setup: function() { 
     observe(window, 'scroll', this, 'onWinScroll'); 
     observe(document, 'touchstart', this, 'onTouchStart'); 
     observe(document, 'touchend', this, 'onTouchEnd'); 
     if (isMobile) { 
      observe(document, 'DOMFocusOut', this, 'docBlurTouch'); 
     } else if (isIE) { 
     // see http://ajaxian.com/archives/fixing-loss-of-focus-on-ie for code to go into this.docBlurIe() 
      observe(document, 'focusout', this, 'docBlurIe'); 
     } else { 
      observe(isFirefox ? document : window, 'blur', this, 'docBlur'); 
     } 
    }, 

    onWinScroll: function() { 
     clearTimeout(this.scrollTimer); 
     this.scrolling = false; 
     this.rehomeAll(); 
    }, 

    rehomeAll: function() { 
     if ((isIOS5 && this.scrolling) || isIOS4 || isAndroid) { 
      this.useAbsolutePositioning(); 
     } else { 
      this.useFixedPositioning(); 
     } 
    }, 

    // Important side effect that this event registered on document on iOs. Without it event.touches.length is incorrect for any elements in the document using the touchstart event!!! 
    onTouchStart: function(event) { 
     clearTimeout(this.scrollTimer); 
     if (!this.scrolling && event.touches.length == 1) { 
      this.scrolling = true; 
      this.touchStartTime = inputOrOtherKeyboardShowingElement(event.target) ? 0 : (new Date).getTime(); 
      // Needs to be in touchStart so happens before iPad automatic scrolling to input, also not reliable using touchMove (although jQuery touch uses touchMove to unreliably detect scrolling). 
      this.rehomeAll(); 
     } 
    }, 

    onTouchEnd: function(event) { 
     clearTimeout(this.scrollTimer); 
     if (this.scrolling && !event.touches.length) { 
      var touchedDuration = (new Date).getTime() - this.touchStartTime; 
      // Need delay so iPad can scroll to the input before we reshow the header. 
      var showQuick = this.touchStartTime && touchedDuration < 400; 
      this.scrollTimer = setTimeout(function() { 
       if (this.scrolling) { 
        this.scrolling = false; 
        this.rehomeAll(); 
       } 
      }.bind(this), showQuick ? 0 : 400); 
     } 
    }, 

    // ... more code 
} 

jQuery मोबाइल scrollstart और scrollstop घटनाओं का समर्थन करता है:

var supportTouch = $.support.touch, 
    scrollEvent = "touchmove scroll", 
    touchStartEvent = supportTouch ? "touchstart" : "mousedown", 
    touchStopEvent = supportTouch ? "touchend" : "mouseup", 
    touchMoveEvent = supportTouch ? "touchmove" : "mousemove"; 

function triggerCustomEvent(obj, eventType, event) { 
    var originalType = event.type; 
    event.type = eventType; 
    $.event.handle.call(obj, event); 
    event.type = originalType; 
} 

// also handles scrollstop 
$.event.special.scrollstart = { 

    enabled: true, 

    setup: function() { 

     var thisObject = this, 
      $this = $(thisObject), 
      scrolling, 
      timer; 

     function trigger(event, state) { 
      scrolling = state; 
      triggerCustomEvent(thisObject, scrolling ? "scrollstart" : "scrollstop", event); 
     } 

     // iPhone triggers scroll after a small delay; use touchmove instead 
     $this.bind(scrollEvent, function(event) { 

      if (!$.event.special.scrollstart.enabled) { 
       return; 
      } 

      if (!scrolling) { 
       trigger(event, true); 
      } 

      clearTimeout(timer); 
      timer = setTimeout(function() { 
       trigger(event, false); 
      }, 50); 
     }); 
    } 
}; 
संबंधित मुद्दे