美文网首页编程地带
jsvascript学习(十三)- scroll相关综合案例

jsvascript学习(十三)- scroll相关综合案例

作者: MA木易YA | 来源:发表于2019-01-06 20:53 被阅读0次

案例素材可到这里领取, __提取码:ephx __

1. 商品展示案例

通过导航条滑动可不断看到后面的商品列表

  • 主要难点在于导航条长度与导航条左边距离的理算,类似于之前的等比缩放,详情可参考注释里面的笔记推算
  • 这里涉及几个鼠标事件,onmousedown、onmousemove以及onmouseup,方法中的return false格外需要注意, 如果没有的话在导航条移动过程中就会在两个鼠标事件中产生冲突
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        *{
            margin: 0;
            padding: 0;
            list-style: none;
            border:none;
        }

        #box{
            width: 800px;
            height: 200px;
            border: 1px solid #ddd;

            position: relative;
            margin: 100px auto;

            overflow: hidden;
        }

        #box ul{
            width: 2600px;
            position: absolute;
            left: 0;
            top: 20px;
        }

        #box ul li{
            float: left;
        }

        #box_bottom{
            position: absolute;
            left: 0;
            bottom: 0;
            background-color: #e8e8e8;

            width: 100%;
            height: 25px;
        }

        .mask{
            position: absolute;
            left: 0;
            top:0;
            height: 25px;
            background-color: orangered;
            border-radius: 12px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div id="box">
        <ul id="box_top">
            <li><img src="images/img1.jpg" alt=""></li>
            <li><img src="images/img2.jpg" alt=""></li>
            <li><img src="images/img3.jpg" alt=""></li>
            <li><img src="images/img4.jpg" alt=""></li>
            <li><img src="images/img5.jpg" alt=""></li>
            <li><img src="images/img6.jpg" alt=""></li>
            <li><img src="images/img7.jpg" alt=""></li>
            <li><img src="images/img8.jpg" alt=""></li>
            <li><img src="images/img1.jpg" alt=""></li>
            <li><img src="images/img2.jpg" alt=""></li>
            <li><img src="images/img1.jpg" alt=""></li>
            <li><img src="images/img2.jpg" alt=""></li>
            <li><img src="images/img3.jpg" alt=""></li>
            <li><img src="images/img4.jpg" alt=""></li>
            <li><img src="images/img5.jpg" alt=""></li>
            <li><img src="images/img6.jpg" alt=""></li>
            <li><img src="images/img7.jpg" alt=""></li>
            <li><img src="images/img8.jpg" alt=""></li>
            <li><img src="images/img1.jpg" alt=""></li>
            <li><img src="images/img2.jpg" alt=""></li>
        </ul>
        <div id="box_bottom">
            <span class="mask"></span>
        </div>
    </div>

<script>
    window.onload = function () {
        // 1. 获取需要的标签
        var box = document.getElementById("box");
        var box_top = document.getElementById("box_top");
        var box_bottom = document.getElementById("box_bottom");
        var mask = box_bottom.children[0];

        // 2. 设置滚动条的长度
        // 滚动条长度 = ( 盒子的宽度 / 内容的宽度) * 盒子的宽度
        var mask_len = (box.offsetWidth / box_top.offsetWidth) * box.offsetWidth;
        mask.style.width = mask_len + 'px';

        // 3. 鼠标操作
        mask.onmousedown = function (event) {
            var e = event || window.event;

            // 3.1 求出初始值
            var beginX = e.clientX - mask.offsetLeft;

            // 3.2 移动
            document.onmousemove = function (event) {
                var e = event || window.event;

                // 3.3 求出移动的距离
                var endX = event.clientX - beginX;

                // 边界值
                if(endX < 0){
                    endX = 0;
                }else if(endX >= box.offsetWidth - mask.offsetWidth){
                    endX = box.offsetWidth - mask.offsetWidth;
                }


                // 3.4 动起来
                mask.style.left = endX + 'px';

                // 内容走的距离 = (内容的长度 - 盒子的长度) \/ (盒子长度 - 滚动条的长度) * 滚动条走的距离
                var content_len = (box_top.offsetWidth - box.offsetWidth) / (box.offsetWidth - mask.offsetWidth) * endX;
                box_top.style.left = -content_len + 'px';

                return false;
            };

            document.onmouseup = function () {
                document.onmousemove = null;
            }
        }
    }
</script>
</body>
</html>

2. 瀑布流图片布局案例

按照瀑布流对图片进行布局展示,往下移动会自动生成图片持续展示

  • 难点在于对于图片大小以及屏幕宽度的把握
  • 对于每一排的图片,要计算出高度最低的盒子将下一排第一个盒子插入此处,并对最低高度进行更新,其他的按照这种模式循环处理

index.html:

  <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>瀑布流布局</title>
    <link rel="stylesheet" href="css/index.css">
</head>
<body>
    <div id="main">
        <div class="box"><div class="pic"><img src="images/img01.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img02.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img03.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img04.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img05.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img06.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img07.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img08.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img09.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img10.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img11.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img12.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img13.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img14.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img15.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img16.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img17.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img18.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img19.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img20.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img21.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img22.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img23.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img24.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img25.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img26.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img27.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img28.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img29.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img30.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img31.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img32.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img33.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img34.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img35.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img36.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img37.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img38.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img39.jpg" alt=""></div></div>
        <div class="box"><div class="pic"><img src="images/img40.jpg" alt=""></div></div>
    </div>
<script src="js/Underscore-min.js"></script>
<script src="js/myFunc.js"></script>
<script src="js/index.js"></script>
</body>
</html>

index.js:

window.onload = function () {
    // 1. 实现瀑布流布局
    waterFull("main", "box");

    // 2. 动态加载图片
    window.onscroll = function () {
        if(checkWillLoadImage()){
            // 2.1 造数据
            var dataArr = [
                {"src": "img04.jpg"},
                {"src": "img06.jpg"},
                {"src": "img08.jpg"},
                {"src": "img09.jpg"},
                {"src": "img10.jpg"},
                {"src": "img12.jpg"},
                {"src": "img14.jpg"},
                {"src": "img16.jpg"},
                {"src": "img18.jpg"}
            ];

            // 2.2 创建元素
            for(var i=0; i<dataArr.length; i++){
                var newBox = document.createElement("div");
                newBox.className = "box";
                $("main").appendChild(newBox);

                var newPic = document.createElement("div");
                newPic.className = "pic";
                newBox.appendChild(newPic);

                var newImg = document.createElement("img");
                newImg.src = "images/" + dataArr[i].src;
                newPic.appendChild(newImg);
            }

            // 2.3 重新布局
            waterFull("main", "box");
        }
    }
};

/**
 * 实现瀑布流布局
 */
function waterFull(parent, child) {
    // 1. 父盒子居中
    var allBox = $(parent).getElementsByClassName(child);// 1.1 获取所有的盒子

    // 1.2 获取子盒子的宽度
    var boxWidth = allBox[0].offsetWidth;
    // 1.3 获取屏幕的宽度
    var screenW = document.documentElement.clientWidth;
    // 1.4 求出列数
    var cols = parseInt(screenW / boxWidth);
    // 1.5 父盒子居中
    $(parent).style.width = cols * boxWidth + 'px';
    $(parent).style.margin = "0 auto";


    // 2. 子盒子的定位
    // 2.1 定义高度数组
    var heightArr = [], boxHeight = 0, minBoxHeight = 0, minBoxIndex = 0;
    // 2.2 遍历子盒子
    for (var i = 0; i < allBox.length; i++) {
        // 2.2.1 求出每一个子盒子的高度
        boxHeight = allBox[i].offsetHeight;
        // 2.2.2 取出第一行盒子的高度放入高度数组
        if (i < cols) { // 第一行
            heightArr.push(boxHeight);
        } else { // 剩余行
            // 1. 取出最矮的盒子高度
            minBoxHeight = _.min(heightArr);
            // 2. 求出最矮盒子对应的索引
            minBoxIndex = getMinBoxIndex(heightArr, minBoxHeight);
            // 3. 子盒子定位
            allBox[i].style.position = "absolute";
            allBox[i].style.left = minBoxIndex * boxWidth + 'px';
            allBox[i].style.top = minBoxHeight + 'px';
            // 4. 更新数组中的高度
            heightArr[minBoxIndex] += boxHeight;
        }
    }

    console.log(heightArr, minBoxHeight, minBoxIndex);
}
/**
 * 获取数组中最矮盒子高度的索引
 * @param arr
 * @param val
 * @returns {number}
 */
function getMinBoxIndex(arr, val) {
    for(var i=0; i<arr.length; i++){
        if(arr[i] === val){
            return i;
        }
    }
}
function $(id) {
    return typeof id === "string" ? document.getElementById(id) : null;
}
/**
 * 判断是否具备加载图片的条件
 */
function checkWillLoadImage() {
    // 1. 获取最后一个盒子
    var allBox = document.getElementsByClassName("box");
    var lastBox = allBox[allBox.length - 1];

    // 2. 求出最后一个盒子自身高度的一半 + offsetTop
    var lastBoxDis = lastBox.offsetHeight * 0.5 + lastBox.offsetTop;

    // 3. 求出屏幕的高度
    var screenW = document.body.clientHeight || document.documentElement.clientHeight;

    // 4. 求出页面偏离浏览器的高度
    var scrollTop = scroll().top;

    return lastBoxDis <= screenW + scrollTop;
}

myFunc.js里面是对scroll方法的封装,详情可参考上一节:

/**
 * 获取滚动的头部距离和左边距离
 * scroll().top scroll().left
 * @returns {*}
 */
function scroll() {
    if(window.pageYOffset !== null){
        return {
            top: window.pageYOffset,
            left: window.pageXOffset
        }
    }else if(document.compatMode === "CSS1Compat"){ // W3C
        return {
            top: document.documentElement.scrollTop,
            left: document.documentElement.scrollLeft
        }
    }

    return {
        top: document.body.scrollTop,
        left: document.body.scrollLeft
    }
}

参考:
网易云js课程

相关文章

网友评论

    本文标题:jsvascript学习(十三)- scroll相关综合案例

    本文链接:https://www.haomeiwen.com/subject/vdbfrqtx.html