乔花
2010.09
一. 应用场景
二. 同类组件
三. 功能分析
四. 技术方案
五. Public API
六. 开发计划
七. 其它
页面上的覆盖层;
对话框层;
Popup 层;
很多很多网站上都有这类似的覆盖层效果;
1. YUI3:http://developer.yahoo.com/yui/3/overlay/ * new Y.Overlay(cfg); * 扩展于Widget, DOM基本结构包含hd,bd,ft; * 提供 位置相关属性(x, y, xy, centered), zIndex, align, shim(加iframe, IE6下默认true), constrain(固定在可视区域中间); * 提供 与修改对应 Attributes 的方法, 主要有 内容(WidgetStdMod), 位置(WidgetPosition, WidgetPositionConstrain), 大小这几个方面的方法; * WidgetPositionAlign, 提供 Align, 支持对齐到某个元素, 整个可视区域, 特定位置上; * WidgetStack, 提供 Stacking, 需要zIndex和shim支持, 当有多个 Overlay 时, 某个层获得焦点时, 将其置于顶层(对应方法 bringToTop ) * 自定义事件 xyChange, bodyContentChange, * Overlay相关的Plugin, 通过 overlay.plug(XXX, cfg)/ overlay.unplug(XXX) 使用: # StdModIO, 提供标准的输入输出, 包含initializer, destructor, formator, 在Overly中实例化为overlay.io; # Animation, 提供Overly的动画展现效果, animHidden/animVisible定义如何展现; 2. JQuery UI, 没有提供 Overlay , 但提供了所有组件的基类 Widget, 扩展出 Dialog , 和相关组件, 如 Draggable(拖拽), Droppable, Resizable. * JQuery Core + Widget + Position + Dialog, 压缩后21K; * Widget, 所有组件的基类, 提供 create, destroy, enable, disable等通用方法; * 使用 $(id).dialog(); # 提供 定制宽高度, resize, 位置, 是否模态窗口, 可拖拽, 支持 按钮; # 提供的方法有 destroy, open, close, enable, disable, moveToTop, stack, 这些都是类似窗口最基本的方法; # 自定义事件有 open, close, beforeClose, focus, drag 等;
3. Mootools, 由 moord 提供的 overlay.js * 77.3K (未压缩, 包含依赖文件), 但纯 Overlay 仅100多行; * new Overlay() 创建 overlay 对象; * 提供 创建, 删除 Overlay, 设置 颜色深浅 透明度, 功能比较简单; * 基于Overlay扩展的组件有 virtual box , 弹出层功能: # virtual-base 为基类; # 扩展有 virtual-box (基本的box), virtual-ajax (请求之后显示内容), virtual-html (动态设置html内容); # virtual box 系列 提供 设置动画效果, 自定义样式, 位置居中等选项, 提供 onShow, onClose, onNext, onPrev 自定义事件; 4. Dojo 的 Dijit 提供了 digit.Dialog. * Dialog+DialogUnderlay 共22K, 不包含一些依赖库. * new dijit.Dialog(cfg); * 支持resize, 拖拽, 表单操作, 和其他类似, 不重复讲了; * 焦点的处理;
- 数据层: * 内容的可自定义设置: # 独立设置 hd, bd, ft 三部分内容; * 后台请求过来的动态数据; # 表单数据; # iframe; # ajax; * 数据解析及格式化: # json; # formator; - 展现层: * 大小: # 设置宽度/高度; # resize; * 位置: # 绝对位置; # 相对于元素的位置; # zIndex, shim , stack; * 对齐: # 相对于元素的对齐; # 在容器或可视区域内的对齐; * 动画: # 主要是在显示/隐藏Overlay时的动画效果, 直接利用 kissy/anim, 类似 switchable 的 plugin-effect; - 其他: * 支持按钮? * Drag + Drop?
本质: 弹出一个层, 并且可以动态设定层位置;
- 将 Overlay 抽象处理, 只处理上面这句话的功能;
- Dialog, Popup 在 Overlay 基础上扩展, 加入自己特点;
DOM 结构
分为两种情况, 一个是已有 DOM, 一个是新建. 两者统一起来, 最终生成的 DOM 结构 如下:
/* * <div class="ks-overlay-container"> * <div class="ks-overlay-bd"></div> * </div> */
当没有内容时, 不会创建 body 层;
位置计算
采用YUI3的组织方式, 利用容器元素及参考元素上各自的九个不同位置点('tl', 'tc', 'tr', 'cl', 'cc', 'cr', 'bl', 'bc', 'br')进行组合定位, 如下图所示:
Shim 和 Mask
Shim, 在 IE6 下是必备; 而 Mask 覆盖层, 通过选项设置;
Shim 和 Mask 本质上也是一致的, 都是新建一个层( div 或者 iframe ), 放在 Overlay 层 下方; 所以我们也把 Shim 和 Mask 合并起来;
S.Dialog
固定的DOM结构, 在 Overlay 基础上 增加 header, footer, close 按钮(is closeable)
/* * <div class="ks-overlay-container"> * <div class="ks-overlay-hd"> * <div class="ks-dialog-close"></div> * </div> * <div class="ks-overlay-bd"></div> * <div class="ks-overlay-ft"></div> * </div> */
另外, 增加 DialogManager 提供管理页面上 Dialog 的方法;
S.Popup
基本上同 Overlay, 但触发类型默认为 'mouse', 弹出层位置默认为触发元素的右侧
var defaultConfig = { triggerType: 'mouse', // 触发类型, click, mouse align: { node: 'trigger', points: ['cr', 'ct'], offset: [10, 0] } };
S.Overlay
config: container: null, // Overlay 容器, 默认为 null 时, 表示新建 DOM; containerCls: CLS_CONTAINER,// 容器 class , 默认 class 为 'ks-overlay' content: undefined, // 默认为 undefined, 不设置 bdCls: CLS_PREFIX + 'bd', // body class, 默认为 'ks-overlay-bd' trigger: null, // 触发元素, 默认为 null 时, Overlay 动作需要另外 js 指定 triggerType: 'click', // 触发类型, 'mouse' or 'click', 默认为 'click' width: 0, // 容器宽度 height: 0, // 容器高度 zIndex: 9999, // z-index 值 xy: null, // 相对页面定位, 有效值为 [n, m] x: 0, // x, y 坐标 y: 0, align: { // 相对指定 node or viewport 定位 node: null, // 参考元素, falsy 值为可视区域, 'trigger' 为触发元素, 其他为指定元素 points: [POSITION_ALIGN.CC, POSITION_ALIGN.CC], // ['tl', 'tr'] 表示 overlay 的 tl 与参考节点的 tr 对齐 offset: [0,0] // 水平, 垂直方向上的偏移, 有效值为 [n, m] }, mask: false, // 是否显示蒙层, 默认不显示 shim: ie6 // 是否需要垫片, IE6下默认需要
绝对定位(xy)与对齐(align)优先级: 当设置 xy 为Truth时, 使用绝对定位, 否则使用对齐; 默认使用对齐.
Member: container // 指向容器元素 trigger // 触发元素, 支持多个触发器 currentTrigger // 当前触发器 body // 容器 body 元素, 当 content 为空时, //不创建 ks-overlay-bd 层, 且 body 直接指向 container shim // 垫片层, 如果选项中 shim 设置为 true Method: show() // 显示 hide() // 隐藏 move(x, y) // 将 overlay 移动到指定位置上, 绝对位置 align(node, points, offset) // 将 overlay 定位到指定节点的特定位置上, // 如果没有指定 node, 会默认使用 config 中的 align 设置 center() // 将 overlay 居中到当前可视区域上 setBody() // 设置 body 内容
S.Dialog 增加了 header 和 footer, config 和 method 做了对应调整
config: header: '', // header 内容 footer: '', // footer 内容 containerCls: CLS_CONTAINER, // 设置 containerCls , 默认为 'ks-overlay ks-dialog' hdCls: CLS_PREFIX + 'hd', // 设置 header 的 class , 默认为 ks-dialog-hd bdCls: CLS_PREFIX + 'bd', // 设置 body 的 class , 默认为 ks-dialog-bd ftCls: CLS_PREFIX + 'ft', // 设置 footer 的 class , 默认为 ks-dialog-ft closeBtnCls: CLS_PREFIX + 'close', // 设置关闭按钮的 class, 默认为 ks-dialog-close width: 400, // 设置容器宽度, 默认为 400 height: 300, // 设置容器高度, 默认为 300 closable: true // 是否需要关闭按钮, 默认需要 Member: header // 对话框头部的HTML元素 footer // 对话框尾部的HTML元素 manager // 当前 DialogManager ID // 唯一的 ID Method: setHeader() // 设置 header 内容 setFooter() // 设置 footer 内容
S.DialogManager
用于管理页面上所有的 Dialog , 目前提供功能较少
Method: register() // 将 dialog 实例注册到 DialogManager 中 hideAll() // 隐藏页面上所有的 dialog get(id) // 根据 id 获取对于的 dialog 对象
S.Mask
统一了 shim 和 mask , 会在 body 最后加入 shim 层或 mask 层
Config: shim: false, // 是 shim 层还是 mask 层 opacity: .6, // 指定 mask 的透明度 style: '' // 指定样式 Member: iframe // shim 和 mask 下都会有, mask 时, 标准浏览器也用 iframe 元素生成mask config // 配置选项 layer // mask时, 且在IE下才会有这个成员, 由于 iframe 不能设置 background, // 所以添加了一 div 作为 layer , 设置透明度及背景颜色 Method: show() // 显示 hide() // 隐藏 toggle() // 切换显示/隐藏 setSize() // 设置宽高 setOffset() // 设置位置, 绝对位置
基本使用, Popup
KISSY.ready(function(S) { var popup = S.Popup({ trigger: '#link2', triggerType: 'mouse', width: 300, height: 200, containerCls: 'popup2', content: 'test popup', align: { node: 'trigger', points: ['tr', 'tl'] } });
基本使用, Dialog
KISSY.ready(function(S){ var dialog = S.Dialog({ trigger: '#btn4', containerCls: 'dialog4', width: 400, height: 300, title: 'this is title', footer: 'footer', content: 'content', mask: false }); var times = 1; dialog.on('show', function(){ dialog.setBody('show'+(times++)); }); S.Event.on('#btn5', 'click', function(e){ dialog.manager.hideAll(); }); });
9月, 实现基本功能.
使用文档: http://kissyteam.github.com/kissy/docs/overlay/index.html
测试页面: http://kissyteam.github.com/kissy/src/overlay/test.html