2011-11-08 7 views
9

मैं एक पूर्ण स्क्रीन वेब ऐप बना रहा हूं जिसमें कुछ मॉड्यूल/विजेट होंगे जो नए आईओएस 5 ओवरफ्लो का उपयोग करते हैं: स्क्रॉल फीचर्स। मैं चाहता हूं कि HTML/body (जब यह पूर्ण स्क्रीन है) स्क्रॉल करते समय उस 'उछाल' प्रभाव को अक्षम करना है, लेकिन केवल उस स्क्रॉल करने योग्य तत्वों पर प्रभाव रखें।केवल एचटीएमएल के लिए बाउंसी स्क्रॉलिंग को अक्षम करना, लेकिन अतिप्रवाह वाले तत्वों को बनाए रखना: स्क्रॉल

स्क्रॉल तत्वों के प्रभाव सम करने के लिए मेरे पास है:

html, body { overflow: hidden; } 

.scrollable { 
    overflow: scroll; 
    -webkit-overflow-scrolling: touch; 
} 

और उसके बाद निम्न स्क्रिप्ट जो स्पर्श स्क्रॉल प्रभाव को निष्क्रिय:

$(document).bind('touchmove', function (e) { 
    if (e.target === document.documentElement) { 
     e.preventDefault(); 
    } 
}); 

इस हालांकि बिल्कुल काम नहीं लगता है , क्योंकि जब एक तत्व को बहुत नीचे या ऊपर तक स्क्रॉल करते हैं तो यह documentElement को भी स्क्रॉल करता है।

क्या शरीर के HTML तत्व के लिए केवल उस प्रभाव को अक्षम करने का कोई तरीका है?

http://dl.dropbox.com/u/1928164/ios5/index.html

+0

मुझे नहीं लगता कि आपका ईवेंट हैंडलर कभी भी रोकथाम को रोक देगा() क्योंकि लक्ष्य वह तत्व है जो ईवेंट को ट्रिगर करता है, जो दस्तावेज़ नहीं हो सकता है। दस्तावेज़ एलीमेंट ()। तो आप वही व्यवहार देख रहे हैं जैसे कि आपके पास ईवेंट हैंडलर नहीं था। – ThinkingStiff

+0

जो 'वर्तमान लक्ष्य' होगा, मुझे डर है। लक्ष्य इसके अंदर कुछ भी वापस कर सकता है, आप कोशिश कर सकते हैं;) – zanona

+0

वर्तमान लक्ष्य लक्ष्य श्रोता के साथ तत्व लौटाता है, न कि घटना को फेंकने वाले तत्व। – ThinkingStiff

उत्तर

0

यह मेरे लिए पता चला है कि केवल प्रभावी समाधान joelambert/ScrollFix स्क्रिप्ट का उपयोग करने के लिए था, अच्छी तरह से वास्तव में काम किया बिना किसी झगड़े के, वास्तव में मैं पहले से ही अपनी परियोजनाओं में से एक में इसका उपयोग कर रहा हूं।

आप his blog post पर अधिक जानकारी में इसके बारे में भी जांच सकते हैं। अन्य उपयोगकर्ताओं के लिए खेद है जिन्होंने उत्तर दिया लेकिन मुझे वास्तव में उन उत्तरों को मेरे लिए काम नहीं मिला।

2

यह दुर्भाग्यपूर्ण है कि -webkit-overflow-scrolling इस बेहतर संभाल नहीं करता है:

यहाँ यह है कि यह कैसे कार्यक्षमता को प्रभावित करता है का एक अच्छा उदाहरण है। इसे काम करने के लिए आपको y स्थिति को ट्रैक करने की आवश्यकता है। मैंने तत्वों जैसे कि मेरे पृष्ठ पर स्क्रॉल करना चाहते हैं, इस पर कक्षा scroll कक्षा डालें। <div><ul> के आस-पास लपेटें जो overflow-y: auto के साथ व्यूपोर्ट भरता है। <ul> पर overflow या height न डालें। <ul> इसकी सामग्री के रूप में लंबा विस्तार करेगा और यह <div> है जो वास्तव में स्क्रॉलिंग कर रहा है। -webkit-overflow-scrolling विरासत में मिला है, इसलिए इसे जितना चाहें डीओएम तक रखें।

डेमो: http://jsfiddle.net/ThinkingStiff/FDqH7/

स्क्रिप्ट:

var swipeY = 0; 

function onTouchMove(event) { 

    var scroll = event.target.closestByClassName('scroll'); 

    if (scroll) { 

     var top = scroll.positionTop - scroll.parentNode.positionTop, 
      heightDifference = (0 - scroll.offsetHeight + scroll.parentNode.offsetHeight); 

     if((top >= 0) && (event.touches[0].screenY > swipeY)) { 
      event.preventDefault(); //at top, swiping down 
     } else if((top <= heightDifference) && (event.touches[0].screenY < swipeY)) { 
      event.preventDefault(); //at bottom, swiping up 
     }; 

    } else { 
     event.preventDefault(); 
    }; 

}; 

function onTouchStart(event) { 

    swipeY = event.touches[0].screenY; 

}; 

Element.prototype.closestByClassName = function (className) { 

    return this.className && this.className.split(' ').indexOf(className) > -1 
     ? this 
     : (this.parentNode.closestByClassName && this.parentNode.closestByClassName(className)); 

}; 

window.Object.defineProperty(Element.prototype, 'positionTop', { 

    get: function() { 
     return this.offsetTop - this.parentNode.scrollTop; 
    } 

}); 

document.getElementById('viewport').addEventListener('touchmove', onTouchMove, false); 
document.getElementById('viewport').addEventListener('touchstart', onTouchStart, false); 

HTML:

<div id="viewport"> 
<div id="scroll-view"> 
    <ul class="scroll"> 
     <li>scroll scroll scroll scroll scroll </li> 
     <li>scroll scroll scroll scroll scroll </li> 
     <li>scroll scroll scroll scroll scroll </li> 

     . . . 

    </ul> 
</div> 
</div> 

सीएसएस:

#viewport { 
    border: 1px solid black; 
    height: 460px; 
    width: 320px; 
    -webkit-overflow-scrolling: touch; 
} 

#scroll-view { 
    height: 100%; 
    overflow-y: auto; 
    width: 100%; 
} 
+0

मैंने आपके कोड की कोशिश की है '# व्यूपोर्ट' के साथ 'ओवरफ्लो: ऑटो' और _lorem ipsun के अंदर एक बहुत से स्थानांतरित div के रूप में और वर्तमान में क्या हो रहा है यह है कि स्क्रिप्ट ने शरीर में उछाल वाली स्क्रॉलिंग को छोड़कर 'व्यूपोर्ट 'की स्क्रॉलिंग अक्षम कर दी है। – zanona

+0

#viewport के अंदर एक div डाल दें और उस पाठ को उसके अंदर रखें। अंदरूनी div पर ओवरफ़्लो सेट न करें, लेकिन यदि आप उपरोक्त कोड का उपयोग कर रहे हैं तो उस पर एक वर्ग "स्क्रॉल" डालें। #viewport के लिए टूर सेटिंग्स अतिप्रवाह और स्थिति के लिए सही हैं। – ThinkingStiff

+0

@ लुडिको मैंने अपना जवाब अपडेट किया और इसे और स्पष्ट करने के लिए एक डेमो बनाया। मैं इसे कुछ महीनों के लिए सफलतापूर्वक उपयोग कर रहा हूं। – ThinkingStiff

2

यहाँ, ThinkingStiff के लिए एक समान जवाब यह है कि सिवाय आपकी एचटीएमएल संरचना को जरूरी नहीं है। यह किसी भी तत्व की तलाश करता है जिसमें अतिप्रवाह सामग्री है और केवल उपयोगकर्ता स्क्रॉलिंग को सक्षम बनाता है जब उपयोगकर्ता उनके साथ बातचीत कर रहा है।

Downsides:

  • एक बार जब उपयोगकर्ता, स्क्रॉल नोड के ऊपर या नीचे सीमा को छूता है कि नोड के भीतर उछल घटित नहीं होगा (लेकिन यह आप के नीचे से झटका अगर होगा/सीमा से ऊपर)। इसका शायद यह अर्थ है कि यह रीफ्रेश करने के लिए खींचने के लिए आपकी आवश्यकताओं को पूरा नहीं करता है :(

  • स्क्रॉल ऑफसेट की गणना करते समय मैंने अपने परीक्षण मामलों में एक अजीब 2px अंतर देखा है।जहां कि से आया सुनिश्चित नहीं हैं, और आप मूल्य

CoffeeScript बदलाव करने की आवश्यकता हो सकती:

# Vertical scrolling behavior overrides. 
# 
# This disables vertical scrolling on the page for touch devices, unless the user is scrolling 
# within an overflowed node. This requires some finessing of the touch events. 
# 
# **NOTE:** This code ends up disabling bounce behavior if the user tries to scroll on a node that 
# is already at its upper or lower limit. 
window$ = $(window) 
initialY = null 
nodeStack = [] 

# When a user begins a (potential) drag, we jot down positional and node information. 
# 
# The assumption is that page content isn't going to move for the duration of the drag, and that 
# it would also be awkward if the drag were to change/stop part way through due to DOM 
# modifications. 
window$.bind 'touchstart', (evt) -> 
    initialY = evt.originalEvent.pageY 
    nodeStack = $(evt.target).parents().andSelf().filter(':not(body, html)').get().reverse() 
    nodeStack = nodeStack.map (node) -> $(node) 

window$.bind 'touchend touchcancel', (evt) -> 
    initialY = null 
    nodeStack = [] 

# We override the `touchmove` event so that we only allow scrolls in allowable directions, 
# depending on where the user first began the drag. 
window$.bind 'touchmove', (evt) -> 
    return evt.preventDefault() if initialY == null 
    # A positive direction indicates that the user is dragging their finger down, thus wanting the 
    # content to scroll up. 
    direction = evt.originalEvent.pageY - initialY 

    for node$ in nodeStack 
    nodeHeight = node$.height() 
    # For some reason, the node's scrollHeight is off by 2 pixels in all cases. This may require 
    # tweaking depending on your DOM. Concerning. 
    scrollHeight = node$[0].scrollHeight - 2 
    nodeScrollTop = node$.scrollTop() 

    # If we have a scrollable element, we want to only allow drags under certain circumstances: 
    if scrollHeight > nodeHeight 
     # * The user is dragging the content up, and the element is already scrolled down a bit. 
     return if direction > 0 and nodeScrollTop > 0 
     # * And the reverse: the user is dragging the content down, and the element is up a bit. 
     return if direction < 0 and nodeScrollTop < scrollHeight - nodeHeight 

    # Otherwise, the default behavior is to disable dragging. 
    evt.preventDefault() 
+0

वाह, वह भाषा कौन है? – Bergi

+0

कॉफीस्क्रिप्ट (यह जावास्क्रिप्ट को संकलित करता है - यह लिखने के लिए बहुत अधिक सुविधाजनक है): http://coffeescript.org/ – Nevir

+0

हाँ, लेकिन हाइलाइटिंग इतना समर्थित नहीं है ... – Bergi

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