H5移動端開發基礎(三)自定義滾動條、實戰-音悅臺
自定義滾動條、實戰-音悅臺
自定義滾動條
*{margin: 0;padding: 0;}
body, html{height: 100%;overflow: hidden;}
#wrap{height: 100%;overflow: hidden;position: relative;}
#scrollBar {position: absolute;right: 0;top: 0;width: 4px;height: 100%;background: rgba(0,0,0,.5);opacity: 0;transition: .3s opacity;}
<div id="wrap">
<div id="scroll"></div>
<div id="scrollBar"></div>
</div>
window.onload = function(){
setInner();
var wrap = document.querySelector ('#wrap');
var scroll = document.querySelector('#scroll');
var bar = document.querySelector('#scrollBar');
var scale = wrap.clientHeight/scroll.offsetHeight;
bar.style.height = wrap.clientHeight*scale + 'px';
var callBack = {
start: function(){
// console.log('滑動開始之前要執行的函式');
bar.style.opacity = 1;
},
in: function(){
// console.log('滑動中執行的函式');
var top = -cssTransform(scroll, 'translateY')*scale;
cssTransform(bar, 'translateY', top);
},
over: function(){
// console.log('滑動結束之後要執行的函式');
bar.style.opacity = 0;
}
};
moveScroll(wrap, callBack);
}
function setInner(){
var scroll = document.querySelector('#scroll');
var inner = '';
for(var i=0; i<300; i++){
inner += '移動端事件互動' + i + '<br/>';
}
scroll.innerHTML = inner;
}
js封裝
transform.js
function cssTransform(el, attr, val){
if(!el.transform){
el.transform = {};
}
if(arguments.length>2){
el.transform[attr] = val;
// console.log(el.transform);
var sVal = '';
for(var s in el.transform){
switch(s){
case 'rotate':
case 'rotateX':
case 'rotateY':
case 'rotateZ':
case 'skewX':
case 'skewY':
sVal += s+'('+el.transform[s]+'deg) ';
break;
case 'translateX':
case 'translateY':
case 'translateZ':
sVal += s+'('+el.transform[s]+'px) ';
break;
case 'scaleX':
case 'scaleY':
case 'scale':
sVal += s+'('+el.transform[s]+') ';
break;
}
// console.log(sVal);
el.style.WebkitTransform = el.style.transform = sVal;
}
}else{
var val = el.transform[attr];
if(typeof val == 'undefined'){
if(['scale', 'scaleX', 'scaleY'].indexOf(attr)>-1){
val = 1;
}else{
val = 0;
}
}
return val;
}
}
tween.js
var Tween = (function(){
return {
/*
t:當前次數
b:起始值
c:起始值和目標點之間的差值
d:總次數
*/
easeOut: function(t, b, c, d){
return -c*((t=t/d-1)*t*t*t-1) + b;
},
backOut: function(t, b, c, d, s){
if(typeof s == 'undefined'){
s = 2.70158;
}
return c*((t=t/d-1)*t*((s+1)*t+s)+1)+b;
}
}
})();
scrollBar.js
function moveScroll(wrap, callBack){
var child = wrap.children[0];
var startPoint = 0;
var startY= 0;
var minY = wrap.clientHeight - child.offsetHeight;
var step = 1;
var lastY = 0;
var lastTime = 0;
var lastDis = 0;
var lastTimeDis = 1;
var isMove = true;
var isFirst = true;
cssTransform(child, 'translateZ', 0.01);
wrap.addEventListener('touchstart', function (e) {
// child.style.transition = 'none';
clearInterval(child.scroll);
if(callBack && callBack.start){
callBack.start();
}
startPoint = {pageX: e.changedTouches[0].pageX, pageY: e.changedTouches[0].pageY};
startY = cssTransform(child, 'translateY');
step = 1;
lastY = startPoint.pageY;
lastTime = new Date().getTime();
lastDis = 0;
lastTimeDis = 1;
isMove = true;
isFirst = true;
});
wrap.addEventListener('touchmove', function (e) {
if(!isMove){
return;
}
var nowPoint = {pageX: e.changedTouches[0].pageX, pageY: e.changedTouches[0].pageY};
var disX = nowPoint.pageX - startPoint.pageX;
var disY = nowPoint.pageY - startPoint.pageY;
var top = startY + disY;
if(isFirst){
isFirst = false;
if(Math.abs(disY) < Math.abs(disX)){
isMove = false;
return;
}
}
var nowTime = new Date().getTime();
if (top > 0) {
step = 1-top / wrap.clientHeight;
top = parseInt(top*step);
}
if (top < minY) {
var over = minY - top; // 計算下超出值
step = 1 - over / wrap.clientHeight; //根據超出值計算係數
over = parseInt(over * step);
top = minY - over;
}
// lastDis = top - lastY;
lastDis = nowPoint.pageY - lastY;
lastTimeDis = nowTime - lastTime;
// lastY = top;
lastY = nowPoint.pageY;
lastTime = nowTime;
cssTransform(child, 'translateY', top);
if(callBack && callBack.in){
callBack.in();
}
});
wrap.addEventListener('touchend', function (e) {
var speed = (lastDis / lastTimeDis) * 200;
speed = isNaN(speed) ? 0 : speed
var top = cssTransform(child, 'translateY');
var target = top + speed;
// var type = 'cubic-bezier(.34, 0.92, .58, .9)';
var type = 'easeOut';
var time = Math.abs(speed * 1.2);
time = time < 300 ? 300 : time;
if (target > 0) {
target = 0;
// type = 'cubic-bezier(.68, 1.31, .92, 1.2)';
type = 'backOut';
}
if (target < minY) {
target = minY;
// type = 'cubic-bezier(.68, 1.31, .92, 1.2)';
type = 'backOut';
}
// child.style.transition = time + 'ms ' + type;
move(target, time, type);
cssTransform(child, 'translateY', target);
});
function move(target, time, type){
var t = 0;
var b = cssTransform(child, 'translateY');
var c = target - b;
var d = Math.ceil(time/20);
clearInterval(child.scroll);
child.scroll = setInterval(function(){
t++;
if(t>d){
clearInterval(child.scroll);
if(callBack && callBack.over){
callBack.over();
}
}else{
var top = Tween[type](t, b, c, d);
cssTransform(child, 'translateY', top);
if(callBack && callBack.in){
callBack.in();
}
}
}, 20);
}
}
音悅臺
適配
<meta name="viewport" content="width=device-width, user-scalable=no"/>
<script type="text/javascript">
setRem();
window.addEventListener('orientationchange', setRem);
window.addEventListener("resize", setRem);
function setRem() {
var html = document.querySelector('html');
var width = html.getBoundingClientRect().width;
console.log(width)
html.style.fontSize = width / 16 + 'px';
}
</script>
樣式
body,h1,h2,h3,h4,h5,h6,p,dl,dd{margin:0;-webkit-text-size-adjust:100%;font-family:Helvetica;}
ul,ol{margin:0;padding:0;list-style:none;}
img{display:block;}
a{text-decoration:none;}
a,input,button{-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-appearance:none;outline:none;}
html,body{height:100%;position:relative;overflow:hidden;background:#eee;}
.wrap{height:100%;position:relative;overflow:hidden;}
#header{position:absolute;background:rgba(0,0,0,0.8);left:0;top:0;width:100%;z-index:2;}
.headerC{height:2rem;}
#logo{float:left;padding:0.38518519rem 0.25185185rem 0.31111111rem;}
#logo img{width:3.55555556rem;}
#menu-btn{float:left;width:1.91111111rem;height:2rem;background:url(../img/menuBtn.png) no-repeat;background-size:1.21481481rem 3.45185185rem;}
.menu-btn-show{background-position:center 0.23703704rem !important;}
.menu-btn-close{background-position:center -1.77777778rem !important;}
#btns{float:right;padding-top:0.31111111rem;}
#btns a{float:left;margin-right:0.22222222rem;width:1.64444444rem;height:1.15555556rem;background:#690;color:#ccc;font-size:0.59259259rem;line-height:1.15555556rem;text-align:center;border-radius:0.11851852rem;}
#btns .search-btn{font-weight:bold;color:#ffffff;margin-right:0.44444444rem;width:1.92592593rem;line-height:1.3037037rem;border-radius:0.14814815rem;}
.search{height:1.52592593rem;padding:0.23703704rem;}
.search input[type='search']{float:left;width:12.28148148rem;height:1.52592593rem;background:#999;padding:5px 10px;box-sizing:border-box;border:1px solid #5a5a5a;font-size:0.6rem;color:#333;border-radius:0.22222222rem 0 0 0.22222222rem;}
.search input[type='search']:focus{background:#fff;}
.search input[type='search']::-webkit-input-placeholder{color:#666;}
.search input[type='submit']{float:right;width:3.00740741rem;height:1.52592593rem;border:none;background:#414040;color:#fff;border-radius:0 0.22222222rem 0.22222222rem 0;font-size:0.77037037rem;}
#nav{position:absolute;width:100%;left:0;top:2rem;border-top:1px solid #414040;background:rgba(0,0,0,0.8);padding:0.14814815rem 0;display:none;}
#nav li{float:left;width:22.5%;line-height:2rem;font-size:0.8rem;text-align:center
相關推薦
H5移動端開發基礎(三)自定義滾動條、實戰-音悅臺
自定義滾動條、實戰-音悅臺
自定義滾動條
js封裝
transform.js
tween.js
scrollBar.js
音悅臺
適配
樣式
html
H5移動端開發基礎(四)多指操作、案例-相簿
多指操作、案例-相簿
多指操作
旋轉
縮放
實現安卓多指事件
案例-相簿
多指操作
// gesturestart:手指觸碰元素,螢幕上有兩個或兩個以上的手指
oBox.addEventListener
H5移動端開發基礎(二)適配、3D、animation
適配、3D、animation
適配
rem適配
getBoundingClientRect
viewport適配
橫豎屏適配
方法一
方法二
3D
H5移動端開發基礎(一)事件基礎
事件基礎
移動端基礎事件
滑屏原理
transform 與 transition
無縫滑屏自動播放幻燈片
移動端基礎事件
手指按下:touchstart <==> mousedown
手指擡起:touchend <
大數據入門第二十二天——spark(三)自定義分區、排序與查找
get buffer arr clas ron arm scala mut all 一、自定義分區
1.概述
默認的是Hash的分區策略,這點和Hadoop是類似的,具體的分區介紹,參見:https://blog.csdn.net/high2011/arti
微信公眾號開發整理(七)--自定義選單查詢、刪除
1.查詢選單:get請求方式2.在工具類中新增訪問get請求常量URL建立查詢選單方法:public static int createMenu(String token,String menu) throws ParseException, IOException{int
Python自動化運維開發----基礎(三)條件語句和迴圈語句
1.python中的條件和迴圈有哪些?
python中的迴圈和其他程式語言一樣,條件有if,迴圈有while、for
2.條件語句
條件語句的格式(1)有一個條件
if 條件:
執行語句1
else:
&
從Android原生角度看移動html5開發APP(三)之上拉載入
在mui框架中上拉載入其實很簡單了,框架已經幫助我們基本實現了。
mui的上拉載入和下拉重新整理類似,都屬於pullRefresh外掛,使用過程如下:
1、頁面滾動到底,顯示“正在載入...”提示(mui框架提供)
2、執行載入業務資料邏輯(開發者提供)
3、載入完畢,隱藏
Xamarin 跨移動端開發系列(01) -- 搭建環境、編譯、除錯、部署、執行
(本文是基於老版本的VS和Xamarin,而VS2017已經集成了Xamarin,所以,本文已經過時,最新的Xamarin開發介紹請參見 使用 Xamarin開發手機聊天程式 。)
如果是.NET開發人員,想學習手機應用開發(Android和iOS),Xamarin 無疑是最好的選擇,編寫一次,
Windows客戶端開發簡介(三)
之前的一篇文章裡,我簡單概要的介紹了一下介面庫的知識。既然是跟介面有關,那麼必然少不了很多關於繪製的內容。對於Windows開發而言,介面繪製使用的一類API就是所謂的“GDI”。
GDI這個東西可有歷史了,但是我們就不去追根朔源了。首先
Python 基礎(三)——流程控制之break 、continue 、else
sim 流程 tin rime con python 基礎 完整 .py gpo break
break 語句和 C 中的類似,用於跳出最近的一級 for 或 while 循環。
循環可以有一個 else 子句;它在循環叠代完整個列表(對於 for )或執行條件為 fals
flask web開發(三) 自定義錯誤頁面
#自定義錯誤頁面 @app.errorhandler(404) #請求未知頁面或未知路由 def page_not_found(e): return render_template('404.html'),404
@app.errorhandler(500
flume ng進擊之路 (三) —— 自定義source API開發
概述
關於flume ng的簡單介紹,可以參考flume ng進擊之路 (一)—— 入門,同時flume ng也提供了各種各樣的source和sink介面供我們在生成環境中使用,但是在生產環境中,我們常常需要定製的source或者sink來滿足我們的要求。
微信公眾平臺開發教程(五)自定義菜單
打開鏈接 delete toolbar 推送 優化 pcl reader 接口查詢 robot 應大家強烈要求,將自定義菜單功能課程提前。
一、概述:
如果只有輸入框,可能太簡單,感覺像命令行。自定義菜單,給我們提供了很大的靈活性,更符合用戶的操作習慣。在一個小小的微信對話
JS基礎(五)自定義函數
調用函數 pre 基礎 clas 自定義 語句 ... 全局 blog 作用:是為了讓重復使用的語句,方便進行調用。
定義格式:
function 自定義函數名 (參數1, 參數2,...) {
執行的語句
}
函數的封裝:把語句放到函數中去的過程。
參數:通過
(三)自定義Realm
ssi 定義 try time public getname tid vax getc
引入依賴
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/
EL表達式(三)自定義 EL 表達式
abd sun title contain tld sta 參數 func lns 自定義EL函數(靜態方法): 編寫步驟: 1.編寫一個Java類,提供一個靜態方法 import java.util.List; public class GetLength {
架構探險(三)自定義類載入器
今天我們來談一談架構探險中自定義的類載入器,一般我們若想實現自定義的類載入器,可以繼承ClassLoader類,然後實現findClass方法即可,詳細介紹可以看以下連結: https://www.cnblogs.com/doit8791/p/5820037.html
本文
如何使hexo顯得自己更有逼格(三)——自定義與優化
部落格地址: 黑境
優化策略
考慮到站點的穩定性和載入速度等,可以使用延遲載入圖片等方式提高響應速度。hexo還提供了一個最小化靜態檔案的外掛hexo-all-minifier可以壓縮html、css、js和影象檔案,刪除檔案中多餘的換行等。通過在
Unity動態編輯Terrain(三) 自定義筆刷
****
程式碼我已經上傳到了我的Github上,需要的話可以直接去下載https://github.com/xdedzl/xdedzl,裡面有一個TerrainModilfyDemo的場景,我做了一個簡單的UI用來測試,工程版本是2018.3。注意編譯環境需要是.net4.x,用3.5會報錯。