案例分析【移动端滑屏】
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width,user-scalable=no" />
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
body {
margin: 0;
}
body,
html {
position: relative;
height: 100%;
overflow: hidden;
}
#wrap {
height: 100%;
overflow: hidden;
}
#list {
margin: 0;
padding: 0;
list-style: none;
}
#list li {
font: 16px/30px "宋体";
text-indent: 20px;
border-bottom: 1px solid #000;
}
</style>
</head>
<body>
<section id="wrap">
<ul id="list"></ul>
</section>
<script type="text/javascript" src="js/startmove.js"></script>
<script type="text/javascript" src="js/mScroll.js"></script>
<script type="text/javascript">
(function(){
var inner = "";
for(var i = 0; i < 300; i++){
inner += `<li>这是第${i}个li</li>`;
}
list.innerHTML = inner;
})();
(function(){
var wrap = document.querySelector('#wrap');
mScroll({
wrap: wrap,
dir: "y",
over: "backOut"
});
})();
</script>
</body>
</html>
function mScroll(init){
var IN = {
dir: "y",
over: "backOut",
showBar: true
};
for(var s in init){
IN[s] = init[s];
}
IN.scroll = IN.wrap.children[0];
var startPoint = {};
var startElOffset = {};
var lastSpeed = 0;
var lastTime = 0;
var lastP = 0;
var bar;
var scale = 1;
var MaxT = {
x:0,
y:0
};
var MinT = {
x:0,
y:0
};
var F = .3;
var isFrist = true;
var isMove = true;
var MoveType = "easeOutStrong";
css(IN.scroll,"translateX",0);
css(IN.scroll,"translateY",0);
css(IN.scroll,"translateZ",.01);
IN.scroll.style.minHeight = "100%";
IN.scroll.style.minWidth = "100%";
if(IN.showBar){
bar = document.createElement("div");
bar.className = "bar";
if(getComputedStyle(IN.wrap)["position"] == "static"){
IN.wrap.style.position = "relative";
}
bar.style.cssText = "position:absolute;background:rgba(0,0,0,.4);border-radius:3px;transition:.6s opacity;opacity:0;";
if(IN.dir == "x"){
bar.style.cssText += "height:6px;left:0;bottom:0;";
scale = IN.wrap.clientWidth/IN.scroll.offsetWidth;
bar.style.width = IN.wrap.clientWidth * scale + "px";
} else {
bar.style.cssText += "width:6px;right:0;top:0;";
scale = IN.wrap.clientHeight/IN.scroll.offsetHeight;
bar.style.height = IN.wrap.clientHeight * scale + "px";
}
IN.wrap.appendChild(bar);
}
IN.wrap.addEventListener('touchstart', function(e) {
clearInterval(IN.scroll.timer);
IN.start&&IN.start();
var touch = e.changedTouches[0];
startPoint = {
x: touch.pageX,
y: touch.pageY
}
startElOffset = getScroll();
MinT = {
x: IN.wrap.clientWidth - IN.scroll.offsetWidth,
y: IN.wrap.clientHeight - IN.scroll.offsetHeight
};
lastSpeed = 0;
lastTime = Date.now();
lastP = IN.dir == "x"?startPoint.x:startPoint.y;
isFrist = true;
isMove = true;
});
IN.wrap.addEventListener('touchmove', function(e) {
if(!isMove){
return;
}
var touch = e.changedTouches[0];
var nowPoint = {
x: touch.pageX,
y: touch.pageY
};
var dis = {
x: nowPoint.x - startPoint.x,
y: nowPoint.y - startPoint.y
};
if(isFrist){
isFrist = false;
if(Math.abs(dis.x) > Math.abs(dis.y)){
if(IN.dir == "y"){
isMove = false;
return;
}
} else {
if(IN.dir == "x"){
isMove = false;
return;
}
}
bar&&(css(bar,"opacity",1));
}
var nowTime = Date.now();
var nowP = IN.dir == "x"?nowPoint.x:nowPoint.y;
var traslate = {
x: dis.x + startElOffset.x,
y: dis.y + startElOffset.y
}
if(IN.over == "none"){
traslate[IN.dir] = Math.min(traslate[IN.dir],MaxT[IN.dir]);
traslate[IN.dir] = Math.max(traslate[IN.dir],MinT[IN.dir]);
} else if(IN.over == "ease"||IN.over == "backOut"){
if(traslate[IN.dir] > MaxT[IN.dir]){
traslate[IN.dir] *= F;
} else if(traslate[IN.dir] < MinT[IN.dir]) {
var over = traslate[IN.dir] - MinT[IN.dir];
over *= F;
traslate[IN.dir] = MinT[IN.dir] + over;
}
}
if(IN.dir == "x")
{
css(IN.scroll,"translateX",traslate.x);
} else {
css(IN.scroll,"translateY",traslate.y);
}
bar&&(css(bar,IN.dir == "x"?"left":"top",-traslate[IN.dir]*scale));
lastSpeed = (nowP - lastP)/(nowTime - lastTime);
lastTime = nowTime;
lastP = nowP;
IN.move&&IN.move();
});
IN.wrap.addEventListener('touchend', function(e) {
if(!isMove){
return;
}
if(Date.now()-lastTime > 100){
lastSpeed = 0;
}
lastSpeed = Number(lastSpeed)?lastSpeed:0;
var time = 120;
var dis = lastSpeed*time;
var target = getScroll()[IN.dir] + dis;
if(IN.over == "backOut"
&&(MaxT[IN.dir] < target||MinT[IN.dir] > target)){
MoveType = "backOut";
} else {
MoveType = "easeOutStrong";
}
target = Math.min(MaxT[IN.dir],target);
target = Math.max(MinT[IN.dir],target);
time = Math.abs(target - getScroll()[IN.dir])*1.7;
target = (IN.dir == "x"?{translateX:target}:{translateY:target});
startMove({
el: IN.scroll,
target:target,
time:time,
type: MoveType,
callBack: function(){
bar&&(css(bar,"opacity",0));
IN.end&&IN.end();
},
callIn: function(){
var traslate = getScroll();
bar&&(css(bar,IN.dir == "x"?"left":"top",-traslate[IN.dir]*scale));
IN.move&&IN.move();
}
});
IN.up&&IN.up();
});
function getScroll(){
return {x:css(IN.scroll,"translateX"),y:css(IN.scroll,"translateY")};
}
}
案例分析【幻灯片】
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width,user-scalable=no" />
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
body {
margin: 0;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
img {
vertical-align: top;
}
body,
html {
position: relative;
height: 100%;
overflow: hidden;
}
#wrap {
height: 100%;
overflow: hidden;
}
#list li {
font: 16px/30px "宋体";
text-indent: 20px;
border-bottom: 1px solid #000;
}
#tabPic {
position: relative;
overflow: hidden;
}
#pics {
overflow: hidden;
}
#pics li {
float: left;
}
#pics img {
width: 100%;
}
#nav {
position: absolute;
left: 0;
bottom: 10px;
width: 100%;
height: 10px;
text-align: center;
}
#nav a {
display: inline-block;
vertical-align: top;
margin: 0 5px;
width: 10px;
height: 10px;
background: #fff;
border-radius: 5px;
transition: .5s;
}
#nav a.active {
width: 20px;
background: #f60;
}
</style>
</head>
<body>
<section id="wrap">
<div>
<div id="tabPic">
<ul id="pics">
<li>
<img src="img/img1.jpg"/>
</li>
<li>
<img src="img/img2.jpg"/>
</li>
<li>
<img src="img/img3.jpg"/>
</li>
<li>
<img src="img/img4.jpg"/>
</li>
</ul>
<nav id="nav">
<a href="javascript:;" class="active"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
</nav>
</div>
<ul id="list"></ul>
</div>
</section>
<script type="text/javascript" src="js/startmove.js"></script>
<script type="text/javascript" src="js/mScroll.js"></script>
<script type="text/javascript">
document.addEventListener('touchstart', function(e) {
e.preventDefault();
});
(function(){
var style = document.createElement("style");
var tabPic = document.querySelector('#tabPic');
var pics = document.querySelector('#pics');
pics.innerHTML += pics.innerHTML;
style.innerHTML = `#pics li {width:${tabPic.clientWidth}px}`;
style.innerHTML += `#pics{width:${tabPic.clientWidth*pics.children.length}px}`;
document.head.appendChild(style);
})();
(function(){
var tabPic = document.querySelector('#tabPic');
var pics = document.querySelector('#pics');
var pic = pics.children;
var navs = document.querySelectorAll('#nav a');
var picW = pic[0].offsetWidth;
var now = 0;
function start(){
if(now == 0){
now = navs.length;
} else if(now == pic.length - 1){
now = navs.length - 1;
}
css(pics,"translateX",-now*picW);
}
function up(){
clearInterval(pics.timer);
now = -Math.round(css(pics,"translateX")/picW);
var target = -now*picW;
startMove({
el:pics,
target:{
translateX: target
},
time: 400,
type: "easeOut"
});
for(var i = 0 ; i< navs.length; i++){
navs[i].className = "";
}
navs[now%navs.length].className = "active";
}
mScroll({
wrap:tabPic,
dir: "x",
showBar: false,
over: "none",
start: start,
up: up
});
})();
(function(){
var inner = "";
for(var i = 0; i < 300; i++){
inner += `<li>这是第${i}个li</li>`;
}
list.innerHTML = inner;
})();
(function(){
var wrap = document.querySelector('#wrap');
mScroll({
wrap: wrap,
dir: "y",
over: "backOut"
});
})();
</script>
</body>
</html>