2011-12-22 6 views
7

आईओएस 5 अब देशी ओवरफ्लो की अनुमति देता है: स्क्रॉल समर्थन।सशर्त रूप से मोबाइल सफारी में स्क्रॉलिंग/टचमोव ईवेंट ब्लॉक करें

मैं जो करना चाहता हूं वह 'स्क्रोल करने योग्य' वर्ग या उनके बच्चों के तत्वों को छोड़कर touchmove ईवेंट को अक्षम कर सकता है।

लेकिन मुझे यह काम करने के लिए प्रतीत नहीं होता है; यह है कि क्या मैं नीचे के साथ काम कर रहा है:

<html> 
<head> 
<style> 
.scrollable { 
height: 5em; 
overflow-y: scroll; 
-webkit-overflow-scrolling: touch; 
} 
</style> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
<script> 

// doesn't seem to work 
var handleMove = function (e) { 
    if (!$(e.target).parents().andSelf().hasClass('scrollable')) { 
    e.preventDefault(); 
    } 
}; 

document.addEventListener('touchmove', handleMove, true); 

</script> 
</head> 
<body> 
<div> 
don't scroll if you drag here 
</div> 
<div class='scrollable'> 
should be scrollable if you drag here 
<ul> 
<li>and here</li> 
<li>and here</li> 
<li>and here</li> 
<li>and here</li> 
<li>and here</li> 
<li>and here</li> 
<li>and here</li> 
<li>and here</li> 
</ul> 
</div> 
don't scroll if you drag here 
</body> 
</html> 

उत्तर

-1

यहाँ एक सब के लिए खड़ी स्क्रॉल अक्षम करने के लिए (अधिकतर) काम कर समाधान है, लेकिन overflowed तत्वों:

(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

इस प्रश्न पर कहीं भी एक कॉफ़ीस्क्रिप्ट टैग नहीं है और न ही किसी ने कॉफ़ीस्क्रिप्ट के बारे में पूछा है। –

+1

क्या यह उत्तर को कम मान्य बनाता है? – Nevir

+10

हां, बिल्कुल। –

15

मुझे पता है कि यह कुछ समय हो गया है क्योंकि आपने सवाल पूछा था, लेकिन मेरे पास एक ही समस्या थी और मैंने समस्या को हल करने के आधार के रूप में आपके कोड का उपयोग किया। तो प्रेरणा के लिए धन्यवाद।

(जावास्क्रिप्ट + jQuery)

<script> 
var handleMove = function (e) { 
    var scrollable = false; 
    var items = $(e.target).parents(); 
    $(items).each(function(i,o) { 
     if($(o).hasClass("scrollable")) { 
      scrollable = true; 
     } 
    }); 
    if(!scrollable) 
     e.preventDefault(); 
}; 
document.addEventListener('touchmove', handleMove, true); 
</script> 

या कम वर्बोज़, लेकिन अंत में एक ही परिणाम (क्रेडिट जम्मू ग्रीफिथ):

<script> 
var handleMove = function (e) { 
    if($(e.target).closest('.scrollable').length == 0) { e.preventDefault(); } 
} 
document.addEventListener('touchmove', handleMove, true); 
</script> 

आप निम्न मेटा टैग शामिल करना चाहिए।

<meta name="viewport" content="width=device-width, initial-scale=1.0, 
    maximum-scale=1.0, user-scalable=no;" /> 
+6

हैंडल की सामग्री को व्यक्त करने के लिए थोड़ा और अधिक तरीका हैमोव फ़ंक्शन 'if (! $ (E.target) .closest ('scrollable') होगा।लंबाई) { e.preventDefault(); } ' –

+0

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

1

मैं स्कॉट के जवाब की कोशिश की लेकिन यह मेरे iphone पर काम नहीं किया आईओएस 5.1.1

इसके अलावा, यह विशेष रूप से महत्वपूर्ण है कि आप एक WebClip एप्लिकेशन का निर्माण कर रहे हैं, भगवान मैं क्या आशा IOS 6 होगा एक व्यूपोर्ट टैग को अनुमति दें जो ऑटो-बाउंस

नीचे मेरा संस्करण नीचे काम करता है (या नहीं) साथ ही साथ स्कॉट का उत्तर भी काम करता है, क्योंकि यह अनिवार्य रूप से वही काम करता है।

jQuery 1.7.2

 $(document).bind("touchmove",function(e){ 
      e.preventDefault(); 
     }); 
     $('.scrollable').bind("touchmove",function(e){ 
      e.stopPropagation(); 
     }); 
2

आप jQuery document.ready स्थिति में यह लिख अगर यह काम करेंगे।

$('body').on('touchmove', function (e) { 
    if ($(e.target).closest("your_scrollable_div_selector").length == 0) 
    e.preventDefault(); 
}); 
3

जावास्क्रिप्ट संस्करण Nevirs उत्तर के आधार पर:

var initialY = null; 
var nodeStack = []; 
var $window = $(window); 

$window.bind('touchstart', function(e) { 
    initialY = e.originalEvent.pageY; 
    nodeStack = $(e.target).parents().andSelf().filter(':not(body, html)').get().reverse(); 
    nodeStack = nodeStack.map(function(node) { 
     return $(node); 
    }); 
}); 

$window.bind('touchend touchcancel', function(e) { 
    initialY = null; 
    nodeStack = []; 
}); 

$window.bind('touchmove', function(e) { 

    if (!initialY) { 
     e.preventDefault(); 
    } 

    var direction = e.originalEvent.pageY - initialY; 

    for (var i = 0; i < nodeStack.length; i +=1) { 
     var $node = nodeStack[i]; 
     var nodeHeight = $node.height(); 
     var scrollHeight = $node[0].scrollHeight - 2; 
     var nodeScrollTop = $node.scrollTop(); 

     if (scrollHeight > nodeHeight) { 
      // the user is dragging the content up, and the element is already scrolled down a bit. 
      var allowedUp = direction > 0 && nodeScrollTop > 0; 

      // the user is dragging the content down, and the element is up a bit. 
      var allowedDown = direction < 0 && nodeScrollTop < scrollHeight - nodeHeight; 

      if (allowedUp || allowedDown) { 
       return; 
      } 
     } 
    } 

    // disable drag 
    e.preventDefault(); 
}); 
0

हम touchmove घटना के बजाय touchstart घटना का उपयोग कर सकते हैं। एक फिंगर घटनाओं के तहत यह कहता है कि एक पैन के दौरान कोई घटना नहीं भेजी जाती है, इसलिए टचमोव बहुत देर हो सकती है।

मैंने श्रोताओं को दस्तावेज में जोड़ा, शरीर नहीं।

document.ontouchstart = function(e){ 
    e.preventDefault(); 
} 
संबंधित मुद्दे