• webpack封装插件实现骨架屏


    在页面初始时没有加载出来,页面显示一片空白,永不体验不好,就可以使用骨架屏,就是在页面内容还未加载完成的时候,先让一些图片或者固定结构站位,

    待内容加载完成之后把他替换掉

    思路:

    webpack中最终生成的html页面使用的是html-webpack-plugin插件,它提供了一系列的事件,我们可以注册到他处理html之前,使用html-webpack-plugin-before-html-processing事件把骨架屏动态插入进去;

    插件:plugin.js

    骨架屏的代码:

    <div id="app">
        <div style="100%;height:50px;background: rgb(211, 219, 224);"></div>
        <ul class="loading-skeleton" style="">
            <li>
                <div class="d1"></div>
                <div class="d2 o"></div>
                <div class="d2 d"></div>
            </li>
            <li>
                <div class="d1"></div>
                <div class="d2 o"></div>
                <div class="d2 d"></div>
            </li>
            <li>
                <div class="d1"></div>
                <div class="d2 o"></div>
                <div class="d2 d"></div>
            </li>
            <li>
                <div class="d1"></div>
                <div class="d2 o"></div>
                <div class="d2 d"></div>
            </li>
            <li>
                <div class="d1"></div>
                <div class="d2 o"></div>
                <div class="d2 d"></div>
            </li>
            <li>
                <div class="d1"></div>
                <div class="d2 o"></div>
                <div class="d2 d"></div>
            </li>
        </ul>
        <style>
            .loading-skeleton{
                100%;height:auto;list-style: none;overflow: hidden;margin:0;padding:0;
            }
            .loading-skeleton li{
                 40%;
                height: 180px;
                float: left;
                margin: 3% 7% 3% 3%;
            }
            .loading-skeleton li .d1{
                 100%;
                height: 130px;
                background: rgb(211, 219, 224);
            }
            .loading-skeleton li .d2{
                 100%;
                height: 15px;
                background: rgb(211, 219, 224);
                margin-top: 5px;
            }
            .loading-skeleton .o {
                float:left;92%;height:100px;margin:3%;
                background: rgb(211, 219, 224);
                animation: skeleton-stripes 1s linear infinite;
                transform-origin: left;
                animation: skeleton-stretch .5s linear infinite alternate;
            }
            .loading-skeleton .d {
                float:left;92%;height:100px;margin:3%;
                background: rgb(211, 219, 224);
                animation: skeleton-stripes 1s linear infinite;
                transform-origin: left;
                animation: skeleton-stretch .5s -.5s linear infinite alternate;
            }
    
            @keyframes skeleton-stretch {
                from {
                    transform: scalex(1);
                }
                to {
                    transform: scalex(.3);
                }
            }
        </style>
    </div>

    效果:

    插件plugin.js

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    class MyPlugin_skeleton {
        constructor(options) {
            this.options = options;
        }
        apply(compiler) {
            compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
                // //编译之前,生成一个text.txt文件,通过compilation操作文件,只是演示与骨架屏没有关系,本身是node环境,根据node+fs也可以使用
                console.log(this.options);
                compilation.assets['./text.txt'] = {
                    source: () => this.options.text,
                    size: () => this.options.text.length
                };
                HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync('MyPlugin',
                    (data, cb) => {
                        ////在编译html文件之前把骨架屏动态加入进去
                        data.html = data.html.replace('<div id="app"></div>', `这里是骨架屏代码`);
                        //错误优先原则,如果处理有错误,传递到第一个参数,否则参数的位置就null
                        cb(null, data) //重点,一定要有回调函数,否则内容不会生效
                    }
                )
            })
        }
    }
    module.exports = MyPlugin_skeleton;

    在webpack.prod.conf.js中引入插件,并使用,它是根据HtmlWbpackPlugin提供的一个口子来处理,插件需要安装在htmlwebapckplugin下面

    打包项目 npm run build

    打开dist/index.html 可以看到我们的骨架屏已经插入到root中

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>index</title>
        <link href="static/css/main.css" rel="stylesheet">
    </head>
    <body>
        <div id="app">
            <div style="100%;height:50px;background: rgb(211, 219, 224);"></div>
            <ul class="loading-skeleton" style="">
                <li>
                    <div class="d1"></div>
                    <div class="d2 o"></div>
                    <div class="d2 d"></div>
                </li>
                <li>
                    <div class="d1"></div>
                    <div class="d2 o"></div>
                    <div class="d2 d"></div>
                </li>
                <li>
                    <div class="d1"></div>
                    <div class="d2 o"></div>
                    <div class="d2 d"></div>
                </li>
                <li>
                    <div class="d1"></div>
                    <div class="d2 o"></div>
                    <div class="d2 d"></div>
                </li>
                <li>
                    <div class="d1"></div>
                    <div class="d2 o"></div>
                    <div class="d2 d"></div>
                </li>
                <li>
                    <div class="d1"></div>
                    <div class="d2 o"></div>
                    <div class="d2 d"></div>
                </li>
            </ul>
            <style>
                .loading-skeleton {
                     100%;
                    height: auto;
                    list-style: none;
                    overflow: hidden;
                    margin: 0;
                    padding: 0;
                }
                
                .loading-skeleton li {
                     40%;
                    height: 180px;
                    float: left;
                    margin: 3% 7% 3% 3%;
                }
                
                .loading-skeleton li .d1 {
                     100%;
                    height: 130px;
                    background: rgb(211, 219, 224);
                }
                
                .loading-skeleton li .d2 {
                     100%;
                    height: 15px;
                    background: rgb(211, 219, 224);
                    margin-top: 5px;
                }
                
                .loading-skeleton .o {
                    float: left;
                     92%;
                    height: 100px;
                    margin: 3%;
                    background: rgb(211, 219, 224);
                    animation: skeleton-stripes 1s linear infinite;
                    transform-origin: left;
                    animation: skeleton-stretch .5s linear infinite alternate;
                }
                
                .loading-skeleton .d {
                    float: left;
                     92%;
                    height: 100px;
                    margin: 3%;
                    background: rgb(211, 219, 224);
                    animation: skeleton-stripes 1s linear infinite;
                    transform-origin: left;
                    animation: skeleton-stretch .5s -.5s linear infinite alternate;
                }
                
                @keyframes skeleton-stretch {
                    from {
                        transform: scalex(1);
                    }
                    to {
                        transform: scalex(.3);
                    }
                }
            </style>
        </div>
        <script src="static/js/main.c43cd934e03c41d9a79f.js"></script>
    </body>
    </html>

    这是一个通用的骨架屏模板,也可以根据自己的需求,设置不同的骨架屏

    拓展

    其实还可以根据用户访问路径进行打包不同的骨架,无非就加入path判断,塞入不同样式。

    var hash=window.location.hash;

    var path=window.location.pathname;

    根据path不同,显示不同的骨架屏

    参考1:https://www.jianshu.com/p/ec4bf33ab2c8

    参考2:https://www.npmjs.com/package/html-webpack-plugin

  • 相关阅读:
    剑指Offer——对成的二叉树
    剑指Offer——二叉树的下一个节点
    路径总和I、II、III
    性能调优工具
    关于在程序中内存检测的一些知识
    ptmalloc、tcmalloc及 jemalloc总结
    [LeetCode] 43. 字符串相乘
    [LeetCode] 155. Min Stack
    [LeetCode] 380. Insert Delete GetRandom O(1)
    linux内存过高排查
  • 原文地址:https://www.cnblogs.com/xiaofenguo/p/13162788.html
Copyright © 2020-2023  润新知