网站首页 » 前端开发 » JavaScript » 移动端侧滑导航、侧滑菜单效果
上一篇:
下一篇:

移动端侧滑导航、侧滑菜单效果

手机端的侧滑导航、侧滑菜单效果极其地常见,这篇文章就是分享侧滑导航的制作过程。首先这是一个基于 jQuery 库的插件,其实不用 jQuery 库也是可以的,并且代码改起来也不能,这里就不作过多的讲解。

首先做这个效果的时候我们得分析下,要实现这个功能,我们需要什么技术。

所需技术

1.滑动,你可以JavaScript 实现 也可以用 CSS3 实现。这里我用CSS3 实现。

2.JavaScript 事件绑定解绑、事件禁用。

从上面所需的技术可以得知要想做这个效果其实不难。好了下面我们开始吧。

这里有一个初步实现的 Demo 1:http://yunkus.com/demo/mobile-slide-side-nav-bar/index.html ,这其实是一个半成品。

当你在不滚动页面内容的情况下,点击导航后效果是没问题的,但是当你滚动内容后再点击导航按钮,那么你会发现当菜单从左侧滑出时,右侧内容顶部本来应该是固定的顶部的导航不见了。这是什么回事?原来 fixed 属性会受到transform: translate3d()属性的影响。如果给元素设置了transform: translate3d()那么 fixed 就会失效。那这个问题要怎么解决呢?

方法一:可以通过JavaScript 来删除transform: translate3d()那,当导航关闭时,把style=”transform: translate3d(0px, 0px, 0px);”这个行内样式删掉,即JavaScript 代码里的:me.contentCtrl.removeAttr(“style”);但这种方法还是有一些瑕疵的。就是当你滑出导航菜单时,右侧内容的这个顶部导航会暂时消失了,当你关闭滑动导航时,它又会回来了,并且会很明显地出场。具体效果可以看Demo1 。

方法二:我们不妨换一种思路来实现这个 fixed 效果。用position:absolute;配合overflow:auto来替代position:fixed。我们只需要对上面的代码稍作修改就可以了。修改后的Demo 2 :http://yunkus.com/demo/mobile-slide-side-nav-bar/index-2.html 。下面是一张横屏的效果图:

移动端侧滑导航、侧滑菜单效果

在做这个效果的时候,会遇到几个坑:

1.fixed 固定问题。

2.滑动出现卡顿。

3.事件禁用问题。

第一个问题我们已经解决了,现在来说说第二个问题,为什么会出现卡顿,一开始我做的时候,我用给transform: translate3d()传的是百分比值,当我把这个百分比值改成具体的像素值时这个卡顿问题就解决了。就像本例子中的侧边的导航宽度设置为70%,一开始我就设置了右边内容transform: translate3d(70%,0,0),虽然效果是实现了,但来回切换几次后就会出现明显的卡顿现象。解决方法就是把这个70% 通过 JavaScript 来计算出来,并动态赋值给translate3d,这个应该不难。关于最后一个问题:事件禁用。为什么要禁用一些默认的行为?因为当你点击按钮滑出导航后,你会发现右边的内容还是可以通过鼠标滚轮滚动内容,或者在手机里滑动。这时我们就需要禁止浏览器的一些默认行为,比如鼠标滚轮,手机滑屏。在想实现这个也非常简单。在导航滑出后,触发下相应的preventDefault()方法就可以了。而收起导航后,取消这两个事件监听就可以,如果不取消,那么就会导致正常情况下浏览器无法滚动。

完整的 JavaScript 代码如下:

menuSide = {
    run: function(){
         var me = $(this)[0];
         me.getElement();
         me.bindElement();
    },

    getElement: function(){
        var me = $(this)[0];
        me.sideTrigger = $("#side-trigger");
        me.sideCtrl = $("#side-ctrl");
        me.contentCtrl = $("#content-ctrl");
        me.maskTrigger = $("#mask-trigger");
        me.navCloseCtrl = $("#nav-close-ctrl");
        me.flag = true; // 默认关闭
    },

    bindElement: function(){
        var me = $(this)[0];
        me.sideTrigger.bind("click",function(event){
          me.dealFn(event);
        });
        me.maskTrigger.bind("click",function(event){
           me.dealFn(event);
        });
        me.navCloseCtrl.bind("click",function(event){
           me.dealFn(event);
        });

    },

    dealFn: function(event){
        var me = $(this)[0];
         var sideCtrlWidth = Math.floor(me.sideCtrl.width());
        me.contentCtrl.toggleClass("side-trigger-active");

        var preventDefaultEvent = function(){
            me.maskTrigger.bind("wheel",function(event){
                preventEvent(event);
            });
            me.maskTrigger.bind("touchmove",function(event){
                preventEvent(event);
            });
        };
        var preventEvent = function(event){
            event.preventDefault();
            event.stopPropagation(); // 不管是例子一还是例子二,这行代码可以注释掉
        };

        var slideMove = function(distance){
             distance = distance || 0;
             me.contentCtrl.css({
                "transform":'translate3d('+distance+'px,0,0)'
            });
        }
        if(me.flag){
            slideMove(sideCtrlWidth);
            preventDefaultEvent();
        }else{
            me.maskTrigger.unbind("wheel");
            me.maskTrigger.unbind("touchmove");
            slideMove();
            me.contentCtrl.removeAttr("style"); // 如果是例子二,那么这行代码就可以注释掉
        }
        me.flag = !me.flag;
    }
} 

在这一段 JavaScript 中有几个地方可能需要说明下:

授课时间

1.$(this)[0],这个就是获取当前对象。跟原生的this等价,注意: 在例子中的$(this)[0]是通过jQuery方法来获取的,如果你直接$(this)是不正确的,这个是一个 jQuery 对象,而真正的 “this” 则是在这个对象里头。

2.me 就是 menuSide 对象每个方法一开始都先把这个对象($(this)[0])传进来,然后就可以使用这个对象下的所有方法及属性了。

3.flag 就是用于标记侧边导航当前的状态(滑出 | 隐藏)

做完了两个demo 后,我有了一个小发现,demo 2 竟然可以在不禁用浏览器默认的滚动行为下,也实现了滑出导航后右侧内容不可被动的效果(至少在 Android 机上,苹果机未测)。

更新于:22:54 2017/3/27

Demo 1 还有一个问题就是在 Iphone 的 Safari 浏览器浏览时滚动会出现不流畅的情况。并且当你滚动内容后,点击按钮滑出导航,再收起侧边导航时你会发现顶部的菜单竟然不重新固定在浏览器窗口面部了。所以Demo 1 的坑是非常多的,如果想不管在 Android 机上还是 Iphone 上都能有最好的用户体验,那么请选择 Demo 2 的方法。

更新于:7:24 2017/6/9

在把文章发到头条号的时候又无意间发现了一个问题,那就是当我切换到横屏的时候,点击菜单按钮弹出菜单后,如果左侧菜单超出了屏幕的高度,那么就会出现如下图所示的问题(页面可滚动,见下图底部空白处):

侧滑菜单效果

要想解决这个问题可以给.side 里的 ul 两个属性就可以了: overflow-y:scrollheight:100%

.side ul{
    overflow-y: scroll;
    height:100%;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 0;
    width: 70%;
    height: 100%;
    background: #333;
}

 

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/mobile-slide-side-nav-bar/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

评论 END