本文是抽屜組件在PC端滾動滑鼠中鍵、手機端滑動時,滾動數據列表實現方法,沒有使用iscroll等第三方插件,支持火狐,谷歌,IE等瀏覽器。演示在:www.jgui.com Github地址:https://github.com/zhaogaojian/JGUI覺得好的給個star,謝謝! 源碼未壓縮 ...
本文是抽屜組件在PC端滾動滑鼠中鍵、手機端滑動時,滾動數據列表實現方法,沒有使用iscroll等第三方插件,支持火狐,谷歌,IE等瀏覽器。
演示在:www.jgui.com
Github地址:https://github.com/zhaogaojian/JGUI
效果
覺得好的給個star,謝謝!
源碼未壓縮,請右鍵查看網頁源碼,相關文件有accordion.js,accordion.css,index.html
隱藏滾動條可以通過設置margin隱藏滾動條方式實現,css3支持直接隱藏滾動條,這兩種方式實現簡單,網上也有很多文章
本文使用監聽滑鼠滾動事件滾動方式。
下麵是實現過程和思路,大家可以一起來學習下使用到的技術。
前端html結構如下
<div class="jgui-accordion" style="width:100%;overflow:hidden;position: absolute;top:60px;left:0px;right: 0px;bottom:0px;"> <div class="jgui-accordion-list"> <ul> <dl> <dt class="jgui-accordion-navitem"> <a> <i class="anticon icon-home"></i> <span>目錄1</span> <i class="jgui-accordion-navitem-more"></i> </a> </dt> .......
方法一:使用jquery animate實現(只處理垂直方向上滾動)
//電腦端中鍵滾動事件 mousewheel = getBrowserInfo() == "Firefox" ? "DOMMouseScroll" : "mousewheel"; $('.jgui-accordion').on(mousewheel, function (event) { var delta = 0; if (!event) /* For IE. */ event = window.event; if (event.originalEvent.wheelDelta) { /* IE/Opera. */ delta = event.originalEvent.wheelDelta / 120; } else if (event.originalEvent.detail) { delta = -event.originalEvent.detail / 3; } console.log(delta); if (delta) handle(delta); if (event.preventDefault) event.preventDefault(); event.returnValue = false; }); var handle = function (delta) { var step = Math.floor($('.jgui-accordion').height()/10); //可視區高度 var cur_top = $('.jgui-accordion').scrollTop(); //當前滾過的高度 var direction = delta > 0 ? -1 : 1; $(".jgui-accordion").stop().animate({ scrollTop: direction * step + cur_top }, 50); } //手機端滑鼠滑動事件 $(".jgui-accordion").on("touchstart", function (e) { startY = e.originalEvent.changedTouches[0].pageY; }); $(".jgui-accordion").on("touchmove", function (e) { e.preventDefault(); moveEndY = e.originalEvent.changedTouches[0].pageY, Y = (moveEndY - startY); startY = moveEndY; var cur_top = $('.jgui-accordion').scrollTop(); //當前滾過的高度 $(".jgui-accordion").stop().animate({ scrollTop: -Y + cur_top }, 0); });
方法二:使用css3 tansform實現,以手機端滑動為例
//手機端滑鼠滑動事件 $(".jgui-accordion-list").on("touchstart", function (e) { startY = e.originalEvent.changedTouches[0].pageY; console.log("aa"); }); curY=0; $(".jgui-accordion-list").on("touchmove", function (e) { e.preventDefault(); moveEndY = e.originalEvent.changedTouches[0].pageY, Y = (moveEndY - startY) ; curY+=Y; startY = moveEndY; $(".jgui-accordion-list").css('-webkit-transform','translate3d(0px,'+curY+'px,0px)') $(".jgui-accordion-list").css('-moz-transform','translate3d(0px,'+curY+'px,0px)') });
在本頁面中,兩種方式性能基本上差不多,第二種需要手動計算滾動區域,防止過高或過低。
PC端模擬手機滑動效果如下
滾動時,會發現缺少了一點慣性,比如滑鼠中鍵一次撥動幾個和撥動一個應該移動距離不一樣,為瞭解決這個問題改進代碼如下
//電腦端中鍵滾動事件 var sumdelta=0; var mousewheel = getBrowserInfo() == "Firefox" ? "DOMMouseScroll" : "mousewheel"; $('.jgui-accordion').on(mousewheel, function (event) { var delta = 0; if (!event) /* For IE. */ event = window.event; if (event.originalEvent.wheelDelta) { /* IE/Opera. */ delta = event.originalEvent.wheelDelta / 120; } else if (event.originalEvent.detail) { delta = -event.originalEvent.detail / 3; } if (delta) { sumdelta+=(delta> 0 ? -1 : 1); setTimeout("handle()",80); } stopPropagation(event); }); var handle = function () { isanimate=true; var step = Math.floor($('.jgui-accordion').height()/5);//可視區高度 var cur_top = $('.jgui-accordion').scrollTop(); //當前滾過的高度 var direction = sumdelta ;//> 0 ? -1 : 1; $(".jgui-accordion").stop().animate({ scrollTop: direction * step + cur_top }, 800,'swing',function(){sumdelta=0;}); }
上面通過setTimeout延時觸發滾動事件,即可實現不同的滾動速度。
測試發現突然變向滑動時,會感覺有延遲,分析代碼原因主要是因為sumdelta=0,這時候可能正在進行的滾動操作被重置了,另外部分變數使用的全局變數也不合適,因為界面上可能有多個accordion,
下麵增加一個Jquery對象變數,優化代碼如下:
//電腦端中鍵滾動事件 var mousewheel = getBrowserInfo() == "Firefox" ? "DOMMouseScroll" : "mousewheel"; $('.jgui-accordion').on(mousewheel, function (event) { var delta = 0; if (!event) /* For IE. */ event = window.event; if (event.originalEvent.wheelDelta) { /* IE/Opera. */ delta = event.originalEvent.wheelDelta / 120; } else if (event.originalEvent.detail) { delta = -event.originalEvent.detail / 3; } if (delta) { var datas=$(this).data('datas'); datas.sumdelta+=(delta> 0 ? -1 : 1); var direction = datas.sumdelta ; var obj=$(this); var handle = function () { datas.sumdelta=0; var step = Math.floor(obj.height()/10);//可視區高度 var cur_top = obj.scrollTop(); //當前滾過的高度 obj.stop().animate({ scrollTop: direction * step + cur_top }, 400,'linear',function(){direction=0;}); } setTimeout(handle,100); } stopPropagation(event); });
datas.sumdelta是自定義的一個Jquery對象變數,增加變數方法如下(return this.each是一個鏈式操作,返回的是this)。
$.fn.jAccordion = function (p_options,p_datas, p_param) { return this.each(function () { var obj = $(this); var datas = $.extend({ sumdelta:0 }, p_datas); obj.data('datas', datas); }); }; $(".jgui-accordion").jAccordion();
為了進一步提升滾輪加速效果和防止Timer重入再次修改代碼如下
//電腦端中鍵滾動事件 var mousewheel = getBrowserInfo() == "Firefox" ? "DOMMouseScroll" : "mousewheel"; $('.jgui-accordion').on(mousewheel, function (event) { var delta = 0; if (!event) /* For IE. */ event = window.event; if (event.originalEvent.wheelDelta) { /* IE/Opera. */ delta = event.originalEvent.wheelDelta / 120; } else if (event.originalEvent.detail) { delta = -event.originalEvent.detail / 3; } if (delta) { var datas=$(this).data('datas'); datas.sumdelta+=(delta> 0 ? -1 : 1); var direction = datas.sumdelta ; var obj=$(this); var handle = function () { datas.isscrolling=true; datas.sumdelta=0; var step = Math.floor(obj.height()/30);//可視區高度 var cur_top = obj.scrollTop(); //當前滾過的高度 obj.stop().animate({ scrollTop: direction*Math.abs(direction) * step + cur_top }, 400,'linear',function(){direction=0;datas.isscrolling=false}); } if(!datas.isscrolling) setTimeout(handle,100); } stopPropagation(event); });
$.fn.jAccordion = function (p_options,p_datas, p_param) { return this.each(function () { var obj = $(this); var datas = $.extend({ sumdelta:0,isscrolling:false }, p_datas); obj.data('datas', datas); }); }; $(".jgui-accordion").jAccordion();
這樣在撥動一兩格時,滾動條緩慢移動,當快速波動時,因為平方的效應,能引起加速滾動,可以快速的回到頂部或者底部。如果不想使用這個滾動條代碼,將mousewheel事件註釋掉即可。
現在滑鼠上下滾動很平滑了,也可以快慢滾動了,同理,手機端touch事件也可以根據這個原理改造,需要考慮滑動時間和滑動距離,根據這個來計算滑動偏移距離,手機端效果將後續實現。大家如果有空深入完善下,應該也是可以媲美IScroll的。後續將擴展一些JS防範方便大家使用。