工具-jquery封装弹框插件

一个文笔一般,想到哪是哪的唯心论前端小白。

前言

没错,跟jQuery磕上了!

前两天无奈之下用jQuery写了个分页,今天又写了一个弹框组件。没有特殊的地方,就是弹框组件,和 el-dialog 是一模一样的。

效果大概是这样子的:

Animation.gif

觉得可能在不知道什么时候可能用一下,所以做个文档记录一下吧!

思路

需求分析:

  1. 通过点击dom对象,或者触发js方法,触发 open 方法,打开弹框。
  2. 弹框自动添加 header 和 footer,并把业务放在 body 中。
  3. 支持按钮自定义,并可以绑定自定义方法。自定义方法执行完成以后关闭弹框。

使用方法设想

根据最近的开发习惯,dom结构当然是这样的最舒服了!

<div class="cm-dialog" id="dialogDemo">
<p>hello world!</p>
</div>
<div class="cm-dialog" id="dialogDemo">
    <p>hello world!</p>
</div>
<div class="cm-dialog" id="dialogDemo"> <p>hello world!</p> </div>

即我们只关注业务内容,由插件动生成弹框的头部和底部。

然后是js结构则是这样的:

$(function () {
const dialogDemo = $('#dialogDemo').initDialog({
title: '查看详情',
cancel: {
label: '取消',
handler: function () {
console.log('触发了取消');
return true;
}
},
submit: {
label: '确定',
handler: function () {
console.log('触发了确定');
return true;
}
}
})
$('#button').on('click', function () {
dialogDemo.trigger('open')
})
})
 $(function () {
    const dialogDemo = $('#dialogDemo').initDialog({
        title: '查看详情',
        cancel: {
            label: '取消',
            handler: function () {
                console.log('触发了取消');
                return true;
            }
        },
        submit: {
            label: '确定',
            handler: function () {
                console.log('触发了确定');
                return true;
            }
        }
    })
    
    $('#button').on('click', function () {
        dialogDemo.trigger('open')
    })
})
$(function () { const dialogDemo = $('#dialogDemo').initDialog({ title: '查看详情', cancel: { label: '取消', handler: function () { console.log('触发了取消'); return true; } }, submit: { label: '确定', handler: function () { console.log('触发了确定'); return true; } } }) $('#button').on('click', function () { dialogDemo.trigger('open') }) })

可以看到,针对jQuery扩展了一个名为 initDialog 的方法,传入配置内容,配置内容包含常用的 title 和两个按钮,分别对应【取消】按钮和【确定】按钮,并绑定两个方法。

关键是最后要使用一个变量来记录这个初始化以后的 dialog 对象,可以使用 trigger 方法去触发内部的 open 方法,打开弹框。

坑点补充

以上这个方案里面有几个点需要注意:

  1. 如果按钮绑定的方法抛出异常,需要阻止关闭,所以这个方法应该有一个 Boolearn 类型的返回值。
  2. 如果只有一个按钮或者多个按钮,则需要动态的去渲染按钮。
  3. body 部分应该有个最大高度,避免超出可视范围的尴尬局面。

开发

开发这块比较简单,提前声明一下,上面三个坑点只有第三个做了,前面两个没做!

意不意外? 但是还会把思路写出来。

开发过程中因为没想明白怎么使用模版把 头部和底部 使用模板渲染出来,一度想着在 cm-dialog 里面再套一层,然后再向里面添加 htm 的方法,后来被 pass 掉了。

最终的方案是这样子的:

$.fn.extend({
initDialog: function (conf) {
var inner = $(this).html();
// 解析 config
var title = conf.title || "标题";
var cancel = conf.cancel || null;
var submit = conf.submit || null;
// 模板
var htm = `
<div class="cm-dialog-wrap">
<div class="cm-dialog-header">
<span>${title}</span>
</div>
<div class="cm-dialog-body">
${inner}
</div>
<div class="cm-dialog-footer">
<button class="cm-button-cancel">${cancel.label}</button>
<button class="cm-button-submit">${submit.label}</button>
</div>
</div>
`;
// 初始化 dialog
$(this).html(htm);
$(this).hide();
// 绑定 open 方法
$(this).bind("open", function () {
$(this).fadeIn();
});
// 绑定 close 方法
$(this).bind("close", function () {
$(this).fadeOut();
});
// 绑定按钮事件
$(".cm-button-cancel").on("click", function () {
if(cancel.handler && cancel.handler()){
$(this).trigger("close");
};
});
$(".cm-button-submit").on("click", function () {
if(submit.handler && submit.handler()){
$(this).trigger("close");
}
});
// 返回 dialog
return $(this);
},
});
$.fn.extend({

  initDialog: function (conf) {

    var inner = $(this).html();

    // 解析 config

    var title = conf.title || "标题";

    var cancel = conf.cancel || null;

    var submit = conf.submit || null;



    // 模板

    var htm = `

    <div class="cm-dialog-wrap">

      <div class="cm-dialog-header">

        <span>${title}</span>

      </div>

      <div class="cm-dialog-body">

        ${inner}

      </div>

      <div class="cm-dialog-footer">

        <button class="cm-button-cancel">${cancel.label}</button>

        <button class="cm-button-submit">${submit.label}</button>

      </div>

    </div>

    `;



    // 初始化 dialog

    $(this).html(htm);

    $(this).hide();



    // 绑定 open 方法

    $(this).bind("open", function () {

      $(this).fadeIn();

    });



    // 绑定 close 方法

    $(this).bind("close", function () {

      $(this).fadeOut();

    });



    // 绑定按钮事件

    $(".cm-button-cancel").on("click", function () {

      if(cancel.handler && cancel.handler()){

          $(this).trigger("close");

      };

    });

    $(".cm-button-submit").on("click", function () {

      if(submit.handler && submit.handler()){

          $(this).trigger("close");

      }

    });



    // 返回 dialog

    return $(this);

  },

});
$.fn.extend({ initDialog: function (conf) { var inner = $(this).html(); // 解析 config var title = conf.title || "标题"; var cancel = conf.cancel || null; var submit = conf.submit || null; // 模板 var htm = ` <div class="cm-dialog-wrap"> <div class="cm-dialog-header"> <span>${title}</span> </div> <div class="cm-dialog-body"> ${inner} </div> <div class="cm-dialog-footer"> <button class="cm-button-cancel">${cancel.label}</button> <button class="cm-button-submit">${submit.label}</button> </div> </div> `; // 初始化 dialog $(this).html(htm); $(this).hide(); // 绑定 open 方法 $(this).bind("open", function () { $(this).fadeIn(); }); // 绑定 close 方法 $(this).bind("close", function () { $(this).fadeOut(); }); // 绑定按钮事件 $(".cm-button-cancel").on("click", function () { if(cancel.handler && cancel.handler()){ $(this).trigger("close"); }; }); $(".cm-button-submit").on("click", function () { if(submit.handler && submit.handler()){ $(this).trigger("close"); } }); // 返回 dialog return $(this); }, });

其实结构很简单,主要是一个思路,就是在方法的一开始,将 inner 提出来,然后放在模板中。这样就实现了dom结构很简单,但是后面会包含头部和底部的开发方式。

然后就是剩余的两个坑点的处理方式:

  1. 其实已经解决了,返回值为 true 和false 的事情,但是如果是异步方法需要注意了,可以使用 trigger 去触发 close 方法。
  2. 传入按钮改为一个数组,使用map函数将数组转换成dom结构,并重新绑定一下方法就好了。

代码分享

主要分享三个文件:

dialog.extends.js

$.fn.extend({
initDialog: function (conf) {
var inner = $(this).html();
// 解析 config
var title = conf.title || "标题";
var cancel = conf.cancel || null;
var submit = conf.submit || null;
// 模板
var htm = `
<div class="cm-dialog-wrap">
<div class="cm-dialog-header">
<span>${title}</span>
</div>
<div class="cm-dialog-body">
${inner}
</div>
<div class="cm-dialog-footer">
<button class="cm-button-cancel">${cancel.label}</button>
<button class="cm-button-submit">${submit.label}</button>
</div>
</div>
`;
// 初始化 dialog
$(this).html(htm);
$(this).hide();
// 绑定 open 方法
$(this).bind("open", function () {
$(this).fadeIn();
});
// 绑定 close 方法
$(this).bind("close", function () {
$(this).fadeOut();
});
// 绑定按钮事件
$(".cm-button-cancel").on("click", function () {
if(cancel.handler && cancel.handler()){
$(this).trigger("close");
};
});
$(".cm-button-submit").on("click", function () {
if(submit.handler && submit.handler()){
$(this).trigger("close");
}
});
// 返回 dialog
return $(this);
},
});
$.fn.extend({

  initDialog: function (conf) {

    var inner = $(this).html();

    // 解析 config

    var title = conf.title || "标题";

    var cancel = conf.cancel || null;

    var submit = conf.submit || null;



    // 模板

    var htm = `

    <div class="cm-dialog-wrap">

      <div class="cm-dialog-header">

        <span>${title}</span>

      </div>

      <div class="cm-dialog-body">

        ${inner}

      </div>

      <div class="cm-dialog-footer">

        <button class="cm-button-cancel">${cancel.label}</button>

        <button class="cm-button-submit">${submit.label}</button>

      </div>

    </div>

    `;



    // 初始化 dialog

    $(this).html(htm);

    $(this).hide();



    // 绑定 open 方法

    $(this).bind("open", function () {

      $(this).fadeIn();

    });



    // 绑定 close 方法

    $(this).bind("close", function () {

      $(this).fadeOut();

    });



    // 绑定按钮事件

    $(".cm-button-cancel").on("click", function () {

      if(cancel.handler && cancel.handler()){

          $(this).trigger("close");

      };

    });

    $(".cm-button-submit").on("click", function () {

      if(submit.handler && submit.handler()){

          $(this).trigger("close");

      }

    });



    // 返回 dialog

    return $(this);

  },

});
$.fn.extend({ initDialog: function (conf) { var inner = $(this).html(); // 解析 config var title = conf.title || "标题"; var cancel = conf.cancel || null; var submit = conf.submit || null; // 模板 var htm = ` <div class="cm-dialog-wrap"> <div class="cm-dialog-header"> <span>${title}</span> </div> <div class="cm-dialog-body"> ${inner} </div> <div class="cm-dialog-footer"> <button class="cm-button-cancel">${cancel.label}</button> <button class="cm-button-submit">${submit.label}</button> </div> </div> `; // 初始化 dialog $(this).html(htm); $(this).hide(); // 绑定 open 方法 $(this).bind("open", function () { $(this).fadeIn(); }); // 绑定 close 方法 $(this).bind("close", function () { $(this).fadeOut(); }); // 绑定按钮事件 $(".cm-button-cancel").on("click", function () { if(cancel.handler && cancel.handler()){ $(this).trigger("close"); }; }); $(".cm-button-submit").on("click", function () { if(submit.handler && submit.handler()){ $(this).trigger("close"); } }); // 返回 dialog return $(this); }, });

dialog.extends.css

需要注意,这里只包含了 dialog 相关的样式,需要配合全局样式去使用。
类似:*{ padding :0; margin: 0}

.cm-dialog {
height: 100%;
width: 100%;
position: fixed;
z-index: 999;
top: 0;
left: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
background: rgba(48, 42, 42, 0.5);
}
.cm-dialog-wrap {
height: auto;
width: 960px;
background: #fff;
box-shadow: 0 0 10px #000;
position: relative;
overflow: hidden;
}
.cm-dialog-header {
position: absolute;
top: 0;
left: 0;
right: 0;
padding: 5px 20px;
background: #ebecee;
height: 40px;
line-height: 40px;
}
.cm-dialog-body {
padding: 70px 20px 70px 20px;
max-height: 500px;
overflow-y: auto;
overflow-x: hidden;
}
.cm-dialog-footer {
position: absolute;
bottom: 0;
background: #ebecee;
padding: 5px 20px;
left: 0;
right: 0;
line-height: 40px;
text-align: right;
}
.cm-dialog-footer button {
padding: 6px 16px;
background: skyblue;
border: none;
outline: none;
border-radius: 4px;
cursor: pointer;
transition: background linear 0.1s;
}
/* .cm-dialog-footer button.cm-button-submit {
background: red;
} */
.cm-dialog-footer button:hover {
background: rgb(58, 182, 231);
}
.cm-dialog {
  height: 100%;
  width: 100%;

  position: fixed;
  z-index: 999;
  top: 0;
  left: 0;

  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;

  background: rgba(48, 42, 42, 0.5);
}

.cm-dialog-wrap {
  height: auto;
  width: 960px;
  background: #fff;
  box-shadow: 0 0 10px #000;

  position: relative;
  overflow: hidden;
}

.cm-dialog-header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: 5px 20px;

  background: #ebecee;
  height: 40px;
  line-height: 40px;
}

.cm-dialog-body {
  padding: 70px 20px 70px 20px;

  max-height: 500px;
  overflow-y: auto;
  overflow-x: hidden;
}

.cm-dialog-footer {
  position: absolute;
  bottom: 0;
  background: #ebecee;

  padding: 5px 20px;
  left: 0;
  right: 0;
  line-height: 40px;
  text-align: right;
}

.cm-dialog-footer button {
  padding: 6px 16px;

  background: skyblue;
  border: none;
  outline: none;
  border-radius: 4px;
  cursor: pointer;

  transition: background linear 0.1s;
}

/* .cm-dialog-footer button.cm-button-submit {
    background: red;
  } */

.cm-dialog-footer button:hover {
  background: rgb(58, 182, 231);
}
.cm-dialog { height: 100%; width: 100%; position: fixed; z-index: 999; top: 0; left: 0; display: flex; flex-direction: row; align-items: center; justify-content: center; background: rgba(48, 42, 42, 0.5); } .cm-dialog-wrap { height: auto; width: 960px; background: #fff; box-shadow: 0 0 10px #000; position: relative; overflow: hidden; } .cm-dialog-header { position: absolute; top: 0; left: 0; right: 0; padding: 5px 20px; background: #ebecee; height: 40px; line-height: 40px; } .cm-dialog-body { padding: 70px 20px 70px 20px; max-height: 500px; overflow-y: auto; overflow-x: hidden; } .cm-dialog-footer { position: absolute; bottom: 0; background: #ebecee; padding: 5px 20px; left: 0; right: 0; line-height: 40px; text-align: right; } .cm-dialog-footer button { padding: 6px 16px; background: skyblue; border: none; outline: none; border-radius: 4px; cursor: pointer; transition: background linear 0.1s; } /* .cm-dialog-footer button.cm-button-submit { background: red; } */ .cm-dialog-footer button:hover { background: rgb(58, 182, 231); }

dialog-demo.html

就是展示一下怎么用。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./index.css">
<link rel="stylesheet" href="./dialog.extend.css">
</head>
<body>
<button id="button">Click Me!</button>
<div class="cm-dialog" id="dialogDemo">
<p>hello world!</p>
</div>
</body>
<script src="./jquery.js"></script>
<script src="./dialog.extends.js"></script>
<script>
$(function () {
const dialogDemo = $('#dialogDemo').initDialog({
title: '查看详情',
cancel: {
label: '取消',
handler: function () {
console.log('触发了取消');
}
},
submit: {
label: '确定',
handler: function () {
console.log('触发了确定');
}
}
})
$('#button').on('click', function () {
dialogDemo.trigger('open')
})
})
</script>
</html>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./index.css">
    <link rel="stylesheet" href="./dialog.extend.css">
</head>

<body>
    <button id="button">Click Me!</button>


    <div class="cm-dialog" id="dialogDemo">
        <p>hello world!</p>
    </div>
</body>

<script src="./jquery.js"></script>
<script src="./dialog.extends.js"></script>
<script>

    $(function () {
        const dialogDemo = $('#dialogDemo').initDialog({
            title: '查看详情',
            cancel: {
                label: '取消',
                handler: function () {
                    console.log('触发了取消');
                }
            },
            submit: {
                label: '确定',
                handler: function () {
                    console.log('触发了确定');
                }
            }

        })

        $('#button').on('click', function () {
            dialogDemo.trigger('open')
        })
    })
</script>

</html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./index.css"> <link rel="stylesheet" href="./dialog.extend.css"> </head> <body> <button id="button">Click Me!</button> <div class="cm-dialog" id="dialogDemo"> <p>hello world!</p> </div> </body> <script src="./jquery.js"></script> <script src="./dialog.extends.js"></script> <script> $(function () { const dialogDemo = $('#dialogDemo').initDialog({ title: '查看详情', cancel: { label: '取消', handler: function () { console.log('触发了取消'); } }, submit: { label: '确定', handler: function () { console.log('触发了确定'); } } }) $('#button').on('click', function () { dialogDemo.trigger('open') }) }) </script> </html>

后记

思路很简单,代码量也很少,关键就是一个将原模板里面的内容重写一遍的思路。

有所思必有所得:

  1. 一个开箱即用的 dialog jQuery 插件。
  2. 一个 jQuery 或者原生代码中使用模板开发的开发思路。
  3. MVVM 模式的浅显探索?

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYviVRDs' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片