JS+CSS3模拟溢出滚动效果


Posted in Javascript onAugust 12, 2016

移动开发的时候,我们经常会遇到滑动事件,众所周知手机端滑动主要依靠touch事件。最近接连遇到两个页面都有类似overflow:auto的效果,一般情况下通过css设置是可以实现的(虽说丑了点儿),,但是一旦overflow:auto的元素响应touch事件时就会有诸多不便,例如fullpage中某一元素自滑动,我们可以通过normalScrollElements来使元素滑动的时候不滑动到下一屏,但是在元素滑动到最底部的时候也就不能响应下一屏事件,上滑也是一样,这时候就需要touch事件来响应,为了以后封装方便,特简单封装一个jquery插件,同时也复习一下jquery插件开发及touch事件;

插件大体思路是这样的,如下图所示:方框内区域为固定宽高的父元素(设置overflow:hidden),子元素高度大于父元素,我们通过响应touch事件改变子元素的translate值(top也可以,但是translate效率更高一些),当然在此期间我们需判断子元素translate值的边界,最大为0,最小为子元素高度-父元素高度

ps:如果想做子元素根据手指移动,松开手指后回到边界需另写程序

JS+CSS3模拟溢出滚动效果

下面来一步步写插件

第一步,先建立一个安全的作用域

;(function($){
//插入代码
})(jQuery) 
如果我们需要通过$(“#id”).xx()方法调用,需要像下面这样写,这里的fn及jquery的prototype;
$.extend({
exec:function(){}
}) //这种扩展通过$.exec()调用
$.fn.simuScroll = function(option){
var scrollObj=new simuScroll(this,option);
return scrollObj.init();
}

下面来看上面代码中的simuScroll方法,这是一个构造函数,它接受两个参数,ele为当前接受touch事件的元素(一般可以设置为父元素),option为用户传入的配置参数,如改变translate的元素,父元素子元素高度,extra为需额外增加的高度,滑动到顶部或底部时执行的回调函数等等;

var simuScroll = function(ele,option){
this.settings = {
target : ele, //事件元素
changeTarget:'',
outerHeight : '800', //外层高度
innerHeight : '500', //内层高度
extra : '0', //额外增加的距离
swipeUp : null,
swipeDown : null,
vertical:true
};
//通过jquery.extend对默认的settings进行扩展,得出一个全新的对象
this.opt = jQuery.extend({},this.settings,option); 
this.initNumber = this.lastNumber = this.result = 0;
this.flag = false;
//计算出子元素与父元素距离差,以此来判定元素的最大滑动距离
this.diff = parseFloat(this.opt.innerHeight) - parseFloat(this.opt.outerHeight) + parseFloat(this.opt.extra);
this.diff = this.diff < 0 ? 0 :this.diff;
this.direction = '';
};

在对jquery prototype进行扩展时,第一步为实例化上面的构造函数,第二步则直接调用了构造函数的init方法,具体见下面备注

init:function(){
//jquery对象直接绑定touch事件获取event需originalEvent获取原生对象的event属性
//jquery对象 获取pagex event.originalEvent.touches[0].pageX 
//dom对象 event.touches[0].pageX 
var target = this.opt.target.get(0); 
//如果子元素高度大于父元素,则执行滑动事件,否则执行回调函数
this.flag = this.diff > 0 ? 'translate' : 'exec';
/*如果元素已设置transform中 translate,scale,skew,rotate中的任何一项,
则我们再直接设置transform:translateY(10px)时会覆盖掉初始设置的属性
所以我们通过获取元素的matrix值既保证原有属性,又能设置任意值*/
var cssText = this.opt.changeTarget.css('-webkit-transform');
if(cssText=='none'){ //元素未设置transform属性
this.str = this.opt.vertical ? 'translateY' : 'translateX' ;
}else{
this.str = cssText ;
var reg = /-?\d+\.?\d*/g; //正则表达式
/*获取matrix中各参数
直接获取到的matrix值为类似matrix(1,0,0,1,0,0)
获取到的为[1,0,0,1,0,0] 这样我们就可以随意的修改某一个值
数组的第5项为元素的translateX值,第6项为translateY值 */
this.params = this.str.match(reg); 
this.matrix = this.opt.vertical ? 6 : 5 ; //根据传入的参数确定要修改的值为translateY或tranlateX
} 
var _this = this;
//父元素绑定touch事件,传递事件对象及context
target.addEventListener('touchstart',function(e){
_this.start(e,_this)
});
target.addEventListener('touchmove',function(e){
_this.move(e,_this)
});
target.addEventListener('touchend',function(e){
_this.end(e,_this)
});
}

touchstart方法相对比较简单,根据需要滑动的方向记录手指接触屏幕时的初始值

start:function(e,context){
e.preventDefault();
var touches = e.touches[0];
context.initNumber = context.opt.vertical ? touches.pageY : touches.pageX;
},

touchmove方法主要根据手指滑动距离动态改变元素css属性,让元素能够跟随手指进行移动

setNumber方法只有一句话: this.params.splice(n-1,1,number) 根据传入的参数改变matrix数组

move:function(e,context){
e.preventDefault();
var touches = e.touches[0];
number = context.opt.vertical ? touches.pageY : touches.pageX;
//获取相对手指触碰屏幕的变化值
var delta = number - context.initNumber;
if(context.flag == 'translate'){ //如果需要滑动
context.result = context.lastNumber + delta;
//设置滑动的最大值和最小值
context.result = context.result > 0 ? 0 : context.result ;
context.result = -context.result > context.diff ? -context.diff : context.result;
//动态设置元素css属性
if(context.matrix){
switch (context.matrix) {
case 6: 
context.setNumber(6,context.result)
break;
case 5:
context.setNumber(5,context.result)
break;
}
context.opt.changeTarget.css('-webkit-transform','matrix('+context.params.join(',')+')')
}else{
context.opt.changeTarget.css('-webkit-transform',context.str+'('+context.result+'px)')
}
}
},

touchend则判断释放时是否需要执行回调函数

end:function(e,context){
e.preventDefault();
var touches = e.changedTouches[0];
var number = context.opt.vertical ? touches.pageY : touches.pageX,
n = number - context.initNumber;
//当元素滑动距离大于10 并且最初元素translate值为0同时回调函数存在,则执行回调函数
if(n>10 && context.lastNumber == 0 && context.opt.swipeDown){ 
context.opt.swipeDown()
}else if(n<-10 && context.lastNumber == -context.diff && context.opt.swipeUp){
context.opt.swipeUp();
}
//将常量设为结果值,能保证多次连贯滑动
context.lastNumber = context.result;
}

基本上一个简单的jQuery插件就完成了,框架如下

;(function($){
var a = function(m,n){
//函数内容
};
a.prototype = {
init:function(){
},
start:function(){
},
move:function(){
},
end:function(){
},
setNumber:function(){
}
}
$.fn.scrol = function(o){
var obj = new a(this,o);
return obj.init()
}
})(jQuery)

调用时如下:

$(".outer").simuScroll({
'outerHeight':$(".outer").height(),
'innerHeight':$('.inner').height(),
'changeTarget' : $(".inner"),
'swipeUp' :function(){
console.log('up')
},
'swipeDown' :function(){
console.log('down')
},
vertical:true
})

以上所述是小编给大家介绍的JS+CSS3模拟溢出滚动效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
下载站控制介绍字数显示的脚本 显示全部 隐藏介绍等功能
Sep 19 Javascript
js操作模态窗口及父子窗口间相互传值示例
Jun 09 Javascript
点击标签切换和自动切换DIV选项卡
Aug 10 Javascript
javascript操作select元素实例分析
Mar 27 Javascript
jQuery Validate表单验证入门学习
Dec 18 Javascript
iscroll.js的上拉下拉刷新时无法回弹的解决方法
Feb 18 Javascript
详解使用Vue.Js结合Jquery Ajax加载数据的两种方式
Jan 10 Javascript
VUE + UEditor 单图片跨域上传功能的实现方法
Feb 08 Javascript
解决vue项目中type=”file“ change事件只执行一次的问题
May 16 Javascript
vue路由组件按需加载的几种方法小结
Jul 12 Javascript
vue-cli3.X快速创建项目的方法步骤
Nov 14 Javascript
Openlayers显示瓦片网格信息的方法
Sep 28 Javascript
JS中script标签defer和async属性的区别详解
Aug 12 #Javascript
jquery实现网站列表切换效果的2种方法
Aug 12 #Javascript
很实用的js选项卡切换效果
Aug 12 #Javascript
js实现浏览器倒计时跳转页面效果
Aug 12 #Javascript
javascript实现瀑布流动态加载图片原理
Aug 12 #Javascript
jquery实现垂直和水平菜单导航栏
Aug 27 #Javascript
JS实现图片剪裁并预览效果
Aug 12 #Javascript
You might like
PHP实现抓取HTTPS内容
2014/12/01 PHP
php实现的简单日志写入函数
2015/03/31 PHP
php+ajax制作无刷新留言板
2015/10/27 PHP
php使用GD2绘制几何图形示例
2017/02/15 PHP
PHP代码重构方法漫谈
2018/04/17 PHP
Avengerls vs Newbee BO3 第一场2.18
2021/03/10 DOTA
用javascript连接access数据库的方法
2006/11/17 Javascript
页面调用单个swf文件,嵌套出多个方法。
2011/11/21 Javascript
jquery遍历筛选数组的几种方法和遍历解析json对象
2013/12/13 Javascript
JS根据生日月份和日期计算星座的简单实现方法
2016/11/24 Javascript
用javascript获取任意颜色的更亮或更暗颜色值示例代码
2017/07/21 Javascript
微信小程序wx.getImageInfo()如何获取图片信息
2018/01/26 Javascript
vue利用v-for嵌套输出多层对象,分别输出到个表的方法
2018/09/07 Javascript
浅谈js闭包理解
2019/03/28 Javascript
详解微信小程序图片地扯转base64解决方案
2019/08/18 Javascript
Vue实例的对象参数options的几个常用选项详解
2019/11/08 Javascript
JavaScript基于SVG的图片切换效果实例代码
2020/12/15 Javascript
python打开文件并获取文件相关属性的方法
2015/04/23 Python
python:接口间数据传递与调用方法
2018/12/17 Python
python实现K近邻回归,采用等权重和不等权重的方法
2019/01/23 Python
python实现画出e指数函数的图像
2019/11/21 Python
Python 实现微信自动回复的方法
2020/09/11 Python
土耳其时尚潮流在线购物网站:Trendyol
2017/10/10 全球购物
商务英语专业自荐信
2013/10/14 职场文书
校长就职演讲稿
2014/01/06 职场文书
父亲生日宴会答谢词
2014/01/10 职场文书
自我鉴定注意事项
2014/01/19 职场文书
摄影专业毕业生求职信
2014/03/13 职场文书
小学教师读书活动总结
2014/07/08 职场文书
项目工作说明书
2014/07/29 职场文书
风之谷观后感
2015/06/11 职场文书
《观察物体》教学反思
2016/02/17 职场文书
Keras在mnist上的CNN实践,并且自定义loss函数曲线图操作
2021/05/25 Python
如何更改Win11声音输出设备?Win11声音输出设备四种更改方法
2022/04/08 数码科技
python神经网络 tf.name_scope 和 tf.variable_scope 的区别
2022/05/04 Python
windows server 2016 域环境搭建的方法步骤(图文)
2022/06/25 Servers