纯小白开发js弹窗插件(纯js源码,不使用jQuery)
前端小白一枚,看了大佬们的博客后心血来潮,写了这么一个玩意,勿喷~~
码云下载链接:https://gitee.com/hao_yu_feng/login-js.git
scdn下载链接:https://download.youkuaiyun.com/download/qq_41312395/12919983(0积分下载)
项目功能:带有登录功能的弹窗,其他一些文本信息类型的弹窗
1. 弹窗是仿照element的样式,然后没有什么慢慢出现的什么特效(需要的话,自己也可以加,很简单)
2. 然后按钮是仿照layui弹窗里面的样式,btn1是第一个按钮,btn2是第二个按钮,以此类推
3. 如果是登录弹窗的话,第一个按钮可以拿到用户名密码
4. 验证码什么的还没加,不过按照这个逻辑写下去就行,很简单的
步骤一,创建元素,定义一大堆乱七八糟的东西
创建项目,并引入js文件,在js文件里面加入几行代码,这里我们用的是匿名函数(匿名函数只要写了,就会自动执行),为什么要传入window?因为方便啊,直接挂在window全局上,有什么需要直接拿就行了
然后在index.html里面写入代码
然后在js里面写
这个init就是一个初始化函数(我是这么写的,因为习惯了,就好比你买了一台电脑,你得先开机装系统,对吧)这里为什么要加this呢?先卖个关子,往下看
然后如果有人问你 这里的options是什么?你就把你41码的鞋拍在他32码的脸上。
你家函数不接受参数,怎么和外面做交互呢?这里的options就是用户传过来的所有参数配置啊,亲
这里为什么我要用new呢?因为我需要在他的原型链(prototype)上面加东西啊,而且还有个叫__proto__的东西也要用
接下来就是想想这个弹窗有什么东西,这里我们抄…呃呃呃,借鉴一下elementui的弹窗
分为四个部分,头部,内容区,按钮区和阴影部分,所以我们就要把这四个当成参数传进去,为什么要当成参数不能写死?万一人家就不要头部和按钮区呢?
然后这是我的参数传递:
documentId:是用户传的id,就是比方说你这个弹窗,我就要放在我这个div下,如果他传了,那就放在用户的div下,不传,就默认放在body下
header:头部(true显示,false不显示,不传默认显示)
isLogin:是否是登录弹窗
content:用户传输的内容
headerContent:头部标题(如果isLogin为false,那么这个参数无效)
documentWidth:弹窗宽度
documentHeight:弹窗高度
inputTypeUser :用户名input的类型
inputNameUser:用户名input的name值
inputTypePwd:密码input的类型
inputNamePwd:密码input的name值
btnName:按钮数组(这里我放的是一个数组,因为谁知道会遇到需要几个按钮的弹窗呢,就算你放100个,我也给你生成100个按钮)
btn1,btn2,btn3:按照按钮数组顺序的回调函数
closeYUPopup :关闭弹窗触发的函数事件
然后js里面这么写
将拿到的参数,加到YUPopup这个原型链上,上面的那个this.init()为什么要加this,就是指向的YUPopup这个上面的init方法,然后我们将参数展开,如果用户传了参数,就用用户的,如果没有,我们就用默认参数,然后把这些参数,统统扔到this上,方便我们后面拿参数,参数有了,来看一下页面有没有报错,看看值有没有传过来
没有报错~来console一下
完美~值也拿到了,你们我们先创建div,但是创建之前要先看看用户有没有给你传他自己定义的div,如果传了,你还要检测他是不是存在的,所以我们创建一个名为createdDocumentBefore的函数来检测一下
我这里写的比较烦…但是保证木得问题~~(谅解小白哈)
然后就是开始创建元素~(我这里使用的是 document.createElement(‘div’) 这种老式的方法)
老规矩,定义函数,这次我们叫 createdDocumentBegin()
然后开始创建div
div创建好了,开始把他放到页面上,这里我用的_show函数
为了看得清楚一点,我把div的背景颜色改成红色
var oDivBox = document.createElement('div'); //创建div
oDivBox.className = 'YU-Dialog' //定义这个div的class名
var oDiv = document.createElement('div'); //呐,为什么要创建两个div呢?因为外面那个是大盒子,这里是盒子里面的盒子
oDiv.className = 'YU-Dialog-oDiv' //然后给这个盒子定义class名
oDiv.style.width = this.documentWidth + 'px' //设置宽,this.documentWidth这个就是用户传过来的那个值
oDiv.style.background = 'red'
oDiv.style.height = this.documentHeight + 'px'//设置高,this.documentHeight 这个就是用户传过来的那个值
然后看看有没有效果,报错什么的
没有效果,没有报错~~emmm看看是什么情况
好吧,创建了_show这个函数,没执行…
再看一下
好了,第一步就完成了
步骤二:加文本框,获取值什么的(头部待会再说)
再回到createdDocumentBegin()这个函数中
首先要判断 this.isLogin 这个值,看看是不是登录框
改造后的createdDocumentBegin函数:
createdDocumentBegin(){
var oDivBox = document.createElement('div');
oDivBox.className = 'YU-Dialog'
var oDiv = document.createElement('div');
oDiv.className = 'YU-Dialog-oDiv'
oDiv.style.width = this.documentWidth + 'px'
oDiv.style.background = 'red'
oDiv.style.height = this.documentHeight + 'px'
//创建表单盒子
var formBox = document.createElement("div");
formBox.className = 'YU-Dialog-content'
var isLogin = ''
if (this.isLogin) {
//创建表单
var form = document.createElement("form");
// console.log(this.formName)
form.setAttribute("name", this.formName);
form.setAttribute("class", 'YU-Dialog-form');
//创建用户名输入框外部div
var userNameDiv = document.createElement('div');
userNameDiv.className = 'YU-Dialog-userName'
//创建用户名输入框
var userName = document.createElement("input");
userName.className = 'YU-Dialog-userName-input'
userName.setAttribute("type", this.inputTypeUser);
userName.setAttribute("name", this.inputNameUser);
//加入页面
userNameDiv.appendChild(userName)
//创建用户密码输入框外部div
var userPwdDiv = document.createElement('div');
userPwdDiv.className = 'YU-Dialog-userPassword'
//创建用户密码输入框
var userPwd = document.createElement("input");
userPwd.className = 'YU-Dialog-userPassword-input'
userPwd.setAttribute("type", this.inputTypePwd);
userPwd.setAttribute("name", this.inputNamePwd);
//加入页面
userPwdDiv.appendChild(userPwd)
form.appendChild(userNameDiv)
form.appendChild(userPwdDiv)
formBox.appendChild(form)
}
oDiv.appendChild(formBox)
oDivBox.appendChild(oDiv)
return oDivBox
},
刷新看效果:
完美~~(样式什么的不着急,我们一会新建一个css,单独改,你问我为什么不在js里改?回答是,代价太大,而且万一用户想改你这个样式都改不了,还得先分析你这个插件是怎么个逻辑
步骤三:按钮搞起
继续搞createdDocumentBegin()这个函数
不过这次不一样了~
首先我们要检测用户传的数据类型对不对,如果不对,直接给他抛出异常
上面的的 FooterBtnName 就是保存的 isBtnName 返回的创建了n个按钮的div元素
然后就是定义isBtnName()函数
老规矩,创建div
创建包裹按钮的div,然后…没错,万能的for
创建好了之后…还记的FooterBtnName 这个变量吗?
给他扔到createdDocumentBegin()这个函数里,这里为什么要加判断呢?因为不加报错啊,你也可以在定义FooterBtnName时这么写 FooterBtnName = ‘’,但是…这样我感觉不好~~~
页面保存,看效果
看着是没什么问题,but…
这两按钮就不能分开吗?说好的回调呢?
改造改造
首先要分析,如何判断他是第几个按钮呢?然后当用户点击的时候如何知道用户点的是哪个按钮呢??
我的答案是…使用自定义data属性,来区分,当然了,用索引也行,毕竟他循环的顺序不可能变啊~~那就搞起,万能的“+”号,然后拼字符串
好了~
下一步,搞回调事件…emmm说实话,我对“回调事件”这个词不太敏感,因为我完全不知道他是什么意思,但是按照我的理解,他不就是用非人类的方法调用函数执行吗?搞起
首先我们给第一个按钮加东西,那么问题来了
这里的click点击之后,拿到的this是…是…这个按钮啊!!!
完全拿不到外面的属性什么的,这时候就需要一个变量that了,这是一个this的指向的问题
这下就没问题了~
但是新问题来了…
特喵的函数呢??
我dnmd,为什么?
然后想了半天…
哦豁了哇~~没存…被自己蠢哭了,但是我就是不存,就和他刚,然后我选择曲线救国,在来一个options他不香吗?
咳咳,这样就好了,刚刚就当没发生过,什么?你问我options是什么?恭喜你,从头看吧,上课不认真听讲的孩子是要受罚的
这样就行了,有人问了,你费那么大劲拿函数干嘛呢?我的答案是,执行他啊,它里面有什么你就给他执行什么,怎么执行呢?先拿函数名~没错,截取字符串
老规矩,循环走起来
保存刷新,输入内容
完美,
看
item就是我们返回的obj,这不就是回调吗?(可能我的理解有误哈)
看,执行了呢~~
但是问题又来了…
这么写的话…如果他传的isLogin不是true…
哦豁…来,继续分析
怪不得…来,把它拉出来
保存,刷新
看着没问题…但是…
唉,服了呀
来吧继续分析
结果发现…
如果他不是登录框的话…表单就不会生成,那肯定拿不到值啊…emmm,好办,万能的if
写了两套代码…唉,小白的技术也就到这了,哈哈,保存刷新
好了~~这里如果不想让他undefine的话…
- item去掉
- 在代码里 that.thatsKey里面手动返回东西
步骤四 搞成弹窗
emmm,这个有点自欺欺人了,就是…
哈哈哈,真是佩服自己啊(不要喷我啊)
再来就是删除这个div,啊不,现在应该叫弹窗了,来吧
首先先要思考怎么做…无非就是把创建的东西再干掉呗~~~那么问题又来了,如果用户实例化了多个弹窗,你先干掉哪个??…这是个问题
首先你要保证,创建的东西是唯一的,然后…等等,唯一的?唯一的不就是this吗?这就好办了啊~
老规矩,创建函数
可是…写什么呢…看那个_show()函数
他创建的时候不就能做点文章吗??
几番试探…这么写吧,createdDocumentBegin()这个函数
不就是返回的整个div的实例吗?这就好办了,开始加属性~
这个_el可以随便定义,因为他是对象,在哪定义都一样(虽然js有个先创建变量,后执行函数的机制…)然后把这个实例传给_show()函数
不用担心他是undefined或者是空,他不可能是空,因为先创建的元素,后展示~
然后再写我们的removeDom()函数
也很简单,就一句
这多好~来
点一下第二个按钮试试
完美删除
多点几个出来
点哪个删哪个~
步骤五
完善一下
加阴影,加头部,加内容~~~
加内容,头部和差不多isBtnName()函数写法差不多
然后阴影部分也是要在_show里面搞一下子
附件有完整代码和demo
完结
其实到这里大部分东西都写完了,存在的问题也很明显了…
就是你这里,外面居然可以随便调用到插件里面的方法,这是一件很可怕的事情,所以…感谢大家能看到这里,也希望大家能多提宝贵意见,谢谢啦
放上我自己写的插件代码,有兴趣的兄弟可以玩一玩~
码云下载链接:https://gitee.com/hao_yu_feng/login-js.git
scdn下载链接:https://download.youkuaiyun.com/download/qq_41312395/12919983