有关组件的尝鲜-SAOUnit弹窗

469 阅读5分钟

只有动手去做的时候,才是距离成功最近的时候

最近开始学习了一个前端开发思维,在这里给和我一样的“童鞋”做下分享,大佬轻喷。

什么是组件

组件是对数据和方法进行封装,每个组件都有自己的属性和方法,是面向对象编程的核心。一个组件可以在许多地方进行使用,这样就不需要进行重复写代码。写代码讲究高内聚低耦合,组件很好的体现了这个思想。

前端的组件长啥样

现如今前端框架层出不穷,这些框架里面就是包含了许许多多的组件,它们有着自己的css样式和JS脚本。用我最近使用的Swiper举例吧。
Swiper的使用方法

先引入CSS样式表和JS脚本,再到<body></body>中创建好指定类名的标签们,最后再初始化一下,这个组件的功能就会被实现了。当然也有一些是纯CSS样式的组件,这里就不多推荐了。

在写过一次代码后,这些组件就可以到任意一个页面中使用了,无需重新写过一遍CSS样式或者JS脚本(初始化还是要再写一遍的)。

SAOUnit弹窗

好了,上面简单的介绍了一下组件。如今我正在着手几个项目,有学校课程需要、有参赛项目需要,还有个人爱好。
今天我就分享一个我个人项目(自嗨)的一个组件。不多说看图

SAOUnit弹窗

很明显,这是一个弹窗组件,是刀剑神域风格的(非常SAO)。
我之所以做这么一个弹窗组件,是因为默认的弹窗alert()实在霸道,它一弹出来,你的页面就被暂停掉了。突然间的暂停让我很不爽,所以就有了这么一个东西。


来看看DOM结构吧

 <div class="saopopup-container">
    <div class="saopopup-frame">
      <div class="saopopup-title"></div> //弹窗标题
      <div class="saopopup-text"></div> //弹窗内容
      <div class="saopopup-bottom">
        <div class="saopopup-button-no">取消</div> //取消按钮
        <div class="saopopup-button-ok">确定</div> //确定按钮
      </div>
    </div>
  </div>

CSS样式我就不放上来了(目前效果不太好),直接来看JS脚本部分,如何实现一个组件的功能。
首先我将这个组件的属性和方法封装在一个构造函数里面。

function MPBpopup(theNode, json) {
    ···
}
参数 必须
theNode String类型,选取当前组件的class或者id
json JSON格式的数据,可选值有title:'标题',text:'内容',okFunc:点击确定调用的函数,noFunc:点击取消调用的函数 可选

每个组件都有自己的属性和方法,下面是该弹窗组件的属性

var _node = document.querySelector(theNode);//获取组件节点
var _content = { //默认弹窗内容
    title: "Message", //标题
    text: "Nothing in here", //内容
    okFunc:()=>{}, //确定时调用的函数
    noFunc:()=>{this.hiddenPopup()} //取消时调的用函数
}
// 初始化设置
var _frame = _node.getElementsByClassName('saopopup-frame')[0]; //弹窗主体
_node.classList.add('saopopup-close'); // 添加隐藏样式
_node.getElementsByClassName('saopopup-button-no')[0].onclick = function(){
    _content.noFunc(); //绑定点击取消的方法
}
_node.getElementsByClassName('saopopup-button-ok')[0].onclick = function(){
    _content.okFunc(); //绑定点击确定的方法
}

以上这些属性都是私有的,前面用一个下划线表示。当使用构造函数创建对象时就会被生成。

组件就要有组件的样子,能够弹出展示内容和关闭就行。不过只有默认的属性值肯定是不行的,弹窗里显示什么内容就得我们自己输入了。
私有方法:将内容写入弹窗中

// 设置弹窗的标题以及内容
function _setContent() {
    _node.getElementsByClassName('saopopup-title')[0].innerHTML = _content.title;
    _node.getElementsByClassName('saopopup-text')[0].innerHTML = _content.text;
}

当然这只是填写了初始默认值,修改弹窗内容需要用到下面这个。

私有方法:修改属性

// 设置对象属性,包含数据合法性判断
function _setData(json){
    if(json){
      if(json.title) _content.title = json.title;
      if(json.text) _content.text = json.text;
      if(json.okFunc) _content.okFunc = json.okFunc;
      if(json.noFunc) _content.noFunc = json.noFunc;
    } else {
      return;
    }
}

私有方法:获取组件主体的高度

// 获取弹窗的高度,用于高度过渡效果
function _getPopupHeight() {
    return _frame.offsetHeight;
}

当组件内部设置好了后,剩下的就是交给外部调用了。

对象方法:打开弹窗

this.showPopup = function (json) {
    _setData(json); //设置弹窗的内容,如果没有传参进来就使用初始化值
    _node.classList.remove('saopopup-close'); //移除 display:none
    _node.classList.add('saopopup-open'); //添加 display:block 附带一段animation
    _setContent(); //将弹窗的内容填入页面中
     // 这里的延时非常有必要,不然会因为异步执行而取不到主体正确的高度
    setTimeout(()=>{
      _node.style.height = _getPopupHeight() + 'px'; // GIF图中高度展开的过渡
    },300)
}

对象方法:关闭弹窗

this.hiddenPopup = function () {
    _node.classList.remove('saopopup-open'); // 移除 display:block
    _node.style.height = '39px'; // 将主体收起
    // 给主体一段时间过渡,再添加display:none
    setTimeout(()=>{
      _node.classList.add('saopopup-close');
    },200)
}

以上就是这个弹窗组件的主要内部逻辑啦~~
此组件放在了我的GitHub上,我会进行更新和维护,如果感兴趣的话就给个★吧。欢迎在回复区讨论和指教。

SAOUnit弹窗使用方式

  1. 首先引入css和js
<!DOCTYPE html>
<html>
<head>
    ...
    <link rel="stylesheet" href="./MPBC.css">
</head>
<body>
    ...
    <script src="./MPBC.js"></script>
    ...
</body>
</html>
  1. HTML内容
<div class="saopopup-container">
    <div class="saopopup-frame">
        <div class="saopopup-title"></div>
        <div class="saopopup-text"></div>
        <div class="saopopup-bottom">
            <div class="saopopup-button-no">取消</div>
            <div class="saopopup-button-ok">确定</div>
        </div>
    </div>
</div>
  1. 初始化一下,最好是挨着</body>标签
var myPopup = new MPBpopup('.saopopup-container',{
    title:"测试用标题",
    text:"测试用内容<p>第二行测试内容</p><p>第三行测试内容</p>",
    okFunc:()=>{myPopup.hiddenPopup()} 
    // 这里设置了点击确认关闭弹窗。关还是不关,取决于你而不是组件。 noFunc是默认关闭弹窗的
});
  1. 需要弹窗时使用
myPopup.showPopup(); 
//然后你就可以看见GIF图的效果了