博客列表 >懒加载和选项卡--2019/07/15

懒加载和选项卡--2019/07/15

LISTEN的博客
LISTEN的博客原创
2019年07月22日 16:30:53660浏览
  1. 写现懒加载的实现原理,并代码实例演示

    * 可视区高度: 用户可以看到的窗口高宽,通常小于文档高度
    * 滚动距离: 有滚动条的情况下,元素滚动条顶部到窗口顶部的距离
    * 自定义属性: data-为前缀的自定义元素属性
    * 滚动事件`scroll`: 当窗口滚动时触动发
    * 加载事件`load`: 当html文档与资源全部加载完成时触发

    实例

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>懒加载</title>
    </head>
    <body style="height: 2000px">
    
    <script>
        var container=document.createElement('div');
        container.setAttribute('align','center');
    
        // 创建文档片段, 可以理解为保存在内存中的页面中的小组件
        // createdocumentfragment()方法创建了一虚拟的节点对象,节点对象包含所有属性和方法。
        var frag=document.createDocumentFragment();
    
        // 页面中的图片,我们全部动态创建,使用文档片段提升加载效率
        for(var i=1;i<=8;i++){
            var imgUrl='images/'+i+'.jpg';
            var img=document.createElement('img');
    
            // 设置统一显示的占位图片
            img.setAttribute('src','images/loading.gif');
    
            // 将真实的图片地址保存到自定义属性data-src中
            img.setAttribute('data-src',imgUrl);
    
            // 自定义图片样式
            img.setAttribute('style','width:600px;height:300px;margin:5px;');
    
            // 先把图片添加到文档片段中, 因为是在内存中操作, 不会引起页面抖动,也不会触发大量的DOM操作
            frag.appendChild(img);
    
        }
    
        // 将保存在文档片段中的所有图片添加到容器中
        container.appendChild(frag);
        // 再把容器,插入到页面的唯一元素<script>之前
        document.body.insertBefore(container,document.body.firstElementChild);
    
        // 监听窗口的滚动事件, 当用户拉到滚动条时, 自动触发自定义的图片懒加载事件方法
        window.addEventListener('scroll',lazyLoaded,false);
    
        // 自定义懒加载事件方法
        function lazyLoaded() {
            // documentElement 属性可返回文档的根节点。<html>
            // console.log(document.documentElement);//获取<html>
            // 获取滚动高度
            var scrollTop=document.documentElement.scrollTop;
    
            // 可视区高度
            var clientHeight=document.documentElement.clientHeight;
    
            // 图片懒加载
            // 获取所有图片,并转为数组
            var imgs = document.images;
            var imgArr=Array.prototype.slice.call(imgs,0);
    
            // 遍历所有图片,确定哪些需要显示出来
            imgArr.forEach(function (img) {
                // 关键步骤: 当图片进入到窗口可视区时需要显示出来
                // 图片顶部的距离如果小于可视区高度与可视区滚动距离之和时,说明已进入可视区
                if(img.offsetTop<=(scrollTop+clientHeight)){
                    // 设置img真实的src图片地址,并显示出来
                    img.setAttribute('src',img.dataset.src);
                }
            });
        }
    
        // 发现首次显示的时候,没有图片被加载,需要再添加一个load事件的监听器
        // load: 当页面加载完成会自动调用
        window.addEventListener('load',lazyLoaded,false);
    
    </script>
    </body>
    </html>

    运行实例 »

    点击 "运行实例" 按钮查看在线实例

    运行结果:懒加载.png


2. 写出选项卡的实现原理, 并代码实例演示

* 自定义属性: 标签页与详情页通过`data-index`建立关联
* classList: 优雅的操作元素的类样式
* forEach(): 优雅的遍历数组对象,注意参数是一个回调函数

实例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>选项卡</title>
    <style>
        ul,li{
            margin: 0;
            padding: 0;
            list-style: none;
        }
        a{
            text-decoration: none;
        }
        a:hover{
            color: red;
            text-decoration-color: red;
            text-decoration-line:underline ;/*underline	定义文本下的一条线。*/
        }

        .tab-container{
            width: 450px;
            height: 300px;
        }
        .tab-nav{
            /*清浮动*/
            overflow: hidden;
        }
        .tab-nav ul li{
            float: left;
            width: 150px;
            height: 60px;
            line-height: 60px;
            text-align: center;
            font-size: 1.2rem;
        }
        .tab-nav .active{
            background-color: lightblue;
            border-bottom: 1px solid red;
        }

        .tab-content .detail{
            line-height: 35px;
            min-height: 200px;
            padding: 20px 10px;
            display: none;
        }
        .tab-content .detail.active{
            background-color: lightblue;
            display: block;
        }

    </style>
</head>
<body>
<div class="tab-container">
    <!--    tab标签导航-->
    <div class="tab-nav">
        <ul>
            <li class="active" data-index="1">HTML/CSS</li>
            <li data-index="2">JavaScript</li>
            <li data-index="3">服务端</li>
        </ul>
    </div>

    <!--    tab标签对应的内容-->
    <div class="tab-content">
        <div class="detail active" data-index="1">
            <ul>
                <li><a href="">HTML</a></li>
                <li><a href="">CSS</a></li>
                <li><a href="">LayUI</a></li>
            </ul>
        </div>
        <div class="detail" data-index="2">
            <ul>
                <li><a href="">JavaScript</a></li>
                <li><a href="">jQuery</a></li>
                <li><a href="">Ajax</a></li>
            </ul>
        </div>
        <div class="detail" data-index="3">
            <ul>
                <li><a href="">PHP</a></li>
                <li><a href="">Java</a></li>
                <li><a href="">C++</a></li>
            </ul>
        </div>
    </div>
</div>

<script>
    // 获取标签页导航tab,以及可点击的所有标签页<li>,并转为数组对象
    var tabnav=document.getElementsByClassName('tab-nav')[0];
    // console.log(tabnav.firstElementChild.children);
    //获取导航tab的所有li标签
    var tabList=tabnav.firstElementChild.children;
    var tabArr=Array.prototype.slice.call(tabList,0);

    // 获取所有详情页,并转为数组对象
    var detail=document.getElementsByClassName('detail');
    var detailArr=Array.prototype.slice.call(detail,0);

    // 利用事件冒泡机制, 将标签页tab的点击事件委托给父级导航条处理
    tabnav.addEventListener('click',showDetail,false);

    // 监听标签tab点击事件
    function showDetail(event) {
        //event.target: 当前被点击的li, event.currentTarget: 被添加的事件的对象,<div.tab_nav>
        // console.log(event.target);
        // console.log(event.currentTarget);

        // 1. 清空原导航标签的样式,并设置当前正在被点击的标签页为当前页
        tabArr.forEach(function (tab) {
            tab.classList.remove('active');
        });
        event.target.classList.add('active');

        // 2. 清空所在详情页样式,并根据与导航data-index属性的对应关系,显示对应的详情页面
        detailArr.forEach(function (detail) {
            detail.classList.remove('active');
        });
        detailArr.forEach(function (detail) {
            // 详情页的index与导航标签的index相同时, 显示该页面
            if(detail.dataset.index===event.target.dataset.index){
                detail.classList.add('active');
            }
        });
    }

    // 还可以添加鼠标移入监听事件
    // tabnav.addEventListener('mouseover',showDetail,false);

</script>
</body>
</html>

运行实例 »

点击 "运行实例" 按钮查看在线实例

运行结果:

选项卡.png

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议