最近整的MooTools库下Mbox弹框插件

这篇文章发布于 2010年11月17日,星期三,23:12,归类于 JS相关。 阅读 81885 次, 今日 1 次 17 条评论

 

一、些背景缘由什么的

不知道数年前,公司的前辈出于什么原因选择了MooTools库(貌似在国内不是很热),用Google趋势一搜这5个js库jQuery, mootools, YUI, dojo,extjs,结果如下图:
js库索引流行对比 张鑫旭-鑫空间-鑫生活

可怜的MooTools库垫底,但是,研究研究此库还是学到不少东西的,其OO思想,就如同JavaScript高级程序设计书中所展示的一样,基础不佳者往往很难驾驭,学习门槛高限制了其蓬勃发展啊,你看人家jQuery,即使JavaScript很初级的人也能整出点小花样,这种感觉就是——即使我很菜,我也能泡到美女,你说人家能不招人喜欢吗?//zxx:当然,阿拉也喜欢jQuery的

原先项目Mbox专门用来装载各种类型元素或HTML代码片段,与提示类的Prompt弹框是分离的,而且结构很简单。所以,最后的弹框效果比较粗糙。现在网站要大改,设计师让我先看了下弹框样式。我一琢磨,不错,比之前的好看很多很多,但是CSS代码量以及目前的弹框结构有些吐槽,而且,load类弹框和alert类弹框UI效果是一致的(而代码是两段)。显然整改的工作量比较大,加上之前使用Mbox有诸多问题,如高宽自适应能力基本上为0,内部逻辑过于复杂,很多功能对于目前这个项目不使用等因素,于是我决定把Mbox弹框和Prompt弹框整合到一起。说干就干,于是周末独自过来加班,在原插件的逻辑基础上修改,折腾了差不多2天,周一结束的时候,基本上可以使用了,各种类型的数据都可以很好的加载。但是,一个页面有多个弹框触发的情况下,参数,事情等有累积和冲突的情况,而且调用的入口有多个,逻辑过于错综复杂,IE6下的显示略显迟钝。于是做了一个决定:从头到尾按照自己的逻辑将弹框插件重写一遍。MooTools库我接触也不过几个月,不少地方还是很吃紧的,要时不时翻阅参考文档。好在,磨豆腐一样,终于用了一天半的功夫磨出来了,然后一个下午的时间调bug,修复细节,于是,全新的Mbox就这样出炉了。

我之前用jQuery写过一个轻量级弹出框插件zxxbox,貌似还是有不少人使用的,您有兴趣可以狠狠地点击这里:zxxbox jQuery弹出框插件

二、demo以及下载

您可以狠狠地点击这里:MooTools库下Mbox弹框测试demo

我已经将精简版的demo和脚本zip格式打包了,您可以狠狠地点击这里:源文件下载.zip 16.2k

如果你只对js感兴趣可以右键 – [目标|链接]另存为这里:mt.mbox.js

三、使用

其使用要稍微比jQuery插件啰嗦些。当然,调用JavaScript文件是一样的,如下所示:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/mootools/1.3.0/mootools-yui-compressed.js"></script>
<script type="text/javascript" src="http://www.zhangxinxu.com/study/js/mt.mbox.js"></script>

与一般的MooTools插件不同,这里的Mbox不需要使用new运算符构造,Mbox本质上是个对象字面量,其中有个关键字叫做open,是装载元素的主要入口,所以,我们可以使用Mbox.open()来装载元素。其定义见下图:
open方法的参数 张鑫旭-鑫空间-鑫生活

可见open()方法有两个参数,第一个大家应该很熟悉,就是一堆API接口参数,第二个参数”from”是元素,但是这个元素不是用来装载的,而是通过其获取一些url地址的。此open()方法里面有个很强大的也是很关键url参数,可以是字符串,对象,id等,都可以,一般与type参数组合使用,见下图:
一些参数 张鑫旭-鑫空间-鑫生活

所以,我们要使用此弹框装载页面上一个id为test的元素,则代码就会如下:

Mbox.open({
    url: "test"
});

如果想直接load一个页面上没有的id为test的HTML代码,直接:

Mbox.open({
    url: '<div id="test">测试</div>'
});

这类非Ajax的加载,url是很智能的,type参数的功能很弱,但是,一旦设置了ajax:true,则type属性就很重要的,例如加载一个图片:

Mbox.open({
    url: "test.jpg",
    type: "image",
    ajax: true
});

这里的type属性如果不设成image的话,八成url会当成字符串处理了。type可选参数有:ele, image, ajax, iframe, swf, string,也就是加载元素,图片,load HTML,加载框架,加载Flash等。

Mbox的基本使用就是如此,非Ajax load和Ajax load,需要通过ajax参数声明。其他一些参数都是辅助性的非必须的,具体可以参见下一节的API参数介绍。

上面提到了一个"from"参数,如果此参数存在,且为元素(element),options参数中的url参数会首先从此元素上获取,默认是取得此元素的href属性值,参数名是"ajaxAttr"

除了open方法外,Mbox还有一个可以load元素的借口,方法名为"assign",此方法直接绑定了点击事件,适用于a标签直接load元素的情况,例如:

<a id="test" href="loaded.html">assign方法绑定加载</a>

Mbox.assign($("test"), {
    type: "ajax",
    ajax: true	
});

如果a标签的href是以#开头的锚点的话,是会试图此锚点id下的页面元素的哦~~

集成弹框
我之所以花大工夫整这个插件,就是下面的功能了,当当当当,alert|confirm|remind类弹框。这些弹框的调用基本上与我的jQuery弹框插件一样,例如,alert提示框直接:

 Mbox.alert("摩西摩西,欧尼酱~~");

哇咔咔,很简单很方便吧。完整的方法以及参数如下:

Mbox.alert(message, surecall, options);

message为提示信息,必选参数,可以是HTML片段,surecall为点击确定后的回调方法,可选,如果要设置options而不需要回调,记得使用null或其他什么东东占位哦,^_^

remind方法最简单直接,其效果也最简洁,没有标题栏,没有关闭按钮,或是确定取消按钮,单纯的提示,效果如下:
remind方法效果 张鑫旭-鑫空间-鑫生活

插件中有个time参数,专门留给remind弹出框使用的,可以定时关闭弹框。其调用及参数如下:

Mbox.remind(message, options);

confirm询问对话框稍微复杂些,完整方法与参数如下:

Mbox.confirm(message, surecall, cancelcall, options);

其确定的回调参数是必选的,如果没有动静,弹框是不会关闭的。cancelcall可选,默认会关闭弹框。

还有一个方法就是loading

Mbox.loading(message);

此处的message参数是可选的,默认情况就是一个loading gif动画图片和“加载中…”几个字。

一般而言,所有的Ajax load都调用了此方法,只是有时候load速度过快,看不到效果。此效果就是demo页面第三个按钮显示的效果,loading状态下,无法点击,无法关闭,只能干等,所以,必须设置load失败的回调。

此Mbox插件各个部件(标题啊,按钮什么的)类名,以及id我都写在了插件里面了,这些类名有:

类名 表示含义
mbox_win 最外框
mbox_bar 标题栏
mbox_close 关闭按钮
mbox_cont 装载内容的div
mbox_operate 集成弹框按钮所在的父div
mbox_btn_sure 确认按钮
mbox_btn_cancel 取消按钮
mbox_alert alert弹框内容外框
mbox_confirm confirm弹框内容框
mbox_remind remind弹框内容框
mbox_loading 加载中loading弹框内容外框
mbox_loading_image 加载中图片类名
mbox_ajax_image ajax加载的图片
mbox_ajax_iframe ajax加载的框架

您可以根据以上类名书写您想要的弹框样式。

四、API参数

参见下表:

参数名 默认值 含义注释
marginImage { x: 50, y: 75 } x,y键值对象,加载图片,尺寸溢出屏幕时的边缘距离
width "auto" 字符串,或是px为单位的整数值,默认"auto",表宽度自动
height "auto" 字符串,或是px为单位的整数值,默认"auto",表宽度自动
url false 可以是元素,id选择器,字符串,指用来load的元素的地址或元素本身
type "ele" 加载的元素的类型,可选参数有:ajax, string, iframe, image, swf
ajax false 是否是Ajax加载元素,如果为true,会调用loading加载中提示框,且会严格进行type类型判断
ajaxAttr "href" 通过其他元素获取url时的属性值,默认为href,暗指a标签,也可以是其他自定义的属性
ajaxOptions {} ajax发送参数,只有当type类型为"ajax"时此参数才有用
title "提示框" 标题栏的默认提示文字
ensure "确定" 确认按钮上的文字
cancel "取消" 取消按钮上的文字内容
clostxt "×" 关闭按钮上的文字
loadimg "http://www.zhangxinxu.com/study/image/loading.gif" 加载中的图片地址
overlay true 是否显示半透明背景层,默认为true,表示显示
opacity 0.35 半透明背景层的透明度
hasShim true 是否IE6下iframe填隙
overlayClosable false 点击半透明背景层是否关闭弹框
reposition true 弹框是否位置居中固定,如果为false,子弹框跟随页面滚动,无重定位
closable true 是否显示关闭按钮,remind等提示框此参数无效,注定不显示
titleable true 是否显示标题栏,remind等提示框注定不显示,alert、confirm弹框显示
optable false 是否显示默认的删除取消按钮,默认是不显示的,alert、confirm弹框死活显示
zIndex 999 层级
time 0 定时关闭弹框的时间,只对remind弹框有效,大于0的整数参数合法有效
useFx false 是否使用动画。动画效果体现在弹框显示以及重定位的时候。false为无动画。
openFrom null 页面上元素,动画效果的起始位置,以该元素为起点。仅初次弹出时有效。
resizeFx {} 额外需要的动画相关的参数
onShow $empty 弹框显示时的回调函数
onClose $empty 弹框关闭时的回调函数

其他我就不多说什么了。

五、算是结语吧

首先对此弹框插件的优缺点进行一些评价吧,首先是优点,在IE6下没有该死的select下拉框位于浮动层之上的问题,各类弹框并行,没有交集或是冲突之类;不足在于,没有拖拽效果,代码量也稍微多了些(相比jQuery),19K的样子。但是要比之前Mbox插件还要小,更不用说还合并了Prompt弹框的代码。一次只能打开一个弹框。

再对比jQuery谈下自己的感受吧。要说写插件,MooTools显然比jQuery的功力差好大一截,我的zxxbox插件(含有拖拽功能)未压缩大小仅12K,而且里面至少差不多1K的CSS代码,同样类似的效果,MooTools的代码量比jQuery要多50%,而且性能以及流畅度上貌似比现在的jQuery要逊色些。

//zxx:由于IE6下的动画效果实在卡的让人揪心,于是我禁掉了,也就是说,IE6下无动画效果。

jQuery为集成的JavaScript,充分利用了JavaScript的优美特性,充分挖掘潜能;MooTools更像是把JavaScript变成了其他东西,OOP化,予以改造。这对于我们的学习,子女教育等似乎都有启示意义。

熟悉了MooTools库后发现这也是款很优秀的插件,其自带的cookie方法,自带很多字符串,数组处理方法,其键盘事件的键值处理也很独到,但是其本身过于冰冷的感觉阻碍了其发展。

//zxx:我最近在把MooTools插件jQuery化,让像getProperty这些方法直接变成jQuery的attr等诸如此类。让后来的新人也能在jQuery习惯下使用MooTools库。

(本篇完)

分享到:


发表评论(目前17 条评论)

  1. janyee说道:

    遇到一个问题,多个同名id 如(id=”test1″)的按钮中 只有第一个可以打开弹框,有没有方法是的多个同名id 的按钮点击都可以弹框的?

  2. 逝者如斯夫说道:

    IE9下在构造的时候,调用build时在
    this.win = new Element(‘div’, {
    id: ‘mboxWindow’,
    ‘class’: ‘mbox_win’,
    styles: {
    width: w,
    top: t,
    left: l,
    position: ‘absolute’,
    zIndex: this.options.zIndex + 2,
    visibility: ‘hidden’
    }
    }).set(“html”, boxConstr);
    这里出问题。

  3. 逝者如斯夫说道:

    IE9下好像有问题,还没找到是哪儿的问题!

  4. ahahah说道:

    使用confirm后,确认执行事件,不能执行ajax业务。怎处理?

  5. Andrew说道:

    6楼朋友的问题估计是 估计(可能是控件中)没有相应的进行destroy操作(除去元素附加属性和事件,元素引用置null), 让IE去合理回收内存,IE低版本在内存回收上有点问题 可以参考 业界的犀牛书

  6. loethen说道:

    写的不错。。支持一下

  7. ahstudy说道:

    还有一个问题,为什么我在设置提示标题和关闭按钮的时候没有用,就是我无法在初始化时options中关闭提示信息和关闭按钮的出现

  8. ahstudy说道:

    不知道作者是否还在关注此网站更新,我想问一下,这个弹出窗插件是否支持拖动??如何设置??

    • 张 鑫旭说道:

      @ahstudy 外部建立一个拖拽的公共方法,例如var $startDrag = function(bar, target) { /* ... */ },然后插件中增加dragable参数,在showControl方法处增加类似:
      //是否可拖拽
      if (this.options.dragable) {
      $startDrag(this.bar, this.win);
      }

  9. 游客说道:

    用了这个,IE下内存不断上升,最终导致死机

  10. mywaiting说道:

    首先说明,偶是Mootools的Fans。这么说吧,在我看来,你的观点难免有点偏颇了。
    1. Mootools的设计思想本来跟jQuery就不同,由于扩展了原生对象,Mootools很容易修复不同EMAC标准间的Js的实现的差异,但这也是Mootools让大众不敢近身的缺点吧。呵呵。
    2. Mootools的OOP只是让你更好地组织代码的吧,不是让你去把Js OOP的啦,这个不要曲解啦。呵呵。
    3. 冒着被拍死的危险,顺便说一句让广大jQuery Fans不高兴的话,jQuery做得到的事情,Mootools肯定做得到;但反过来就不是很好用了,至少写代码没有Mootools这么顺手吧。呵呵。
    4. 最后来一句总结,快速开发就jQuery吧,插件也多,快速也方便。但要是准备大点的项目,或者说不喜欢满屏幕的dollar符号,用Mootools一定没错。呵呵。

  11. 水色说道:

    options设计的非常好,配合默认值,用户可以很方便的使用,
    而form的设计我不太认同,个人觉得这儿应该接入的是一段html,
    而至于html从哪儿来,怎么来,应该交给使用者自己去解决,
    包揽的好处在于方便,但获取html我还是觉得不应该是由弹框本身提供,
    标题栏,按钮等也可以开放一下,但程序本身还应该提供关闭方法

  12. Oopen-Lib说道:

    你好,你的插件已被Open-Lib.Com收录。
    感谢你的贡献。

  13. pifoo说道:

    效果很不错

  14. 雪璇舞说道:

    资料总是这么详尽,讲解的也很仔细明白,我是JS的小白,属于知其然不知其所以然的那种,来这里获益匪浅~谢谢你这里的好文字!