<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Zepto.scroll</title> <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"/> <style> body {margin:0;padding:0;} .box {width:400px;height:600px;margin:20px auto;border:1px solid #ccc;overflow-y:auto;} .btn-scroll {width:30px;height:30px;position:absolute;left:50%;top:200px;margin-left:160px;text-align:center;line-height:15px;background-color:#666;color:#fff;text-decoration:none;font-size:30px;} .btn-scroll:before {width:0;height:0;content:"";display:inline-block;border:7px solid transparent;border-bottom-color:#fff;} </style> </head> <body> <div class="box"> <p>0001</p> <p>0002</p> <p>0003</p> <p>0004</p> <p>0005</p> <p>0006</p> <p>0007</p> <p>0008</p> <p>0009</p> <p>0010</p> <p>0011</p> <p>0012</p> <p>0013</p> <p>0014</p> <p>0015</p> <p>0016</p> <p>0017</p> <p>0018</p> <p>0019</p> <p>0020</p> <p>0021</p> <p>0022</p> <p>0023</p> <p>0024</p> <p>0025</p> <p>0026</p> <p>0027</p> <p>0028</p> <p>0029</p> <p>0030</p> <p>0031</p> <p>0032</p> <p>0033</p> <p>0034</p> <p>0035</p> <p>0036</p> <p>0037</p> <p>0038</p> <p>0039</p> <p>0040</p> <p>0041</p> <p>0042</p> <p>0043</p> <p>0044</p> <p>0045</p> <p>0046</p> <p>0047</p> <p>0048</p> <p>0049</p> <p>0050</p> <p>0051</p> <p>0052</p> <p>0053</p> <p>0054</p> <p>0055</p> <p>0056</p> <p>0057</p> <p>0058</p> <p>0059</p> <p>0060</p> <p>0061</p> <p>0062</p> <p>0063</p> <p>0064</p> <p>0065</p> <p>0066</p> <p>0067</p> <p>0068</p> <p>0069</p> <p>0070</p> <p>0071</p> <p>0072</p> <p>0073</p> <p>0074</p> <p>0075</p> <p>0076</p> <p>0077</p> <p>0078</p> <p>0079</p> <p>0080</p> <p>0081</p> <p>0082</p> <p>0083</p> <p>0084</p> <p>0085</p> <p>0086</p> <p>0087</p> <p>0088</p> <p>0089</p> <p>0090</p> <p>0091</p> <p>0092</p> <p>0093</p> <p>0094</p> <p>0095</p> <p>0096</p> <p>0097</p> <p>0098</p> <p>0099</p> <p>0100</p> <p>0101</p> <p>0102</p> <p>0103</p> <p>0104</p> <p>0105</p> <p>0106</p> <p>0107</p> <p>0108</p> <p>0109</p> <p>0110</p> <p>0111</p> <p>0112</p> <p>0113</p> <p>0114</p> <p>0115</p> <p>0116</p> <p>0117</p> <p>0118</p> <p>0119</p> <p>0120</p> <p>0121</p> <p>0122</p> <p>0123</p> <p>0124</p> <p>0125</p> <p>0126</p> <p>0127</p> <p>0128</p> <p>0129</p> <p>0130</p> <p>0131</p> <p>0132</p> <p>0133</p> <p>0134</p> <p>0135</p> <p>0136</p> <p>0137</p> <p>0138</p> <p>0139</p> <p>0140</p> <p>0141</p> <p>0142</p> <p>0143</p> <p>0144</p> <p>0145</p> <p>0146</p> <p>0147</p> <p>0148</p> <p>0149</p> <p>0150</p> <p>0151</p> <p>0152</p> <p>0153</p> <p>0154</p> <p>0155</p> <p>0156</p> <p>0157</p> <p>0158</p> <p>0159</p> <p>0160</p> <p>0161</p> <p>0162</p> <p>0163</p> <p>0164</p> <p>0165</p> <p>0166</p> <p>0167</p> <p>0168</p> <p>0169</p> <p>0170</p> <p>0171</p> <p>0172</p> <p>0173</p> <p>0174</p> <p>0175</p> <p>0176</p> <p>0177</p> <p>0178</p> <p>0179</p> <p>0180</p> <p>0181</p> <p>0182</p> <p>0183</p> <p>0184</p> <p>0185</p> <p>0186</p> <p>0187</p> <p>0188</p> <p>0189</p> <p>0190</p> <p>0191</p> <p>0192</p> <p>0193</p> <p>0194</p> <p>0195</p> <p>0196</p> <p>0197</p> <p>0198</p> <p>0199</p> <p>0200</p> </div> <a href="javascript:;" class="btn-scroll"></a> <script src="http://zeptojs.com/zepto.min.js"></script> <script> ;(function($) { var DEFAULTS = { endY: 0, duration: 200, updateRate: 15 }; var interpolate = function (source, target, shift) { return (source + (target - source) * shift); }; var easing = function (pos) { return (-Math.cos(pos * Math.PI) / 2) + .5; }; var scroll = function(settings) { var options = $.extend({}, DEFAULTS, settings); if (options.duration === 0) { window.scrollTo(0, options.endY); if (typeof options.callback === 'function') options.callback(); return; } var startY = window.pageYOffset, startT = Date.now(), finishT = startT + options.duration; var animate = function() { var now = Date.now(), shift = (now > finishT) ? 1 : (now - startT) / options.duration; window.scrollTo(0, interpolate(startY, options.endY, easing(shift))); if (now < finishT) { setTimeout(animate, options.updateRate); } else { if (typeof options.callback === 'function') options.callback(); } }; animate(); }; var scrollNode = function(settings) { var options = $.extend({}, DEFAULTS, settings); if (options.duration === 0) { this.scrollTop = options.endY; if (typeof options.callback === 'function') options.callback(); return; } var startY = this.scrollTop, startT = Date.now(), finishT = startT + options.duration, _this = this; var animate = function() { var now = Date.now(), shift = (now > finishT) ? 1 : (now - startT) / options.duration; _this.scrollTop = interpolate(startY, options.endY, easing(shift)); if (now < finishT) { setTimeout(animate, options.updateRate); } else { if (typeof options.callback === 'function') options.callback(); } }; animate(); }; $.scrollTo = scroll; $.fn.scrollTo = function() { if (this.length) { var args = arguments; this.forEach(function(elem, index) { scrollNode.apply(elem, args); }); } }; }(Zepto)); </script> <script> $(".btn-scroll").on("click", function(e) { $(".box").scrollTo({ endY: $(".box p").eq(99).offset().top, duration: 200, callback: function() { // } }); }); </script> </body> </html>
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Zepto.scrollto</title> <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"/> <style type="text/css"> .wrap {overflow:auto;width:500px;height:400px;border:2px solid red;} .box {width:100%;overflow-y:auto;} </style> </head> <body> <div class="wrap"> <div class="box"> <p>0001 </p> <p>0002 </p> <p>0003 </p> <p>0004 </p> <p>0005 </p> <p>0006 </p> <p>0007 </p> <p>0008 </p> <p>0009 </p> <p>0010 </p> <p>0011 </p> <p>0012 </p> <p>0013 </p> <p>0014 </p> <p>0015 </p> <p>0016 </p> <p>0017 </p> <p>0018 </p> <p>0019 </p> <p>0020 </p> <p>0021 </p> <p>0022 </p> <p>0023 </p> <p>0024 </p> <p>0025 </p> <p>0026 </p> <p>0027 </p> <p>0028 </p> <p>0029 </p> <p>0030 </p> <p>0031 </p> <p>0032 </p> <p>0033 </p> <p>0034 </p> <p>0035 </p> <p>0036 </p> <p>0037 </p> <p>0038 </p> <p>0039 </p> <p>0040 </p> <p>0041 </p> <p>0042 </p> <p>0043 </p> <p>0044 </p> <p>0045 </p> <p>0046 </p> <p>0047 </p> <p>0048 </p> <p>0049 </p> <p>0050 </p> <p>0051 </p> <p>0052 </p> <p>0053 </p> <p>0054 </p> <p>0055 </p> <p>0056 </p> <p>0057 </p> <p>0058 </p> <p>0059 </p> <p>0060 </p> <p>0061 </p> <p>0062 </p> <p>0063 </p> <p>0064 </p> <p>0065 </p> <p>0066 </p> <p>0067 </p> <p>0068 </p> <p>0069 </p> <p>0070 </p> <p>0071 </p> <p>0072 </p> <p>0073 </p> <p>0074 </p> <p>0075 </p> <p>0076 </p> <p>0077 </p> <p>0078 </p> <p>0079 </p> <p>0080 </p> <p>0081 </p> <p>0082 </p> <p>0083 </p> <p>0084 </p> <p>0085 </p> <p>0086 </p> <p>0087 </p> <p>0088 </p> <p>0089 </p> <p>0090 </p> <p>0091 </p> <p>0092 </p> <p>0093 </p> <p>0094 </p> <p>0095 </p> <p>0096 </p> <p>0097 </p> <p>0098 </p> <p>0099 </p> <p>0100 </p> </div> </div> <script src="http://zeptojs.com/zepto.min.js"></script> <script> ;(function($){ $.extend($.fn, { scrollto: function(m){ var n = 0, timer = null, that = this; var smoothScroll = function(m){ var per = Math.round(m / 50); n = n + per; if(n > m){ clearInterval(timer); return false; } that.scrollTop(n); }; timer = setInterval(function(){ smoothScroll(m); }, 20); } }) })(Zepto); $(".wrap").on("click", function(){ $(".wrap").scrollto(2000); }); </script> </body> </html>
;(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() }) } })(Zepto)