制作移动端整页滚动动画
需要用到
rem7.5.js(rem适配)
pageSlider.js(控制动画的js文件)
基于zepto,引入zepto.js文件
animate.css(动画样式)
base.css(公共样式)
下面看一下页面结构
<div class="section sec1"
style="background-image:url(./images/9.png);background-size: contain;background-color: #D5C1D7 !important;height: 100vh;">
</div>
<div class="section sec2">
2
</div>
......
js部分
<script>
//$(function(){
var pageSlider = PageSlider.case();
//});
//a标签无法触发跳转的问题用以下代码
$(".to-form-link>a").on('touchend', function () {
location.replace($(this).attr("href"));
});
</script>
<script>
if (!(/msie [6|7|8|9]/i.test(navigator.userAgent))) {
new WOW().init();
};
</script>
这里需要注意一点,如果你想在翻动页面进行点击的一些操作,那么就需要将pageSlider.js中的阻止默认行为给去掉,否则是无法进行点击事件的。
解决动画同时进行的bug
如果你进行翻页可能会发现你每次翻页的时候所有的页面的动画都会同时进行,那么可以操作pageSlider.js
中的callback
函数对每个页面单独的动画进行显示以及隐藏
pageSlider.js
动画样式的选择可以根据官网进行自定义设置
animate.css
给元素添加动画的方法
首先给需要进行动画效果的标签添加class名,wow
的样式必须存在,后面跟你需要执行的动画名称,比如slideInLeft
例:<div class="wow slideInLeft" ></div>
类名前面的wow是每一个带动画的元素都要加的,slideInLeft
就是说明动画样式。后面的data-wow-duration
(动画持续时间)、data-wow-delay
(动画延迟时间)、data-wow-offset
(元素的位置露出后距离底部多少像素执行)和data-wow-iteration
(动画执行次数)这四个属性可选可不选。
例如:
<span class="wow lightSpeedIn" data-wow-delay="2.3s" data-wow-duration="1s"></span>
这里是pageSlider.js修改后的文件,这个文件实在是不太好找,时间比较长了,这里复制粘贴即可
/*
* pageSlider - Zepto plugin for mobile single page sliding
*
* Copyright (c) 2015 Frans Lee dmon@foxmail.com
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Version: 1.0
*
*/
;(function($, window, document, undefined) {
'use strict';
/**
* Instantiate parameters
*
* @constructor
*/
function funwow(){
var wow = new WOW({
boxClass: 'wow',
animateClass: 'animation',
offset: 0, //距可视窗口执行动画的距离
mobile: true,
live: true,
});
console.log(wow);
wow.init();
}
function PageSlider(optOrIndex){
this.inited = false,
this.startY = 0,
this.distance = 0,
this.timer = null,
this.nextPageTop = 0,
this.prevPageTop = 0,
this.index = 0,
this.curPagePos = 0,
this.nextPagePos = 0,
this.pageHeight = 0,
this.prevPagePos = 0;
var sec1 = document.querySelector('.sec1')
this.opt = {
startPage: 1,
range: 10,
duration: 300,
loop: false,
elastic: true,
translate3d: true,
callback:{
1:function(){
funwow()
document.querySelector('.sec1_img4').style.display = 'block';
},
2:function(){
funwow()
},
}
};
this.init(optOrIndex);
};
/**
* Set translate/translate3d according to the option
*
* @param {Number|String} offsetY Vertical Offset
* @returns {String} translate/translate3d
*/
PageSlider.prototype.motion = function(offsetY){
if (this.opt.translate3d) {
return 'translate3d(0,' + offsetY + 'px,0)';
} else {
return 'translate(0,' + offsetY + 'px)';
}
};
/**
* Show the specified page
*
* @param {Number} index The target page number
* @param {string} direction The direction of the sliding,'next' or 'prev'
*/
PageSlider.prototype.showSec = function(index, direction) {
if ($('.current').length) $('.current,.next,.prev').css({
'-webkit-transition': null,
'-webkit-transform': null
}).removeClass('current prev next');
var cur, next, prev;
var totalSec = $('.section').length;
if (direction == 'next') {
cur = index == totalSec ? 1 : (index + 1);
next = cur == totalSec ? (this.opt.loop ? 1 : 0) : (cur + 1);
prev = index;
} else if (direction == 'prev') {
cur = index == 1 ? totalSec : (index - 1);
next = index;
prev = cur == 1 ? (this.opt.loop ? totalSec : 0) : (cur - 1);
} else {
cur = index;
next = index == totalSec ? (this.opt.loop ? 1 : 0) : (index + 1);
prev = index == 1 ? (this.opt.loop ? totalSec : 0) : (index - 1);
}
var $curSec = $('.sec' + cur);
var $nextSec = $('.sec' + next);
var $prevSec = $('.sec' + prev);
$curSec.addClass('current');
this.pageHeight = $('.current').height();
$nextSec.addClass('next').css('-webkit-transform', this.motion(this.pageHeight));
$prevSec.addClass('prev').css('-webkit-transform', this.motion(-this.pageHeight));
$curSec.addClass('ani').siblings('.section').removeClass('ani');
//执行回调
typeof(this.opt.callback[cur])=='function' && this.opt.callback[cur]();
};
/**
* Touch start event handler
*/
PageSlider.prototype.touchStartHandler = function(event) {
var that = event.data.that;
if(that.timer){
return;
}
that.index = $('.section').index($(this)) + 1;
var touch = event.touches[0];
that.distance = 0;
that.startY = touch.clientY;
that.curPagePos = $(this).offset().top;
that.nextPagePos = $('.next').length && $('.next').offset().top;
that.prevPagePos = $('.prev').length && $('.prev').offset().top;
$(this).off('touchmove').on('touchmove', {
'that': that
}, that.touchMoveHandler);
$(this).off('touchend').on('touchend', {
'that': that
}, that.touchEndHandler);
};
/**
* Touch move event handler
*/
PageSlider.prototype.touchMoveHandler = function(event) {
var that = event.data.that;
if(that.timer){
return;
}
var touch = event.touches[0];
that.distance = touch.clientY - that.startY;
if (Math.abs(that.distance) < 5) {
return;
};
if (!that.opt.elastic && ((that.index === 1 && that.distance > 0) || (that.index === $('.section').length && that.distance < 0))) {
return;
}
that.curPageTop = that.curPagePos + that.distance;
that.nextPageTop = that.nextPagePos + that.distance;
that.prevPageTop = that.prevPagePos + that.distance;
$(this).css('-webkit-transform', that.motion(that.curPageTop));
$('.next').css('-webkit-transform', that.motion(that.nextPageTop));
$('.prev').css('-webkit-transform', that.motion(that.prevPageTop));
};
/**
* Touch end event handler
*/
PageSlider.prototype.touchEndHandler = function(event) {
var that = event.data.that;
if(that.timer){
return;
}
$('.current,.next,.prev').css('-webkit-transition', '-webkit-transform ' + that.opt.duration + 'ms linear');
if ((that.distance < -that.opt.range && $('.next').length) || (that.distance > that.opt.range && $('.prev').length)) {
var next = !!(that.distance < -that.opt.range);
$(this).css('-webkit-transform', that.motion((next ? (-$(this).height()) : $(this).height())));
$(next ? '.next' : '.prev').css('-webkit-transform', that.motion(0));
that.timer = setTimeout(function() {
that.showSec(that.index, next ? 'next' : 'prev');
clearTimeout(that.timer);
that.timer = null;
}, that.opt.duration + 5);
} else {
$(this).css('-webkit-transform', that.motion(0));
$('.prev').css('-webkit-transform', that.motion(-that.pageHeight));
$('.next').css('-webkit-transform', that.motion(that.pageHeight));
that.timer = setTimeout(function() {
$('.current,.next,.prev').css({
'-webkit-transition': null
});
clearTimeout(that.timer);
that.timer = null;
}, that.opt.duration + 5);
}
};
/**
* Sliding to the target page
*
* @param {Number} index The target page number
*/
PageSlider.prototype.go = function(index){
this.init(index);
};
/**
* PageSlider initializer
*
* @param {Object|Number} optOrIndex Settings or page number
*/
PageSlider.prototype.init = function(optOrIndex){
var that = this;
if (typeof(optOrIndex) == 'object') {
$.extend(true, that.opt, optOrIndex);
that.inited = false;
} else {
optOrIndex && (that.opt.startPage = optOrIndex);
}
if (!that.inited) {
$('.section').off('touchstart').on('touchstart', {
'that': that
}, that.touchStartHandler);
that.showSec(that.opt.startPage);
that.inited = true;
} else {
that.showSec(that.opt.startPage)
}
$(window).on('onorientationchange' in window ? 'orientationchange':'resize',function(){
that.go(that.index+1);
});
};
/**
* To generate an instance of object
*
* @param {Object|Number} optOrIndex Settings or page number
*/
PageSlider.case = function(optOrIndex) {
return new PageSlider(optOrIndex);
};
if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
define(function() {
return PageSlider;
});
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = PageSlider.case;
module.exports.PageSlider = PageSlider;
} else {
window.PageSlider = PageSlider;
}
})(window.Zepto, window, document);
```js
ine.amd === 'object' && define.amd) {
define(function() {
return PageSlider;
});
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = PageSlider.case;
module.exports.PageSlider = PageSlider;
} else {
window.PageSlider = PageSlider;
}
})(window.Zepto, window, document);