2011-11-08 31 views
9

Tôi đang tạo một ứng dụng web toàn màn hình sẽ có một số mô-đun/tiện ích sử dụng tính năng tràn 5 của iOS mới: các tính năng cuộn. Điều tôi muốn là vô hiệu hóa hiệu ứng 'bouncy' đó khi cuộn html/body (vì nó là toàn màn hình) nhưng chỉ giữ hiệu ứng đó trên các phần tử có thể cuộn.chỉ tắt cuộn bouncy cho html nhưng vẫn duy trì các phần tử bị tràn: cuộn

làm mịn ảnh hưởng của các yếu tố cuộn Tôi có:

html, body { overflow: hidden; } 

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

và sau đó kịch bản sau đó vô hiệu hóa các hiệu ứng cảm ứng cuộn:

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

mặc dù điều này dường như không làm việc ở tất cả các , bởi vì khi di chuyển một phần tử đến cuối dưới cùng hoặc đầu nó cũng cuộn các documentElement.

Có cách nào để chỉ vô hiệu hóa hiệu ứng đó cho phần tử html của cơ thể không?

Dưới đây là một ví dụ tốt về cách này ảnh hưởng đến các chức năng:

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

+0

Tôi không nghĩ trình xử lý sự kiện của bạn sẽ bao giờ chạm vào preventDefault() vì mục tiêu là phần tử kích hoạt sự kiện, không bao giờ có thể là document.documentElement (). Vì vậy, bạn đang nhìn thấy hành vi tương tự như thể bạn không có trình xử lý sự kiện. – ThinkingStiff

+0

sẽ là 'currentTarget' tôi sợ. mục tiêu có thể trả lại bất cứ điều gì bên trong nó, bạn có thể muốn thử;) – zanona

+0

currentTarget trả về phần tử với trình nghe, chứ không phải phần tử đã ném sự kiện. – ThinkingStiff

Trả lời

0

Hóa ra cho tôi rằng giải pháp hiệu quả duy nhất là sử dụng joelambert/ScrollFix kịch bản, làm việc thực sự tốt không có độ trễ, Thực ra tôi đã sử dụng nó trong một trong các dự án của tôi.

Bạn cũng có thể kiểm tra chi tiết hơn trên his blog post. Xin lỗi vì những người dùng khác đã trả lời nhưng tôi thực sự không nhận được những câu trả lời đó để làm việc cho tôi.

2

Nó không may rằng -webkit-overflow-scrolling không xử lý tốt hơn này. Bạn cần phải theo dõi vị trí y để làm cho nó hoạt động. Tôi đặt lớp học scroll vào bất kỳ thứ gì tôi muốn cuộn trên trang của mình, chẳng hạn như <ul> yếu tố. Hãy quấn một số <div> xung quanh <ul> lấp đầy khung nhìn với overflow-y: auto. Không đặt overflow hoặc height trên <ul>. Các <ul> sẽ mở rộng cao như nội dung của nó và đó là <div> đó là thực sự làm việc di chuyển. -webkit-overflow-scrolling được kế thừa, vì vậy hãy đặt nó ở xa DOM như bạn muốn.

Demo: http://jsfiddle.net/ThinkingStiff/FDqH7/

Script:

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> 

CSS:

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

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

Tôi đã thử mã của bạn với '# viewport' như một div vị trí aboslute với' overflow: auto' và rất nhiều _lorem ipsun inside_ và những gì đang xảy ra là kịch bản đã vô hiệu hóa việc cuộn 'viewport' trong khi vẫn di chuyển bouncy trong cơ thể. – zanona

+0

Đặt một div bên trong #viewport và đặt văn bản bên trong đó. Không thiết lập tràn trên div bên trong, nhưng đặt một lớp "di chuyển" trên nó nếu bạn đang sử dụng mã trên. Cài đặt tour cho #viewport là chính xác cho tràn và vị trí. – ThinkingStiff

+0

@ludicco Tôi đã cập nhật câu trả lời của mình và tạo một bản trình diễn để làm cho nó rõ ràng hơn. Tôi đã sử dụng thành công này trong một vài tháng nay. – ThinkingStiff

2

Dưới đây là một câu trả lời tương tự như ThinkingStiff của, ngoại trừ việc nó không ủy quyền cấu trúc html của bạn. Nó tìm kiếm bất kỳ phần tử nào có nội dung bị tràn và chỉ cho phép cuộn khi người dùng tương tác với họ.

Nhược điểm:

  • Khi người dùng truy cập các giới hạn trên hoặc dưới của nút cuộn, nảy trong nút đó sẽ không xảy ra (nhưng nó sẽ nếu bạn flick từ bên dưới/trên các giới hạn). Điều này có thể có nghĩa là nó không đáp ứng các yêu cầu của bạn về kéo để làm mới: (

  • Có sự khác biệt 2px kỳ lạ mà tôi nhận thấy trong các trường hợp thử nghiệm của mình khi tính toán độ lệch cuộn.Không chắc chắn nơi đó đến từ đâu, và bạn có thể cần phải tinh chỉnh giá trị

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

Wow, ngôn ngữ nào vậy? – Bergi

+0

CoffeeScript (nó biên dịch sang JavaScript - nó chỉ thuận tiện hơn để viết): http://coffeescript.org/ – Nevir

+0

vâng, nhưng việc đánh dấu không được hỗ trợ rất tốt ... – Bergi

Các vấn đề liên quan