日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

手机html滚动原理,手机滚动-如何实现惯性滚动

發(fā)布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手机html滚动原理,手机滚动-如何实现惯性滚动 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

手機慣性滾動時應(yīng)該怎么計算速度,以及之后速度怎么遞減等問題

因為要做一個手機端的滾動插件,所以想模擬出手機原生的慣性滾動,就是手指快速滑動后,手機頁面在手指抬起來之后,依然會滾動一段距離的效果。

現(xiàn)在我嘗試了兩種方法

1、在手指start與end之間時間少于300ms時,根據(jù)手指移動距離得出需要繼續(xù)滾動的長度,在end之后通過transition與top實現(xiàn)動畫效果

2、在手指end之后通過手指的移動距離與使用時間計算平局速度,如果使用時間少于300ms,則通過requestAnimationFrame循環(huán)調(diào)用一個每次都遞減速度的函數(shù),當(dāng)速度很小時跳出函數(shù)循環(huán)。在函數(shù)中每一次都設(shè)置一次top值,因為requestAnimationFrame間隔很短,大概之后16ms左右,以實現(xiàn)效果

第一種方法代碼

移動手指事件滾動

* {

margin: 0;

padding: 0;

}

.container {

position: relative;

margin: 50px;

width: calc(100% - 100px);

height: 400px;

border: 1px solid green;

box-sizing: border-box;

overflow: hidden;

}

.container .scroll {

position: absolute;

top: 0;

left: 0;

width: 100%;

transition: all 160ms ease-out;

}

.container p {

margin: 0 auto 10px;

width: 80%;

height: 80px;

border: 1px solid yellow;

}

.container .scroll:after {

content: '';

display: block;

clear: both;

}

.container .barBox {

position: absolute;

right: 2px;

top: 2px;

width: 3px;

height: calc(100% - 4px);

background: rgba(100, 200, 100, 0.3);

}

.container .barBox .bar {

position: absolute;

top: 0;

right: 0;

height: 0;

width: 100%;

background: #ccc;

transition: all 160ms ease-out;

}

var oContainer = document.getElementById('container');

var oScroll = oContainer.children[0];

var oBarBox = document.getElementById('barBox');

var oBar = oBarBox.children[0];

// 盒子尺寸

var iWrapperH = numberPx(getStyle(oContainer, 'height'));

var iScrollH = numberPx(getStyle(oScroll, 'height'));

var iBarBoxH = numberPx(getStyle(oBarBox, 'height'));

var iBarH = iWrapperH / iScrollH * iBarBoxH;

// 初始狀態(tài)

setStyle(oBar, {

height: iBarH + 'px'

})

// 參數(shù)

var startTime = 0;

var endTime = 0;

var isMove = false;

var iScrollTop = 0;

var iBarTop = 0;

var endTimeout = null;

oContainer.addEventListener('touchstart', function (e) {

startTime = new Date().getTime();

var startY = e.targetTouches[0].clientY;

var startTop = numberPx(getStyle(oScroll, 'top'));

var endY = startY;

var endTop = startTop;

setStyle(oScroll, {

top: startTop + 'px'

})

setStyle(oBar, {

top: -startTop / iScrollH * iBarBoxH + 'px'

})

var moveFn = function (e) {

isMove = true;

var nowY = e.targetTouches[0].clientY;

var nowTop = startTop;

endY = nowY;

var moveY = nowY - startY;

nowTop += moveY;

endTop = nowTop;

iScrollTop = nowTop > 0 ? 0 : (nowTop < iWrapperH - iScrollH ? iWrapperH - iScrollH : nowTop);

iBarTop = -iScrollTop / iScrollH * iBarBoxH;

setStyle(oScroll, {

top: iScrollTop + 'px'

})

setStyle(oBar, {

top: iBarTop + 'px'

})

}

var endFn = function (e) {

endTime = new Date().getTime();

if ( endTime - startTime <= 200 && isMove ) {

var moveY = endY - startY;

var iScale = 1;

var iTime = 300;

if ( Math.abs(moveY) <= 100 ) {

iScale = 1;

iTime = 300;

} else if ( Math.abs(moveY) <= 200 ) {

iScale = 2;

iTime = 500;

} else {

iScale = 3;

iTime = 700;

}

moveY = moveY * iScale;

endTop += moveY;

iScrollTop = endTop > 0 ? 0 : (endTop < iWrapperH - iScrollH ? iWrapperH - iScrollH : endTop);

iBarTop = -iScrollTop / iScrollH * iBarBoxH;

setStyle(oScroll, {

transition: 'all ' + iTime + 'ms ease-out',

top: iScrollTop + 'px'

})

setStyle(oBar, {

transition: 'all ' + iTime + 'ms ease-out',

top: iBarTop + 'px'

})

clearTimeout(endTimeout);

endTimeout = setTimeout(function () {

setStyle(oScroll, {

transition: 'all 160ms ease-out'

})

setStyle(oBar, {

transition: 'all 160ms ease-out',

})

}, 500);

}

isMove = false;

document.documentElement.removeEventListener('touchmove', moveFn);

oContainer.removeEventListener('touchend', endFn);

}

document.documentElement.addEventListener('touchmove', moveFn);

oContainer.addEventListener('touchend', endFn);

})

function getStyle (obj, name) {

if(window.getComputedStyle) {

return getComputedStyle(obj, null)[name];

} else {

return obj.currentStyle[name];

}

}

function setStyle (obj, oStyle) {

for(var i in oStyle) {

obj.style[i] = oStyle[i];

}

}

function numberPx (num) {

return Number(num.split('px')[0]);

}

第二種代碼

移動手指事件滾動使用速度

* {

margin: 0;

padding: 0;

}

.container {

position: relative;

margin: 50px;

width: calc(100% - 100px);

height: 400px;

border: 1px solid green;

box-sizing: border-box;

overflow: hidden;

}

.container .scroll {

position: absolute;

top: 0;

left: 0;

width: 100%;

}

.container p {

margin: 0 auto 10px;

width: 80%;

height: 80px;

border: 1px solid yellow;

}

.container .scroll:after {

content: '';

display: block;

clear: both;

}

.container .barBox {

position: absolute;

right: 2px;

top: 2px;

width: 3px;

height: calc(100% - 4px);

background: rgba(100, 200, 100, 0.3);

}

.container .barBox .bar {

position: absolute;

top: 0;

right: 0;

height: 0;

width: 100%;

background: #ccc;

}

var oContainer = document.getElementById('container');

var oScroll = oContainer.children[0];

var oBarBox = document.getElementById('barBox');

var oBar = oBarBox.children[0];

// 盒子尺寸

var iWrapperH = numberPx(getStyle(oContainer, 'height'));

var iScrollH = numberPx(getStyle(oScroll, 'height'));

var iBarBoxH = numberPx(getStyle(oBarBox, 'height'));

var iBarH = iWrapperH / iScrollH * iBarBoxH;

// 初始狀態(tài)

setStyle(oBar, {

height: iBarH + 'px'

})

// 參數(shù)

var startTime = 0;

var endTime = 0;

var pastTime = 0; // 過去一次的時間

var nowTime = 0; // 當(dāng)前移動的時間

var isMove = false;

var iBarTop = 0;

var timer = true;

oContainer.addEventListener('touchstart', function (e) {

startTime = new Date().getTime();

pastTime = startTime;

var startY = e.targetTouches[0].clientY;

var startTop = numberPx(getStyle(oScroll, 'top'));

var endY = startY;

var endTop = startTop;

timer = false;

var moveFn = function (e) {

isMove = true;

var nowY = e.targetTouches[0].clientY;

var nowTop = startTop;

endY = nowY;

var moveY = nowY - startY;

nowTop += moveY;

endTop = nowTop = getPos(nowTop);

setStyle(oScroll, {

top: nowTop + 'px'

})

setStyle(oBar, {

top: getBarTop(nowTop) + 'px'

})

}

var endFn = function (e) {

endTime = new Date().getTime();

var speed = (endY - startY) / (endTime - startTime);

if ( endTime - startTime <= 300 && isMove ) {

speed *= 16;

var f = 0,

top = endTop;

timer = true;

show();

function show () {

timer && requestAnimationFrame(show);

f = Math.min(Math.abs(speed) / 10, 0.5); //重點

if( speed > 0.2 ) {

speed -= f

} else if(speed < -0.2){

speed += f

} else {

timer = false

speed = 0

return

}

top += speed;

if ( top > 0 || top < iWrapperH -iScrollH ) {

timer = false

speed = 0

setStyle(oScroll, {

top: getPos(top) + 'px'

})

setStyle(oBar, {

top: getBarTop(getPos(top)) + 'px'

})

return

}

setStyle(oScroll, {

top: top + 'px'

})

setStyle(oBar, {

top: getBarTop(top) + 'px'

})

}

}

isMove = false;

document.documentElement.removeEventListener('touchmove', moveFn);

document.documentElement.removeEventListener('touchend', endFn);

}

document.documentElement.addEventListener('touchmove', moveFn);

document.documentElement.addEventListener('touchend', endFn);

})

function getPos (num) {

return num >= 0 ? 0 : (num <= iWrapperH - iScrollH ? iWrapperH - iScrollH : num);

}

function getBarTop (num) {

return -num / iScrollH * iBarBoxH;

}

function getStyle (obj, name) {

if(window.getComputedStyle) {

return getComputedStyle(obj, null)[name];

} else {

return obj.currentStyle[name];

}

}

function setStyle (obj, oStyle) {

for(var i in oStyle) {

obj.style[i] = oStyle[i];

}

}

function numberPx (num) {

return Number(num.split('px')[0]);

}

可以看看原生的效果

蘋果移動效果

* {

margin: 0;

padding: 0;

}

.container {

position: relative;

margin: 50px;

width: calc(100% - 100px);

height: 400px;

border: 1px solid green;

box-sizing: border-box;

overflow: auto;

}

.container p {

margin: 0 auto 10px;

width: 80%;

height: 80px;

border: 1px solid yellow;

}

雖然現(xiàn)在看起來可以滾動了,但是感覺距離原生的慣性滾動、以及iScroll、better-scroll等的效果差的還是挺遠(yuǎn)的。看他們的源碼,真是找不到哪兒是哪兒的東西,希望懂的大佬們,能夠指點指點我!!!

總結(jié)

以上是生活随笔為你收集整理的手机html滚动原理,手机滚动-如何实现惯性滚动的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。