为nuclear扩展scrollToTop

This commit is contained in:
张磊 2015-07-03 17:56:57 +08:00
parent e7bf535ed7
commit 360ee2b06a
4 changed files with 349 additions and 7 deletions

173
dist/nuclear.js vendored
View File

@ -17,11 +17,13 @@
}(this, function () {
/* paste from Zepto v1.1.6 -
contain zepto,event and touch modules
contain zepto,event and touch ajax fx modules
https://github.com/madrobby/zepto/blob/master/src/zepto.js
https://github.com/madrobby/zepto/blob/master/src/event.js
https://github.com/madrobby/zepto/blob/master/src/touch.js
https://github.com/madrobby/zepto/blob/master/src/ajax.js
https://github.com/madrobby/zepto/blob/master/src/fx.js
https://gist.github.com/madrobby/8507960#file-scrolltotop-js
*/
var Nuclear = (function () {
@ -1739,6 +1741,175 @@ var Nuclear = (function () {
return params.join('&').replace(/%20/g, '+')
}
})(Nuclear)
; (function ($, undefined) {
var prefix = '', eventPrefix,
vendors = { Webkit: 'webkit', Moz: '', O: 'o' },
testEl = document.createElement('div'),
supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,
transform,
transitionProperty, transitionDuration, transitionTiming, transitionDelay,
animationName, animationDuration, animationTiming, animationDelay,
cssReset = {}
function dasherize(str) { return str.replace(/([a-z])([A-Z])/, '$1-$2').toLowerCase() }
function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : name.toLowerCase() }
$.each(vendors, function (vendor, event) {
if (testEl.style[vendor + 'TransitionProperty'] !== undefined) {
prefix = '-' + vendor.toLowerCase() + '-'
eventPrefix = event
return false
}
})
transform = prefix + 'transform'
cssReset[transitionProperty = prefix + 'transition-property'] =
cssReset[transitionDuration = prefix + 'transition-duration'] =
cssReset[transitionDelay = prefix + 'transition-delay'] =
cssReset[transitionTiming = prefix + 'transition-timing-function'] =
cssReset[animationName = prefix + 'animation-name'] =
cssReset[animationDuration = prefix + 'animation-duration'] =
cssReset[animationDelay = prefix + 'animation-delay'] =
cssReset[animationTiming = prefix + 'animation-timing-function'] = ''
$.fx = {
off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined),
speeds: { _default: 400, fast: 200, slow: 600 },
cssPrefix: prefix,
transitionEnd: normalizeEvent('TransitionEnd'),
animationEnd: normalizeEvent('AnimationEnd')
}
$.fn.animate = function (properties, duration, ease, callback, delay) {
if ($.isFunction(duration))
callback = duration, ease = undefined, duration = undefined
if ($.isFunction(ease))
callback = ease, ease = undefined
if ($.isPlainObject(duration))
ease = duration.easing, callback = duration.complete, delay = duration.delay, duration = duration.duration
if (duration) duration = (typeof duration == 'number' ? duration :
($.fx.speeds[duration] || $.fx.speeds._default)) / 1000
if (delay) delay = parseFloat(delay) / 1000
return this.anim(properties, duration, ease, callback, delay)
}
$.fn.anim = function (properties, duration, ease, callback, delay) {
var key, cssValues = {}, cssProperties, transforms = '',
that = this, wrappedCallback, endEvent = $.fx.transitionEnd,
fired = false
if (duration === undefined) duration = $.fx.speeds._default / 1000
if (delay === undefined) delay = 0
if ($.fx.off) duration = 0
if (typeof properties == 'string') {
// keyframe animation
cssValues[animationName] = properties
cssValues[animationDuration] = duration + 's'
cssValues[animationDelay] = delay + 's'
cssValues[animationTiming] = (ease || 'linear')
endEvent = $.fx.animationEnd
} else {
cssProperties = []
// CSS transitions
for (key in properties)
if (supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') '
else cssValues[key] = properties[key], cssProperties.push(dasherize(key))
if (transforms) cssValues[transform] = transforms, cssProperties.push(transform)
if (duration > 0 && typeof properties === 'object') {
cssValues[transitionProperty] = cssProperties.join(', ')
cssValues[transitionDuration] = duration + 's'
cssValues[transitionDelay] = delay + 's'
cssValues[transitionTiming] = (ease || 'linear')
}
}
wrappedCallback = function (event) {
if (typeof event !== 'undefined') {
if (event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below"
$(event.target).unbind(endEvent, wrappedCallback)
} else
$(this).unbind(endEvent, wrappedCallback) // triggered by setTimeout
fired = true
$(this).css(cssReset)
callback && callback.call(this)
}
if (duration > 0) {
this.bind(endEvent, wrappedCallback)
// transitionEnd is not always firing on older Android phones
// so make sure it gets fired
setTimeout(function () {
if (fired) return
wrappedCallback.call(that)
}, ((duration + delay) * 1000) + 25)
}
// trigger page reflow so new elements can animate
this.size() && this.get(0).clientLeft
this.css(cssValues)
if (duration <= 0) setTimeout(function () {
that.each(function () { wrappedCallback.call(this) })
}, 0)
return this
}
testEl = null
})(Nuclear)
; (function ($) {
var scrollToTopInProgress = false
$.fn.scrollToTop = function (position) {
var $this = this,
targetY = position || 0,
initialY = $this.scrollTop(),
lastY = initialY,
delta = targetY - initialY,
speed = Math.min(750, Math.min(1500, Math.abs(initialY - targetY))),
start, t, y, frame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) { setTimeout(callback, 15) },
cancelScroll = function () { abort() }
if (scrollToTopInProgress) return
if (delta == 0) return
function smooth(pos) {
if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 5)
return 0.5 * (Math.pow((pos - 2), 5) + 2)
}
function abort() {
$this.off('touchstart', cancelScroll)
scrollToTopInProgress = false
}
$this.on('touchstart', cancelScroll)
scrollToTopInProgress = true
frame(function render(now) {
if (!scrollToTopInProgress) return
if (!start) start = now
t = Math.min(1, Math.max((now - start) / speed, 0))
y = Math.round(initialY + delta * smooth(t))
if (delta > 0 && y > targetY) y = targetY
if (delta < 0 && y < targetY) y = targetY
if (lastY != y) $this.scrollTop(y)
lastY = y
if (y !== targetY) frame(render)
else abort()
})
}
})(Nuclear)
Nuclear.create = function (obj) {
Nuclear._mixObj(obj);
if (!obj.statics) obj.statics = {};

4
dist/nuclear.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -47,7 +47,7 @@
}
</style>
</head>
<body style="height:1000px;">
<body style="height:2000px;">
<!--<div class="nc-nav" style="width: 100%; height: 10px; position: absolute;">
<a></a>
<a></a>
@ -57,7 +57,7 @@
<script type="text/javascript">
var Nav = $.create({
scrollTo: function (top) {
$("html,body").scrollTop(top);
$("body").scrollToTop(top);
},
render: function () {
var i = 0, len = this.option.positions.length, pec = 100 / len, linkStr = "";
@ -69,7 +69,7 @@
return '<div class="nc-nav">' + linkStr + '</div>';
}
})
new Nav({ index: 2, positions: [100, 200, 300, 400, 500, 1200, 1200, 1200, 1200, 1200] }, "body");
new Nav({ index: 2, positions: [100, 500, 1000, 1500, 500, 1200, 1200, 1200, 1200, 1200] }, "body");
</script>
<a href="https://github.com/AlloyTeam/Nuclear" target="_blank" style="position: absolute; right: 0; top: 0;">
<img src="http://alloyteam.github.io/AlloyRenderingEngine/asset/img/github.png" alt="" />

View File

@ -1,9 +1,11 @@
/* paste from Zepto v1.1.6 -
contain zepto,event and touch modules
contain zepto,event and touch ajax fx modules
https://github.com/madrobby/zepto/blob/master/src/zepto.js
https://github.com/madrobby/zepto/blob/master/src/event.js
https://github.com/madrobby/zepto/blob/master/src/touch.js
https://github.com/madrobby/zepto/blob/master/src/ajax.js
https://github.com/madrobby/zepto/blob/master/src/fx.js
https://gist.github.com/madrobby/8507960#file-scrolltotop-js
*/
var Nuclear = (function () {
@ -1720,4 +1722,173 @@ var Nuclear = (function () {
serialize(params, obj, traditional)
return params.join('&').replace(/%20/g, '+')
}
})(Nuclear)
; (function ($, undefined) {
var prefix = '', eventPrefix,
vendors = { Webkit: 'webkit', Moz: '', O: 'o' },
testEl = document.createElement('div'),
supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,
transform,
transitionProperty, transitionDuration, transitionTiming, transitionDelay,
animationName, animationDuration, animationTiming, animationDelay,
cssReset = {}
function dasherize(str) { return str.replace(/([a-z])([A-Z])/, '$1-$2').toLowerCase() }
function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : name.toLowerCase() }
$.each(vendors, function (vendor, event) {
if (testEl.style[vendor + 'TransitionProperty'] !== undefined) {
prefix = '-' + vendor.toLowerCase() + '-'
eventPrefix = event
return false
}
})
transform = prefix + 'transform'
cssReset[transitionProperty = prefix + 'transition-property'] =
cssReset[transitionDuration = prefix + 'transition-duration'] =
cssReset[transitionDelay = prefix + 'transition-delay'] =
cssReset[transitionTiming = prefix + 'transition-timing-function'] =
cssReset[animationName = prefix + 'animation-name'] =
cssReset[animationDuration = prefix + 'animation-duration'] =
cssReset[animationDelay = prefix + 'animation-delay'] =
cssReset[animationTiming = prefix + 'animation-timing-function'] = ''
$.fx = {
off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined),
speeds: { _default: 400, fast: 200, slow: 600 },
cssPrefix: prefix,
transitionEnd: normalizeEvent('TransitionEnd'),
animationEnd: normalizeEvent('AnimationEnd')
}
$.fn.animate = function (properties, duration, ease, callback, delay) {
if ($.isFunction(duration))
callback = duration, ease = undefined, duration = undefined
if ($.isFunction(ease))
callback = ease, ease = undefined
if ($.isPlainObject(duration))
ease = duration.easing, callback = duration.complete, delay = duration.delay, duration = duration.duration
if (duration) duration = (typeof duration == 'number' ? duration :
($.fx.speeds[duration] || $.fx.speeds._default)) / 1000
if (delay) delay = parseFloat(delay) / 1000
return this.anim(properties, duration, ease, callback, delay)
}
$.fn.anim = function (properties, duration, ease, callback, delay) {
var key, cssValues = {}, cssProperties, transforms = '',
that = this, wrappedCallback, endEvent = $.fx.transitionEnd,
fired = false
if (duration === undefined) duration = $.fx.speeds._default / 1000
if (delay === undefined) delay = 0
if ($.fx.off) duration = 0
if (typeof properties == 'string') {
// keyframe animation
cssValues[animationName] = properties
cssValues[animationDuration] = duration + 's'
cssValues[animationDelay] = delay + 's'
cssValues[animationTiming] = (ease || 'linear')
endEvent = $.fx.animationEnd
} else {
cssProperties = []
// CSS transitions
for (key in properties)
if (supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') '
else cssValues[key] = properties[key], cssProperties.push(dasherize(key))
if (transforms) cssValues[transform] = transforms, cssProperties.push(transform)
if (duration > 0 && typeof properties === 'object') {
cssValues[transitionProperty] = cssProperties.join(', ')
cssValues[transitionDuration] = duration + 's'
cssValues[transitionDelay] = delay + 's'
cssValues[transitionTiming] = (ease || 'linear')
}
}
wrappedCallback = function (event) {
if (typeof event !== 'undefined') {
if (event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below"
$(event.target).unbind(endEvent, wrappedCallback)
} else
$(this).unbind(endEvent, wrappedCallback) // triggered by setTimeout
fired = true
$(this).css(cssReset)
callback && callback.call(this)
}
if (duration > 0) {
this.bind(endEvent, wrappedCallback)
// transitionEnd is not always firing on older Android phones
// so make sure it gets fired
setTimeout(function () {
if (fired) return
wrappedCallback.call(that)
}, ((duration + delay) * 1000) + 25)
}
// trigger page reflow so new elements can animate
this.size() && this.get(0).clientLeft
this.css(cssValues)
if (duration <= 0) setTimeout(function () {
that.each(function () { wrappedCallback.call(this) })
}, 0)
return this
}
testEl = null
})(Nuclear)
; (function ($) {
var scrollToTopInProgress = false
$.fn.scrollToTop = function (position) {
var $this = this,
targetY = position || 0,
initialY = $this.scrollTop(),
lastY = initialY,
delta = targetY - initialY,
speed = Math.min(750, Math.min(1500, Math.abs(initialY - targetY))),
start, t, y, frame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) { setTimeout(callback, 15) },
cancelScroll = function () { abort() }
if (scrollToTopInProgress) return
if (delta == 0) return
function smooth(pos) {
if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 5)
return 0.5 * (Math.pow((pos - 2), 5) + 2)
}
function abort() {
$this.off('touchstart', cancelScroll)
scrollToTopInProgress = false
}
$this.on('touchstart', cancelScroll)
scrollToTopInProgress = true
frame(function render(now) {
if (!scrollToTopInProgress) return
if (!start) start = now
t = Math.min(1, Math.max((now - start) / speed, 0))
y = Math.round(initialY + delta * smooth(t))
if (delta > 0 && y > targetY) y = targetY
if (delta < 0 && y < targetY) y = targetY
if (lastY != y) $this.scrollTop(y)
lastY = y
if (y !== targetY) frame(render)
else abort()
})
}
})(Nuclear)