2011-11-08 15 views
9

新しいiOS 5オーバーフロー:スクロール機能を使用するいくつかのモジュール/ウィジェットを持つフルスクリーンウェブアプリを作成している。 私が望むのは、html/bodyをスクロールするとき(フルスクリーンであるため)、その効果を無効にすることですが、スクロール可能な要素に対してのみその効果を維持します。これがすべてで動作するようには思えないがhtml用のバウンススクロールを無効にするが、オーバーフローのある要素を維持する:scroll

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

html, body { overflow: hidden; } 

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

、その後、タッチスクロールの効果を無効にし、次のスクリプト:私が持っているスクロール可能な要素の影響を滑らかにする

要素を非常に下端または上にスクロールすると、documentElementもスクロールするためです。

body html要素に対してのみその効果を無効にする方法はありますか?

ここでは、これが機能にどのように影響するかを示す良い例です:

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

+0

targetがイベントをトリガーした要素であるため、あなたのイベントハンドラがpreventDefault()にヒットするとは考えていません。これは決してdocument.documentElement()ではありません。イベントハンドラを持っていない場合と同じ動作をしています。 – ThinkingStiff

+0

これは 'currentTarget'となるでしょう、私は恐れています。ターゲット内で何かを返すことができます。試してみることもできます) – zanona

+0

currentTargetは、イベントをスローした要素ではなく、リスナーを持つ要素を返します。 – ThinkingStiff

答えて

0

それだけで効果的なソリューションがjoelambert/ScrollFixスクリプトを使用することでした、本当によく働いていたことを私のために判明遅れはなく、実際に私のプロジェクトの1つで既に使用しています。

詳細についてはhis blog postで確認することもできます。 他のユーザーには申し訳ありませんが、私は本当にその回答を得られませんでした。

2

それは-webkit-overflow-scrollingは、この優れたを処理しないことを残念です。あなたはそれを動作させるためにyの位置を追跡する必要があります。 <ul>要素のように、ページ上をスクロールしたいものにクラスscrollを配置します。ビューポートを塗りつぶす<ul>の周りに<div>をラップすると、overflow-y: autoが表示されます。 <ul>overflowまたはheightを入れないでください。 <ul>はその内容と同じくらいに拡張され、実際にはスクロールしているのは<div>です。 -webkit-overflow-scrollingは継承されているので、DOMの遠いところに置いてください。

デモ: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> 

CSS:

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

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

あなたのコードを試しました'overflow:auto'と多くの_lorem ipsun inside_を持つabosluteの位置付けされたdivとして'#viewport'を使い、現在起こっていることは、スクリプトが 'viewport'のスクロールを無効にし、 – zanona

+0

#viewportの内側にdivを入れ、その中にテキストを入れます。内側のdivにオーバーフローを設定しないでください。ただし、上記のコードを使用している場合は、クラスに「スクロール」を設定してください。 #viewportのツアー設定は、オーバーフローと位置に対して正しいです。 – ThinkingStiff

+0

@ludicco私は自分の答えを更新し、より明確にするためのデモを作成しました。私はこれを数ヶ月間使っています。 – ThinkingStiff

2

ここThinkingStiffさんに似た答えはそれことを除いて、ですあなたのhtml構造を強制するものではありません。オーバーフローしたコンテンツを持つ要素を検索し、ユーザーがそれらとやり取りしているときにのみスクロールを有効にします。

マイナス面:ユーザーは(それはあなたが限界の上方/下方からフリックする場合)が発生しないことをノード内にバウンス、スクロール可能なノードの上部または下部限界にぶつかる

  • 一度。これは、おそらく、それがリフレッシュするためのあなたの要件を満たしていないことを意味します:(

  • 私はスクロールオフセットを計算する際にテストケースで気づいた奇妙な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

CoffeeScript(JavaScriptをコンパイルするだけで、書く方がはるかに便利です):http://coffeescript.org/ – Nevir

+0

ええ、強調表示はあまりサポートされていません... – Bergi

関連する問題