DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> JS+CSS3模擬溢出滾動效果
JS+CSS3模擬溢出滾動效果
編輯:關於JavaScript     

移動開發的時候,我們經常會遇到滑動事件,眾所周知手機端滑動主要依靠touch事件。最近接連遇到兩個頁面都有類似overflow:auto的效果,一般情況下通過css設置是可以實現的(雖說丑了點兒),,但是一旦overflow:auto的元素響應touch事件時就會有諸多不便,例如fullpage中某一元素自滑動,我們可以通過normalScrollElements來使元素滑動的時候不滑動到下一屏,但是在元素滑動到最底部的時候也就不能響應下一屏事件,上滑也是一樣,這時候就需要touch事件來響應,為了以後封裝方便,特簡單封裝一個jquery插件,同時也復習一下jquery插件開發及touch事件;

插件大體思路是這樣的,如下圖所示:方框內區域為固定寬高的父元素(設置overflow:hidden),子元素高度大於父元素,我們通過響應touch事件改變子元素的translate值(top也可以,但是translate效率更高一些),當然在此期間我們需判斷子元素translate值的邊界,最大為0,最小為子元素高度-父元素高度

ps:如果想做子元素根據手指移動,松開手指後回到邊界需另寫程序

下面來一步步寫插件

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

;(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模擬溢出滾動效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對網站的支持!

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved