2020年史上最全移动端Web整理从开发基础到实战(二)

file

一、Zepto简介

file

Zepto是一个轻量级的针对现代高级浏览器的 JavaScript库, 它与jquery有着类似的api。

Zepto 主要使用在移动端浏览器上面,由于移动端的浏览器都是比较新的平台,而 jQuery 主要是在 PC 上为了浏览器的兼容性而使用的,所以在移动端一般不使用 jQuery,因为它的兼容性失去了意义。

Zepto 就是移动端代替 jQuery 的 js 库,它封装了很多关于手势操作的方法。如果你会用jquery,那么你也会用zepto。

Zepto js 库文件的下载地址:https://github.com/madrobby/zepto,直接下载源码文件,相应的所有 js 文件就在 src 目录下。

二、手势事件封装

Zepto 将移动端的 touchStarttouchmovetouchEnd 封装成了一系列事件。

tap :触摸屏幕时触发。

singleTap :单击屏幕时触发

doubleTap:双击屏幕时触发。(如果你不需要检测单击、双击,使用 tap 代替)。

longTap :长按时触发。当一个元素被按住超过750ms触发。

swipe:滑动屏幕时触发。

swipeLeft, swipeRight, swipeUp, swipeDown:屏幕左滑,右滑,上滑,下滑时触发。

三、Zepto 模块化

Zepto 有一点和 jQuery 是不同的,就是 Zepto 是分模块的。在使用的时候不是像 jQuery 只需要引入一个 js 文件就可以了。Zepto 是分模块的。

默认的 Zepto.js 文件只包含下面一些功能:

zepto核心模块;包含许多方法
event通过on()& off()处理事件
ajaxXMLHttpRequest 和 JSONP 实用功能
form序列化 & 提交web表单
ie增加支持桌面的Internet Explorer 10+和Windows Phone 8。

如果要使用到其他的功能,就需要包含其他的 js 文件:

detect.js提供 $.os$.browser消息
fx.jsThe animate()方法
fx_methods.js以动画形式的 show, hide, toggle, 和 fade*()方法.
assets.js实验性支持从DOM中移除image元素后清理iOS的内存。
data.js一个全面的 data()方法, 能够在内存中存储任意对象。
deferred.js提供 $.Deferredpromises API. 依赖"callbacks" 模块. 当包含这个模块时候, $.ajax() 支持promise接口链式的回调。
callbacks.js为"deferred"模块提供 $.Callbacks
selector.js实验性的支持 jQuery CSS 表达式 实用功能,比如 $('div:first')el.is(':visible')
touch.js在触摸设备上触发tap– 和 swipe– 相关事件。这适用于所有的touch(iOS, Android)和pointer事件(Windows Phone)。
gesture.js在触摸设备上触发 pinch 手势事件。
stack.js提供 andSelf& end()链式调用方法
ios3.jsString.prototype.trim 和 Array.prototype.reduce 方法 (如果他们不存在) ,以兼容 iOS 3.x.

所以,每次在使用到某一个功能的时候,就需要到 html 文件下添加相应的 js 库文件,这样就比较繁琐,更重要的是多个 js 文件会增加访问服务器的次数,那么我们可不可以像 jQuery 一样,只包含一个 js 库文件就包括所有的功能呢?

答案是肯定的。

四、Zepto 的定制

Zepto 允许将多个 js 文件打包成一个 js 文件。

操作步骤:

1、安装 Nodejs 环境

2、下载 zepto.js 源码并解压好。

3、cmd 命令行进入解压缩后的目录

4、执行npm install 命令(这一步需要联网下载)

5、编辑 zepto.js 源码中的 make文件,添加自定义模块并保存,如下

原来的:modules = (env['MODULES'] || 'zepto event ajax form ie').split(' ')

增加自己需要的模块:modules = (env['MODULES'] || 'zepto event ajax form ie fx selector touch').split(' ')

6、然后执行命令 npm run-script dist(这一步会在当前目录生成一个dist文件夹)
7、查看目录 dist ,里面就有我们打包好的 zepto.js 库文件。

五、使用 zepto 实现京东移动首页

相关源码已放置 Github

以下为详细代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="./css/base.css">
    <link rel="stylesheet" href="./css/index.css">
    <!-- <script src="./js/index.js"></script> -->
    <script src="./zepto-master/src/zepto.min.js"></script>
    <script src="./zepto-master/src/fx.js"></script>
    <script src="./zepto-master/src/selector.js"></script>
    <script src="./zepto-master/src/touch.js"></script>
    <script src="./js/index-zepto.js"></script>
</head>

<body>
    <div class="jd">
        <!-- 搜索栏开始 -->
        <div class="search">
            <a href="javascript:;" class="search-logo"></a>
            <form action="" class="search-text">
                <input type="text" placeholder="请输入商品名称">
            </form>
            <a href="javascript:;" class="search-login">登录</a>
        </div>
        <!-- 搜索栏结束 -->

        <!-- 轮播图开始 -->
        <div class="slideshow">
            <ul class="slideshow-img clearfix">
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/l1.jpg" alt="">
                    </a>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/l2.jpg" alt="">
                    </a>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/l3.jpg" alt="">
                    </a>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/l4.jpg" alt="">
                    </a>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/l5.jpg" alt="">
                    </a>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/l6.jpg" alt="">
                    </a>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/l7.jpg" alt="">
                    </a>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/l8.jpg" alt="">
                    </a>
                </li>
            </ul>
            <ul class="slideshow-dot">
                <li class="select"></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
            </ul>
        </div>
        <!-- 轮播图结束 -->

        <!-- 导航栏开始 -->
        <div class="nav">
            <ul class="nav-ul clearfix">
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/nav0.png">
                    </a>
                    <p>商品分类</p>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/nav1.png">
                    </a>
                    <p>商品分类</p>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/nav2.png">
                    </a>
                    <p>商品分类</p>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/nav3.png">
                    </a>
                    <p>商品分类</p>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/nav4.png">
                    </a>
                    <p>商品分类</p>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/nav5.png">
                    </a>
                    <p>商品分类</p>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/nav6.png">
                    </a>
                    <p>商品分类</p>
                </li>
                <li>
                    <a href="javascript:;">
                        <img src="./uploads/nav7.png">
                    </a>
                    <p>商品分类</p>
                </li>
            </ul>
        </div>
        <!-- 导航栏结束 -->

        <!-- 主体内容开始 -->
        <div class="content">
            <div class="content-box clearfix content-box-sk">
                <div class="content-title">
                    <span class="content-title-left-clock"></span>
                    <span class="content-title-left-text fl">掌上秒杀</span>
                    <div class="content-title-left-time fl">
                        <span>0</span>
                        <span>0</span>
                        <span>:</span>
                        <span>0</span>
                        <span>0</span>
                        <span>:</span>
                        <span>0</span>
                        <span>0</span>
                    </div>
                    <span class="content-title-right fr">更多秒杀...</span>
                </div>
                <lu class="content-ul clearfix">
                    <li>
                        <a href="javascript:;">
                            <img src="./uploads/detail01.jpg" alt="" class="br">
                        </a>
                        <p>¥10.00</p>
                        <p class="content-ul-delete">¥20.00</p>
                    </li>
                    <li>
                        <a href="javascript:;">
                            <img src="./uploads/detail01.jpg" alt="" class="br">
                        </a>
                        <p>¥10.00</p>
                        <p class="content-ul-delete">¥20.00</p>
                    </li>
                    <li>
                        <a href="javascript:;">
                            <img src="./uploads/detail01.jpg" alt="">
                        </a>
                        <p>¥10.00</p>
                        <p class="content-ul-delete">¥20.00</p>
                    </li>
                </lu>
            </div>
            <div class="content-box clearfix">
                <div class="content-title">
                    <h3>京东超市</h3>
                </div>
                <lu class="content-ul">
                    <li class="fl">
                        <a href="javascript:;">
                            <img src="./uploads/cp1.jpg" alt="">
                        </a>
                    </li>
                    <li class="fl bl bb">
                        <a href="javascript:;">
                            <img src="./uploads/cp2.jpg" alt="">
                        </a>
                    </li>
                    <li class="fl bl">
                        <a href="javascript:;">
                            <img src="./uploads/cp3.jpg" alt="">
                        </a>
                    </li>
                </lu>
            </div>
            <div class="content-box clearfix">
                <div class="content-title">
                    <h3>京东超市</h3>
                </div>
                <lu class="content-ul">
                    <li class="fr">
                        <a href="javascript:;">
                            <img src="./uploads/cp4.jpg" alt="">
                        </a>
                    </li>
                    <li class="fl bl bb">
                        <a href="javascript:;">
                            <img src="./uploads/cp5.jpg" alt="">
                        </a>
                    </li>
                    <li class="fl bl">
                        <a href="javascript:;">
                            <img src="./uploads/cp6.jpg" alt="">
                        </a>
                    </li>
                </lu>
            </div>
        </div>
        <!-- 主体内容结束 -->
    </div>
</body>

</html>

js 文件:

$(function () {  
    // 1.在开始和最后位置添加图片
    // 2.重新设置图片盒子的宽度和图片的宽度
    // 3.添加定时器,自动轮播
    // 4.添加过渡结束事件
    // 5.设置小白点
    // 6.添加手动轮播

    // 获取元素
    var ulObj = $(".slideshow-img");
    var first = ulObj.find("li:first-of-type");
    var last = ulObj.find("li:last-of-type");

    var bannerWidth = $(".slideshow").width();

    // 在开始和最后位置添加图片
    ulObj.append(first.clone());
    last.clone().insertBefore(first);

    // 重新设置图片盒子的宽度和图片的宽度
    var liObjs = ulObj.find("li");

    ulObj.width(liObjs.length +"00%");
    liObjs.each(function (index) {  
        // 数组是DOM操作,要转换成zepto元素
        $(liObjs[index]).width(bannerWidth);
    });    

    // 设置默认显示第一张图
    ulObj.css("transform", "translateX("+ -bannerWidth +"px)");

    var index = 1;

    // 盒子改变大小的时候重现设置图片盒子的宽度和图片的宽度
    $(window).on("resize", function () {  
        ulObj.width(liObjs.length +"00%");
        liObjs.each(function (index) {  
            // 数组是DOM操作,要转换成zepto元素
            $(liObjs[index]).width($(".slideshow").width());            
        });
        ulObj.css("transform", "translateX("+ -$(".slideshow").width()*index +"px)");
    });

    // 轮播动画函数
    var setAnimate = function () {  
        ulObj.animate(
            {"transform": "translateX("+ -$(".slideshow").width()*index +"px)"},
            500,
            "linear",
            function () {  // 过渡结束事件回调函数
                if(index == 0) {
                    index = liObjs.length -2;
                    ulObj.css("transform", "translateX("+ -$(".slideshow").width()*index +"px)");
                } else if(index == liObjs.length -1) {
                    index = 1;
                    ulObj.css("transform", "translateX("+ -$(".slideshow").width()*index +"px)");
                }
                // 设置小白点
                $(".slideshow-dot").children("li").removeClass("select").eq(index-1).addClass("select");          
    
            }
        );
    };

    var timerId;
    // 添加定时器,自动轮播
    var timerStart = function () {  
        timerId = setInterval(function () {  
            index++;
            setAnimate();
        }, 1500);
    };
    timerStart();

    // 手动轮播操作
    ulObj.on("swipeLeft", function () {
        clearInterval(timerId);
        index++;
        setAnimate();
        //手动轮播操作完成后再开启定时器
        timerStart();
    });
    ulObj.on("swipeRight", function () {
        clearInterval(timerId);
        index--;
        setAnimate();
        // 手动轮播操作完成后再开启定时器
        timerStart();
    });

    //------------------------------------------------

    // 搜索栏上下滚动时改变透明度
    var bannerEffect = function () {  
        var bannerObj = $(".search");
        var slideshowObj = $(".slideshow");
        var bannerHeight = bannerObj.height();
        var imgHeight = slideshowObj.height();
        // console.log(bannerHeight + '  ' + imgHeight);

        $(window).on("scroll", function (e) {  
            var scrollHeight = $(window).scrollTop();            
            if(scrollHeight < (imgHeight-bannerHeight)) {
                var setopacity = scrollHeight / (imgHeight-bannerHeight);
                bannerObj.css("backgroundColor", "rgba(233, 35, 34,"+setopacity+")");
            }
            
        });
        
    };
    bannerEffect();

    //-----------------------------------------------------

    // 设置倒计时
    var timerCount = function () {  
        var timers = $(".content-title-left-time").children("span");
        var titleCount = 2*60*60;

        var timerId = setInterval(function () {  
            titleCount--;
            var hour = Math.floor(titleCount / 3600);
            var minute = Math.floor((titleCount % 3600) / 60);
            var second = titleCount % 60;

            if(titleCount >= 0) {
                $(timers[0]).html(Math.floor(hour / 10));
                $(timers[1]).html(hour % 10);
                $(timers[3]).html(Math.floor(minute / 10));
                $(timers[4]).html(minute % 10);
                $(timers[6]).html(Math.floor(second / 10));
                $(timers[7]).html(second % 10);
            } else {
                titleCount = 0;
                clearInterval(timerId);
                return;
            }

        }, 1000);
    };
    timerCount();

});

六、实现JD分类页面

我们先看看要实现的效果图:

file

1、项目需求:

  • 全屏页面
  • 右侧的页面随着页面宽度的变化而变化,左侧栏宽度固定不变。
  • 左侧栏可以上下滑动,如果滑动超出上下范围自动反弹回去
  • 点击左侧栏每个项目,自动滚动左侧栏使得项目置顶
  • 当点击项目可能使得超出滑动范围的时候,以滑动范围为准,当前点击的项目不必置顶。

2、项目分析

如何实现一个全屏页面,没有滚动条?

如下面的结构:大盒子1和大盒子2分为上下结构,小盒子3和小盒子4在大盒子2的内部,分为左右结构。

file

那么如何排布,使得上下左右都没有滚动条呢?

思路:

1、要使得大盒子1和大盒子2上下没有滚动条,可以使得大盒子1 的宽度为 100%,高度加入100px,大盒子2的高度 100%;这时会超出100px的高度,如果这时我们让大盒子1定位(position:absolute;),,确实可以实现上下没有滚动条,但是大盒子的头部100px 的位置会被覆盖,所以再让大盒子2 padding-top: 100px; 就可以了。

2、要使得小盒子3和小盒子4左右没有滚动条,可不可以参考大盒子1和大盒子2的策略呢?让小盒子3 宽度100px,高度100%,小盒子4宽度100%,高度100%,然后小盒子3定位(position:absolute;),这是不可以的,因为小盒子3的高度是100%,参照父盒子(大盒子2)的,所以高度是整个视口的高度,而大盒子1占了位置,所以小盒子3只能往下挪,在底部冲出100px的大小,无法弥补。

那么怎么办呢?

第一,可以将小盒子3定位(position:absolute;)改为浮动(float:left);

第二,可以取消大盒子2的宽度100%,改为 margin-left:100px;小盒子3依然浮动(float:left),也是可以的。

第三,BFC区域不与浮动区域重叠,而将一个区域变成BFC区域可以使用overflow:hidden;

BFC主要三个特点:

  • BFC区域不会与float区域重叠(对应两栏布局)
  • BFC容器中的子元素,不会影响到外边。(对应子元素margin-top会传递到父元素,清除方法可以使用overflow:hidden,position:absolute/flex; display:inline-block/flex/table-cell;)
  • 计算BFC的高度时,浮动元素也参与计算(对应清除浮动的三个方法,都是让父元素成为BFC区域)

3、示例代码:

相关源码以放置 Github:https://github.com/Daotin/Web/tree/master/Code/src/11/jd.zip

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="./css/base.css">
    <link rel="stylesheet" href="./css/category.css">
    <script src="./js/category.js"></script>
    <script src="./js/tap.js"></script>
    <title>Document</title>
</head>
<body>
    <div class="layout">
        <!-- 头部header -->
        <div class="header">
            <div class="header-back"></div>
            <form action="" class="header-text">
                <input type="text" placeholder="请输入商品名称">
            </form>
            <div class="header-menu"></div>
        </div>
        <!-- 主体main -->
        <div class="main">
            <div class="main-left">
                <span>拉这么多想干嘛?</span>
                <ul>
                    <li class=""><a href="javascript:;">热门推荐</a></li>
                    <li class="active"><a href="javascript:;">潮流女装</a></li>
                    <li class=""><a href="javascript:;">品牌男装</a></li>
                    <li class=""><a href="javascript:;">内衣配饰</a></li>
                    <li class=""><a href="javascript:;">家用电器</a></li>
                    <li class=""><a href="javascript:;">电脑办公</a></li>
                    <li class=""><a href="javascript:;">手机数码</a></li>
                    <li class=""><a href="javascript:;">母婴频道</a></li>
                    <li class=""><a href="javascript:;">图书</a></li>
                    <li class=""><a href="javascript:;">家居家纺</a></li>
                    <li class=""><a href="javascript:;">居家生活</a></li>
                    <li class=""><a href="javascript:;">家具建材</a></li>
                    <li class=""><a href="javascript:;">热门推荐</a></li>
                    <li class=""><a href="javascript:;">潮流女装</a></li>
                    <li class=""><a href="javascript:;">品牌男装</a></li>
                    <li class=""><a href="javascript:;">内衣配饰</a></li>
                    <li class=""><a href="javascript:;">家用电器</a></li>
                    <li class=""><a href="javascript:;">电脑办公</a></li>
                    <li class=""><a href="javascript:;">手机数码</a></li>
                    <li class=""><a href="javascript:;">母婴频道</a></li>
                    <li class=""><a href="javascript:;">图书</a></li>
                    <li class=""><a href="javascript:;">家居家纺</a></li>
                    <li class=""><a href="javascript:;">居家生活</a></li>
                    <li class=""><a href="javascript:;">家具建材</a></li>
                </ul>
            </div>
            <div class="main-right">
                <a href="javascript:;" class="main-right-img">
                    <img src="./uploads/banner_1.jpg" alt="">
                </a>
                <h3>商品分类</h3>
                <div class="main-right-cate">
                    <ul>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                        <li>
                            <a href="javascript:;">
                                <img src="./uploads/nv-fy.jpg" alt="">
                                <p>毛衣</p>
                            </a>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

CSS 代码:

html, body {
    width: 100%;
    height: 100%;
}

.layout {
    width: 100%;
    height: 100%;
}

/* 头部header */
.header {
    width: 100%;
    height: 50px;
    background-color: #eee;
    border-bottom: 1px solid #ccc;
    position: absolute;
}
.header-back,
.header-menu {
    width: 50px;
    height: 50px;
    background: url("../images/jd-sprites.png");
    background-size: 200px 200px;
    position: absolute;
    top: 0;
    padding: 15px;
    background-origin: content-box;
    background-clip: content-box;
}
.header-back {
    background-position: -20px 0;
    left: 0;
}
.header-menu {
    background-position: -60px 0;
    right: 0;
}
.header-text {
    padding: 0 60px;
}
.header-text > input {
    width: 100%;
    height: 30px;
    margin-top: 10px;
    border-radius: 10px;
    padding-left: 10px;
    font-size: 16px;
    color: #aaa;
}


/* 主体main */
.main {
    width: 100%;
    height: 100%;
    padding-top: 50px;
}
.main-left {
    width: 100px;
    height: 100%;
    float: left;
    overflow: hidden;
    position: relative;
    background: #eee;
}
.main-left > span {
    display: inline-block;
    width: 100%;
    font-size: 10px;
    color: #ccc;
    text-align: center;
    margin-top: 80px;
}
.main-left ul {
    width: 100px;
    position: absolute;
    left: 0;
    top: 0;
}
.main-left ul li {
    width: 100%;
    height: 50px;
    line-height: 50px;
    text-align: center;
    border-right: 1px solid #ccc;
    border-bottom: 1px solid #ccc;
    background-color: #eee;
}
.main-left li.active {
    background-color: #fff;
    border-bottom: 1px solid #ccc;
    border-right: 1px solid #ccc;
}
.main-left li.active a {
    color: #e92322;
}
.main-left a {
    display: block;
    width: 100%;
    height: 50px;
    color: #666;
}
.main-right {
    /* width: 100%; */
    height: 100%;
    margin-left: 100px;
    /* 设置为伸缩盒子 */
    display: flex;
    flex-direction: column;
}
.main-right-img {
    width: 100%;
}
.main-right-img > img {
    width: 100%;
    /* 消除基线 */
    display: block;
}
.main-right > h3 {
    font-size: 14px;
    font-weight: bold;
    color: #333;
    margin: 10px 0 10px 5px;
}
.main-right-cate {
    width: 100%;
    /* 下面两个一起使得没有上下滚动条 */
    flex: 1;
    overflow: hidden;
}

.main-right-cate> ul {
    width: 100%;
}
.main-right-cate > ul > li {
    width: 33.33%;
    text-align: center;
    float: left;
}

原生 js 代码:

window.onload = function () {  
    leftSlideEffect();
};

// 左侧滑动栏效果和点击效果
function leftSlideEffect() {  
    // 添加左侧栏的滑动效果
    var mainObj = document.querySelector(".main");
    var leftUlObj = document.querySelector(".main-left").children[1];

    var mainLeftHeight = document.querySelector(".main-left").offsetHeight;
    var leftUlObjHeight = leftUlObj.offsetHeight;

    var liObjs = leftUlObj.querySelectorAll("li");


    var startY=0; // 起始位置
    var diffY=0;  // 滑动后与起始位置的偏移
    var currentY=0; // 保存每次滑动后的偏移

    var maxTop = 0; // 最大top偏移值
    var minTop = mainLeftHeight-leftUlObjHeight; // 最大top偏移值
    var maxBounceTop = maxTop + 100; //弹性最大高度
    var minBounceTop = minTop - 100; //弹性最小高度
    leftUlObj.addEventListener("touchstart", function(e) {
        // 计算起始坐标
        startY = e.targetTouches[0].clientY;
    });

    leftUlObj.addEventListener("touchmove", function(e) {
        /*计算距离的差异*/
        diffY = e.targetTouches[0].clientY - startY;
        /*判断滑动的时候是否超出当前指定的滑动区间*/
        if((diffY+currentY > maxBounceTop) || (diffY+currentY < minBounceTop)) {
            return;
        }
        /*先将之前可能添加的过渡效果清除*/
        leftUlObj.style.transition = "none";
        /*实现偏移操作:应该在之前的滑动距离的基础之上再进行滑动*/
        leftUlObj.style.top = diffY+currentY + "px";
    });

    leftUlObj.addEventListener("touchend", function() {
        
        if(diffY+currentY > maxTop) {
            // 回到maxTop位置,设置currentY当前值
            leftUlObj.style.transition = "top 0.5s"
            leftUlObj.style.top = maxTop + "px";
            currentY = maxTop;
        } else if(diffY+currentY < minTop) {
            // 回到minTop位置,设置currentY当前值
            leftUlObj.style.transition = "top 0.5s"
            leftUlObj.style.top = minTop + "px";
            currentY = minTop;
        } else {
            // 记录当前滑动的距离
            currentY += diffY;
        }
    });

   // -----------------------------------------------------
  
  	// 左侧滑动栏点击效果
    /*为每一个li元素设置添加一个索引值*/
    for(var i=0; i<liObjs.length; i++) {
        // liObjs是对象,给对象增加属性值
        liObjs[i].index = i;
    }
    // 点击事件
    fingerTap.tap(leftUlObj, function (e) {
        // 清除所有li标签
        for(var i=0; i<liObjs.length; i++) {
            liObjs[i].classList.remove("active");
        }
        //设置点击的li标签的样式
        var indexLi = e.target.parentElement;
        
        indexLi.classList.add("active");
        // 每个li标签的高度
        var indexLiHeight = indexLi.offsetHeight;

        /*2.移动当前的li元素到父容器的最顶部,但是不能超出之前设定了静止状态下的最小top值*/
        leftUlObj.style.transition = "top 0.5s";

        if(-indexLiHeight*indexLi.index < minTop) {
            leftUlObj.style.top = minTop + "px";
            // 记得重置currentY的值
            currentY=minTop;
        } else {
            leftUlObj.style.top = -indexLiHeight*indexLi.index + "px";
            // 记得重置currentY的值
            currentY=-indexLiHeight*indexLi.index;
        }
    });
}

把点击事件封装成一个单独 js 库,tap.js。

// 封装移动端的tap事件

var fingerTap = {
    tap: function (dom, callback) {  
        // 判断dom是否存在
        if((!dom) || (typeof dom != "object")) {
            return;
        }
        var startX, startY, endX, endY, startTime, endTime;
        dom.addEventListener("touchstart", function (e) {  
            // 不止一个手指
            if(e.targetTouches.length > 1) {
                return;
            }
            startX = e.targetTouches[0].clientX;
            startY = e.targetTouches[0].clientY;
            
            // 点击时记录毫秒数
            startTime = Date.now(); 

        });

        dom.addEventListener("touchend", function (e) {
            // 不止一个手指
            if(e.changedTouches.length > 1) {
                return;
            }
            // 之所以使用changedTouches,是因为手指离开后就没有targetTouches了
            endX = e.changedTouches[0].clientX;
            endY = e.changedTouches[0].clientY;
            // 记录离开手指的毫秒数
            endTime = Date.now();
            //如果是长按操作就返回
            if(endTime - startTime > 300) {
                return;
            }
            // 判断从按下到抬起手指在一定的范围滑动也算tap事件
            if((Math.abs(endX-startX) <= 6) && (Math.abs(endY-startY) <= 6)) {
                // tap点击事件的处理函数
                callback && callback(e);
            }
        });
    }
};

4、使用 Zepto 实现点击操作

上面 tap.js 是我们自己封装的点击事件,其实在 Zepto 中,已经封装好了 tap 单击事件,我们可以直接使用。

只需要将

fingerTap.tap(leftUlObj, function (e) {});

改为:

$(leftUlObj).on("tap", function() {});

就可以实现相同的效果。

最后

还有2件事拜托大家

一:求赞 求收藏 求分享 求留言,让更多的人看到这篇内容

二:欢迎添加我的个人微信

备注“资料”, 300多篇原创技术文章,海量的视频资料即可获得

备注“加群”,我会拉你进技术交流群,群里大牛学霸具在,哪怕您做个潜水鱼也会学到很多东西

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值