S.Overlay

乔花

2010.09

Outline

一. 应用场景

二. 同类组件

三. 功能分析

四. 技术方案

五. 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]
    }
};
                
五. Public API

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