1、依赖
a、jQuery
b、angularjs
2、page.js文件
1 var Page = function (options) { 2 var myApp = angular.module('myApp', []); 3 myApp.controller('myCtrl', function ($scope) { 4 $scope.setData = function (obj) { 5 for (let key in obj) { 6 var contains = false; 7 for (var i = 0; i < $scope.$$watchers.length; i++) { 8 if ($scope.$$watchers[i].exp == key) { 9 contains = true; 10 break; 11 } 12 } 13 if (!contains) { 14 $scope.$watch(key, function (newValue) { 15 options.data[key] = newValue; 16 }, true) 17 } 18 eval("$scope." + key + "=obj[key]"); 19 } 20 $scope.$applyAsync(); 21 } 22 }); 23 const { 24 onLoad, 25 onReady, 26 onPullDownRefresh, 27 onReachBottom, 28 onPageScroll 29 } = options; 30 options.onLoad = function (obj) { 31 options.setData(this.data); 32 onLoad && onLoad.call(this, obj) 33 } 34 options.onReady = function (opts) { 35 onReady && onReady.call(this, opts) 36 } 37 options.onPullDownRefresh = function (opts) { 38 onPullDownRefresh && onPullDownRefresh.call(this, opts) 39 } 40 options.stopPullDownRefresh = function () { 41 clearTimeout(__navAnimateGoTopTimeout); 42 $("#TheStatusRefresh").stop().animate({ top: "-40px" }, "fast", function () { 43 __navAnimatelock = false; 44 $("#TheStatusRefresh img").removeClass("route"); 45 }); 46 } 47 options.onReachBottom = function (opts) { 48 onReachBottom && onReachBottom.call(this, opts) 49 } 50 options.onPageScroll = function (opts) { 51 onPageScroll && onPageScroll.call(this, opts) 52 } 53 options.setData = function (obj) { 54 for (let key in obj) { 55 eval("options.data." + key + "=obj[key]"); 56 } 57 var appElement = document.querySelector("[ng-controller=myCtrl]"); 58 var $scope = angular.element(appElement).scope(); 59 var fun = $scope.$eval("setData"); 60 fun(obj); 61 }; 62 63 var __disY, __startY, __endY; 64 var __navAnimatelock = false; 65 var __navAnimateGoTopTimeout; 66 var GetParamsToJson = function () { 67 var obj = {}; 68 var url = $(location).attr('href'); 69 if (url.indexOf("?") == -1) { 70 return {}; 71 } 72 var arr = decodeURI(url).split("?")[1].split("&") 73 for (var i = 0; i < arr.length; i++) { 74 obj[arr[i].split("=")[0]] = unescape(arr[i].split("=")[1]); 75 } 76 return obj; 77 } 78 79 window.onload = function () { 80 var opts = GetParamsToJson(); 81 options.onReady(opts); 82 } 83 $(document).ready(function () { 84 var opts = GetParamsToJson(); 85 options.onLoad(opts); 86 $("body").on("click", "[click]", function () { 87 var func = $(this).attr("click"); 88 if (options.hasOwnProperty(func)) { 89 options[func](this); 90 } 91 }); 92 }); 93 $(window).scroll(function (e) { 94 var scrollTop = $(this).scrollTop(); 95 var viewH = $(this).height(); 96 var contentH = $(document).height(); 97 if (contentH - viewH - scrollTop <= 1) { 98 options.onReachBottom(); 99 } 100 options.onPageScroll({ scrollTop: scrollTop }); 101 }); 102 103 if (onPullDownRefresh) { 104 $(document).on('touchstart', function (e) { 105 if (__navAnimatelock) { 106 return; 107 } 108 var scrollTop = $(this).scrollTop(); 109 __startY = e.originalEvent.changedTouches[0].pageY - scrollTop; 110 }); 111 $(document).on('touchmove', function (e) { 112 if (__navAnimatelock) { 113 return; 114 } 115 var scrollTop = $(this).scrollTop(); 116 __endY = e.originalEvent.changedTouches[0].pageY; 117 __disY = __endY - __startY - scrollTop; 118 if (scrollTop > 0) { 119 return; 120 } 121 $("body").addClass("StaticBody"); 122 if (__disY > -40 && __disY < 140) { 123 $('#TheStatusRefresh').css({ 124 top: -40 + __disY + 'px', 125 }); 126 } 127 else if (__disY >= 140) { 128 $('#TheStatusRefresh').css({ 129 top: 140 - 40 + 'px', 130 }); 131 } 132 else { 133 $('#TheStatusRefresh').css({ 134 top: -40 + 'px', 135 }); 136 } 137 }); 138 $(document).on('touchend', function (e) { 139 if (__navAnimatelock) { 140 return; 141 } 142 $("body").removeClass("StaticBody"); 143 var scrollTop = $(this).scrollTop(); 144 __endY = e.originalEvent.changedTouches[0].pageY; 145 __disY = __endY - __startY - scrollTop; 146 if (scrollTop > 0) { 147 return; 148 } 149 if (__disY >= 70) { 150 __navAnimatelock = true; 151 $("#TheStatusRefresh").stop().animate({ top: "40px" }, "fast", function () { 152 __navAnimatelock = true; 153 $("#TheStatusRefresh img").addClass("route"); 154 options.onPullDownRefresh(); 155 __navAnimateGoTopTimeout = setTimeout(function () { 156 options.stopPullDownRefresh(); 157 }, 3000); 158 }); 159 } 160 else { 161 __navAnimatelock = true; 162 options.stopPullDownRefresh(); 163 } 164 }); 165 } 166 }
a:onPullDownRefresh
有个下拉动画
3、页面
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 5 <meta http-equiv="Cache-Control" content="no-transform"> 6 <meta http-equiv="Cache-Control" content="no-siteapp"> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0"> 8 <meta content="black" name="apple-mobile-web-app-status-bar-style"> 9 <meta content="yes" name="apple-mobile-web-app-capable"> 10 <link href="page.css" rel="stylesheet" /> 11 </head> 12 <body ng-controller="myCtrl" ng-app="myApp"> 13 <div style="100px;height:2000px;" > 14 <p ng-bind="name" click="test" style="height:100px;100px;background-color:pink"></p> 15 </div> 16 <script src="jquery.js"></script> 17 <script src="angular.js"></script> 18 <script src="page.js"></script> 19 </body> 20 </html>
4、使用
Page({
data: {
name: '张三',
age: 1
},
onLoad: function (options) {
console.log("onLoad", options)
this.myFun1();
},
onReady: function () {
this.setData({
age: 222
});
console.log("onReady")
},
onReachBottom: function () {
console.log("onReachBottom")
},
myFun1: function () {
console.log('myFun1')
},
test: function (e) {
this.stopPullDownRefresh();
},
onPullDownRefresh: function () {
console.log(123)
}
})
a:绑定事件使用 click="方法名",其他事件可自行扩展
b:设置属性也跟微信一致,使用setData,直接给this.data.list赋值无效
c:onload方法的参数为当前页面地址栏参数转成的对象
5、用到的css
1 [click] { 2 cursor: pointer; 3 } 4 5 .StaticBody { 6 position: absolute; 7 overflow: hidden; 8 } 9 10 #TheStatusRefresh { 11 height: 40px; 12 width: 40px; 13 background: white; 14 position: fixed; 15 top: -40px; 16 border-radius: 100%; 17 left: calc(50% - 20px); 18 border: 1px solid #efefef; 19 padding: 9px; 20 } 21 22 #TheStatusRefresh img { 23 width: 20px; 24 height: 20px; 25 } 26 27 #TheStatusRefresh img.route { 28 -webkit-transition-property: -webkit-transform; 29 -webkit-transition-duration: 0.8s; 30 -moz-transition-property: -moz-transform; 31 -moz-transition-duration: 0.8s; 32 -webkit-animation: refresh_rotate 0.8s linear infinite; 33 -moz-animation: refresh_rotate 0.8s linear infinite; 34 -o-animation: refresh_rotate 0.8s linear infinite; 35 animation: refresh_rotate 0.8s linear infinite; 36 } 37 38 @@-webkit-keyframes refresh_rotate { 39 from { 40 -webkit-transform: rotate(0deg) 41 } 42 43 to { 44 -webkit-transform: rotate(360deg) 45 } 46 } 47 48 @@-moz-keyframes refresh_rotate { 49 from { 50 -moz-transform: rotate(0deg) 51 } 52 53 to { 54 -moz-transform: rotate(359deg) 55 } 56 } 57 58 @@-o-keyframes refresh_rotate { 59 from { 60 -o-transform: rotate(0deg) 61 } 62 63 to { 64 -o-transform: rotate(359deg) 65 } 66 } 67 68 @@keyframes refresh_rotate { 69 from { 70 transform: rotate(0deg) 71 } 72 73 to { 74 transform: rotate(359deg) 75 } 76 }
仅此记录一下