Skip to content

Instantly share code, notes, and snippets.

@yusugomori
Created April 1, 2012 12:47
Show Gist options
  • Save yusugomori/2275137 to your computer and use it in GitHub Desktop.
Save yusugomori/2275137 to your computer and use it in GitHub Desktop.
iphoneTouchScroll.coffee
#
# javascripts/iphoneTouchScroll.coffee
#
class iPhoneTouchScroll
constructor: ->
@clientHeight = 0
@dataX = 0
@dataY = 0
@startX = 0
@startY = 0
@dragX = 0
@dragY = 0
@isDrag = false
@tapTimer = false
@isHref = false
@isInput = false
@targetHref = null
@prevStatus = null
@preserveHeight = 0
@boot()
# イベント監視スタート
@onTouch(".scrollview-host")
@onRotate(".scrollview-host")
$(document).on "click", ".main-header .nav a", (e) =>
@boot()
boot: () ->
$('body').imagesLoaded =>
@_getClientHeight()
@_getPreserveHeight(".scrollview-host")
@iphoneHack()
_getClientHeight: () ->
@clientHeight = document.documentElement.clientHeight + 15 # iPhone hack
$("body, .page-view").css
"min-height": @clientHeight
"max-height": @clientHeight
$(".content").css
height: @clientHeight
"overflow-y": "hidden"
$(".scrollview-host").css
"min-height": @clientHeight
"-webkit-transform": "translate3d(0px, 0px, 0px)"
"-webkit-transition-property": "-webkit-transform"
"-webkit-transform-style": "preserve-3d"
_getPreserveHeight: (elem) ->
setTimeout =>
@preserveHeight = @clientHeight - $(elem).outerHeight() - 15
, 100
iphoneHack: () ->
setTimeout(scrollTo, 120, 0, 1) # iPhone hack
queue: []
onRotate: (elem) ->
window.onorientationchange = () =>
@_getClientHeight()
@_getPreserveHeight(elem)
@iphoneHack()
tagNameReg: new RegExp("select|input|textarea") # <a>タグは別処理のため除外
onTouch: (elem) ->
$(elem).bind "touchstart", (e) =>
target = e.target
if target.tagName.toLowerCase().match(@tagNameReg)
# @isInput = true
return true
# <a>タグ上をタップしたか判別
@isHref = @navigateHref(target)
e.preventDefault()
return if event.touches[1]?
touch = event.touches[0]
data = @_getTranslate(elem)
@startY = touch.pageY
@dataY = data.y
@isDrag = true
# タイマー内に touchmove したら解除
if @isHref
@tapTimer = setTimeout =>
window.location = @targetHref
, 130
# タッチ開始時にフルスクリーンになっていない場合
if document.documentElement.scrollTop is 0
@iphoneHack()
$(elem).bind "touchmove", (e) =>
clearTimeout(@tapTimer)
e.preventDefault()
return if event.touches[1]?
return unless @isDrag
touch = event.touches[0]
@dragY = touch.pageY
cache = { dragY: @dragY, dataY: @dataY, startY: @startY, preserveHeight: @preserveHeight}
@queue.push(@doScroll)
scroll = setTimeout =>
if @queue.length > 0
f = @queue.shift()
f(elem, cache, false)
, 84
$(elem).bind "touchend", (e) =>
e.preventDefault()
return if event.touches[1]?
cache = { dragY: @dragY, dataY: @dataY, startY: @startY, preserveHeight: @preserveHeight}
if @queue.length > 0
f = @queue.shift()
@queue = []
f(elem, cache, true)
@isDrag = false
navigateHref: (self) ->
if self.tagName is "A"
@targetHref = $(self).attr('href')
return true
a = $(self).parents("a")
if a.length is 0
return false
else
@targetHref = $(a[0]).attr('href')
return true
doScroll: (elem, cache, flg) ->
if flg is false
@prevStatus = flg
dy = cache.dragY - cache.startY
y = cache.dataY + dy
$(elem).css
"-webkit-transform": "translate3d(0px, #{y}px, 0px)"
"-webkit-transition-timing-function": "cubic-bezier(0, 0.75, 0.25, 1.0)"
"-webkit-transition-duration": "0ms"
else
dy = cache.dragY - cache.startY
time = "600ms"
if Math.abs(dy) > 150
time = "350ms"
ratio = 4.8
if @prevStatus isnt flg
@prevStatus = flg
ratio = 1.05
time = "700ms"
else
ratio = 4
y = cache.dataY + dy * ratio
if y > 100
y = 100
else if cache.preserveHeight - 100 > y
y = cache.preserveHeight - 100
$(elem).css
"-webkit-transform": "translate3d(0px, #{y}px, 0px)"
"-webkit-transition-timing-function": "cubic-bezier(0, 0.75, 0.25, 1.0)"
"-webkit-transition-duration": time
setTimeout ->
if y > 0
$(elem).css
"-webkit-transform": "translate3d(0px, 0px, 0px)"
"-webkit-transition-duration": "325ms"
"-webkit-transition-timing-function": "cubic-bezier(0.42, 0, 0.58, 1.0)"
else if cache.preserveHeight > y
$(elem).css
"-webkit-transform": "translate3d(0px, #{cache.preserveHeight}px, 0px)"
"-webkit-transition-duration": "325ms"
"-webkit-transition-timing-function": "cubic-bezier(0.42, 0, 0.58, 1.0)"
, 200
return
_getTranslate: (elem) ->
m = new WebKitCSSMatrix($(elem).css('-webkit-transform'))
return { x: parseInt(m.e, 10), y: parseInt(m.f, 10) }
$ ->
new iPhoneTouchScroll()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment