使用webpack封装一个javascript原生弹出框组件

CrazyMing 2019-09-09
0条评论 439 次浏览
CrazyMing 2019-09-090条评论 439 次浏览

github地址:https://github.com/crazyming9528/crazy-popup
在线demo地址:http://demo.crazyming.cn/?link=popup

环境准备:

新建一个项目目录 打开cli,运行以下命令

npm init # 初始化项目
npm i @babel/core @babel/preset-env babel-loader --dev-save
npm i webpack webpack-cli webpack-node-externals --dev-save
npm i node-sass --save-dev
npm i sass-loader --save-dev
npm i css-loader --save-dev
npm i style-loader --save-dev

使用babel将项目中的es6转为 浏览器支持的js代码
参考webpack 文档 在根目录新建webpack.config.js配置文件 代码如下:

const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
    target: 'node',
    mode: 'production',
    entry: {
        index: './src/index.js'
    },
    externals: [nodeExternals()],
    output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name].bundle.js',
        library: 'popup',
        libraryTarget: 'var'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },

            {
                test: /\.scss$/,
                use: [
                    {
                        loader: "style-loader" // 将 JS 字符串生成为 style 节点
                    },
                    {
                        loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
                    },
                    {
                        loader: "sass-loader" // 将 Sass 编译成 CSS
                    }
                ]
            }
        ]
    },
    devtool: 'source-map'
};

上方配置中,entry配置入口文件,我们的代码就写在这个入口文件里边,output配置的是 打包后输出目录,文件名,库的名称:popup,libraryTarget: ‘var'(默认值),使用这个配置,当popup库被加载时,那么库的返回值会被分配到使用用var申明的变量上。

使用babel-loader 处理js 文件,为了方便,我使用scss预处理器写样式,对于.scss文件需要使用sass-loader编译 ,这里loder的加载顺序是从后往前的,所以从后往前 依次是 sass-loader -> css-loader -> style-loader

在packjson 加入:"build": "webpack --progress --color",

编写代码

根据我们配置中写的那样,新建src文件,并在src 新建index.js

进入 src/index.js 文件

首先定义一个 生成dom 的函数:generateDom,该函数将传入的html代码转为dom元素并返回。
暴露show方法,show方法 接收一个option参数,option是一个对象,包含的属性有:title(标题) content(内容) confirm(点击确定的回调) cancel(点击取消的回调),show方法 首先拼装html,然后使用前面定义的generateDom 函数 生成 dom 并插入到body元素下面,然后在确定按钮 和取消按钮的dom上监听点击事件 并把对应的回调写在执行函数里边,
index.js代码如下:

import './index.scss'

const generateDom = (html) => {
    const dom = document.createElement('div');
    dom.className = 'popup_wrapper';
    dom.innerHTML = html;

    return dom;
}


export const show = (option = {}) => {
    const html = `<div class="popup_box"><div class="popup_header">${option.title}</div>
<div class="popup_content">${option.content}</div>
<div class="popup_footer">
    <button type="button" class="popup_footer_button_confirm">确定</button>
    <button type="button" class="popup_footer_button_cancel">取消</button>
</div></div>`


    document.querySelector('body').appendChild(generateDom(html));

    document.querySelector('.popup_footer_button_confirm').addEventListener('click', () => {
        option.confirm();
        document.querySelector('.popup_wrapper').remove();
    });
    document.querySelector('.popup_footer_button_cancel').addEventListener('click', () => {
        option.cancel();
        document.querySelector('.popup_wrapper').remove();

    })

};


console.log("popup is ok");

在src下新建index.scss样式文件

scss样式文件代码如下:

@charset "UTF-8";

.popup_wrapper {
  background-color: rgba(0, 0, 0, 0.3);
  z-index: 9999999;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;


  .popup_box {
    box-sizing: border-box;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 400px;
    background-color: white;

    .popup_header {
      background: #3498db;
      color: white;
      padding: 5px;

    }

    .popup_content {
      padding: 15px 30px;

    }

    .popup_footer {

      text-align: right;
      padding: 5px;

      .popup_footer_button_confirm {
        background: #3498db;

        color: #ffffff;
        font-size: 14px;
        padding: 5px 8px;
        text-decoration: none;
        border: none;
        cursor: pointer;

        &:hover {
          background: #2980b9;

          color: #ffffff;
          text-decoration: none;
        }

      }

      .popup_footer_button_cancel {

        background: #f88c17;

        color: #ffffff;
        font-size: 14px;
        padding: 5px 8px;
        text-decoration: none;
        border: none;
        cursor: pointer;

        &:hover {
          background: #ef510a;

          color: #ffffff;
          text-decoration: none;
        }

      }

    }

  }


  @media (max-width: 768px) {

    .popup_box {
      width: 260px;
    }


  }
}



需要注意的是 要在index.js 中导入样式文件:

import './index.scss'

这样就ok了
执行npm run build 打包,打包好的 文件位于 dist/index.bundle.js

使用

新建一个 测试页面 引入index.bundle.js ,即可使用:

popup.show({
            title: "提示",
            content: "谷歌是一家位于美国的跨国科技企业,业务包括互联网搜索、云计算、广告技术等,同时开发并提供大量基于互联网的产品与服务,其主要利润来自于AdWords等广告服务。你确定吗?",
            confirm: function () {
                // alert('你点击了确定')
            },
            cancel: function () {
                // alert("你点击了取消")
            }
        })

测试页代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Title</title>
    <script src="index.bundle.js"></script>
</head>
<body>

<button class="test">测试弹窗</button>
<script>

    var button = document.getElementsByClassName('test')[0];
    button.addEventListener('click', function () {
        popup.show({
            title: "提示",
            content: "谷歌是一家位于美国的跨国科技企业,业务包括互联网搜索、云计算、广告技术等,同时开发并提供大量基于互联网的产品与服务,其主要利润来自于AdWords等广告服务。你确定吗?",
            confirm: function () {
                // alert('你点击了确定')
            },
            cancel: function () {
                // alert("你点击了取消")
            }
        })

    })

</script>
</body>
</html>
9+

发表评论

电子邮件地址不会被公开。

隐藏
变装