欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JGUI源码:Accordion鼠标中键滚动和手机端滑动实现

程序员文章站 2022-05-31 15:10:26
本文是抽屉组件在PC端滚动鼠标中键、手机端滑动时,滚动数据列表实现方法,没有使用iscroll等第三方插件,支持火狐,谷歌,IE等浏览器。具体代码在www.jgui.com 源码未压缩,请右键查看网页源码,相关文件有accordion.js,accordion.css,index.html 首先可以 ......

本文是抽屉组件在pc端滚动鼠标中键、手机端滑动时,滚动数据列表实现方法,没有使用iscroll等第三方插件,支持火狐,谷歌,ie等浏览器。
具体代码在   源码未压缩,请右键查看网页源码,相关文件有accordion.js,accordion.css,index.html

首先可以通过设置margin隐藏滚动条方式实现,这种方式实现简单,网上也有很多文章,本文使用的另一种方式:jquery实现滚动。

前端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端模拟手机滑动效果如下
JGUI源码:Accordion鼠标中键滚动和手机端滑动实现

滚动时,会发现缺少了一点惯性,比如鼠标中键一次拨动几个和拨动一个应该移动距离不一样,为了解决这个问题改进代码如下

//电脑端中键滚动事件
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,这时候可能正在进行的滚动操作被重置了,另外部分变量使用的全局变量也不合适,因为界面上可能有多个according,
此处增加一个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对象变量,简单实现一个自动为jquery对象增加jquery对象变量方法如下。

$.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();

现在鼠标上下滚动很平滑了,也可以快慢滚动了,同理,手机端touch事件也可以根据这个原理改造,需要考虑滑动时间和滑动距离,根据这个来计算滑动偏移距离。大家如果有空深入完善下,应该也是可以媲美iscroll的。