[阿当视频]WEB组件学习笔记

1. JS分层和组件的种类


浏览器底层包括
HTML CSS JS(DOM/BOM/Style/Canvas 2D/WebGl/SVG)

框架核心层解决的问题
JS核心语法层面薄弱(面象对象 包等)
JS原生API不好用(cookie ajax)
浏览器兼容问题
框架:Prototype YUI Dojo jQuery等

框架组件层又分为:框架通用组件和定制组件
原生浏览器只提供了一些简单的控件:input text checkbox radio select
没有提供:日历选择器、富文本编辑等

组件分为:框架组件、定制组件(前两者第三方提供)和独立组件(没有任何依赖,中间没有框架核心层直接就是原生JS,开发过程中发现重用模块并抽象出来的组件

应用层
具体项目需求

2. CSS命名空间
1)全名前加前缀,没有副作用,轻巧性价比高
2)把所有的CSS挂在一个类中,用子孙选择器的缺点
- 复用困难,跨团队困难
- 样式和HTML结构偶和
- 权重

3. 引入require.js

<script src="scripts/require.js" data-main="scripts/main.js" ></script>

4. 弹窗组件
简单版(有确定和关闭按钮) —>定制长宽和位置 —>调整接口格式—>定制标题—>定制关闭按钮—>定制皮肤—>定制按钮文案—>模态—>拖动

以下是代码

require.config({
    paths:{
        jquery:'jquery-3.1.0.min',
        jqueryUI:'http://code.jquery.com/ui/1.12.0/jquery-ui.min'
    }
})

define(['jquery','jqueryUI','Window'],function($,$UI,w){
    $('input').click(function(){
        new w.Window().alert({
            title : '友情提示',
            content : '自定义内容',
            width : 300,
            height : 150,
            y : 50,
            hasCloseBtn : true,
            hasMask : true,
            isDraggable : true,
            dragHandle : '.window_header',
            skinClassName : 'window-skin-a',
            textBtn : 'OK',
            handlerBtn : function(){
                console.log('you click the button')
            },
            closeBtn : function(){
                console.log('you click the close button')
            }
        });
    })
})
main.js
define(['jquery','jqueryUI'],function($,$UI){
    function Window(){
        this.cfg = {
            width : 500,
            height : 300,
            title : '',
            content : '',
            hasCloseBtn : false,
            hasMask : false,
            isDraggable : false,
            skinClassName : null,
            textBtn : '确定',
            handlerBtn : null,
            closeBtn : null,
            dragHandle : null
        }
    }

    Window.prototype = {
        alert : function(cfg){
            var CFG = $.extend(this.cfg,cfg),
            boundingBox = $(
                '<div id="window_boundingBox">'+
                '<div class="window_header">'+ CFG.title +'</div>'+
                '<div class="window_body">'+ CFG.content +'</div>'+
                '<div class="window_footer"><input type="button" value="'+ CFG.textBtn +'" class="btn" /></div>'+
                '</div>'
                ),
            btn = boundingBox.find('.window_footer input'),
            mask = $('<div class="mask"></div>'),
            closeBtn = $('<div class="close">X</div>');
            if(CFG.hasCloseBtn){
                closeBtn.appendTo(boundingBox);
                closeBtn.click(function(){
                    CFG.closeBtn && CFG.closeBtn();
                    boundingBox.remove();
                    mask && mask.remove();
                })
            }
            if(CFG.skinClassName){
                boundingBox.addClass(CFG.skinClassName);
            }
            if(CFG.hasMask){
                mask.appendTo('body');
                mask.click(function(){
                    boundingBox.remove();
                    mask && mask.remove();
                })
            }
            if(CFG.isDraggable){
                if(CFG.dragHandle){
                    boundingBox.draggable({handle:CFG.dragHandle});
                } else{
                    boundingBox.draggable();
                }
            }
            boundingBox.appendTo('body');
            btn.appendTo(boundingBox);
            btn.click(function(){
                CFG.handlerBtn && CFG.handlerBtn();
                boundingBox.remove();
                mask && mask.remove();
            })
            boundingBox.css({
                width : this.cfg.width + 'px',
                height : this.cfg.height + 'px',
                left : (this.cfg.x || (window.innerWidth - this.cfg.width)/2 ) + 'px',
                top : (this.cfg.y || (window.innerHeight - this.cfg.height)/2 ) + 'px'
            })
        },
        confirm : function(){

        },
        prompt : function(){

        }
    }

    return {
        Window : Window
    }
})
window.js
*{
    padding: 0;
    margin: 0;
}
body{
    height: 100%;
}
#window_boundingBox{
    width: 300px;
    height: 150px;
    border:1px solid #666;
    position: absolute;
    left: 50%;
    top: 20%;
    background: white;
}
.window_header{
    background: #999;
    font-size: 16px;
    padding:0 10px;
    height: 30px;
    line-height: 30px;
}
.window_body{
    padding: 10px;
}
.btn{
    position: absolute;
    left: 0;
    text-align: center;
    bottom: 10px;
    left: 50%;
    width: 50px;
    text-align: center;
    margin-left: -25px;
}
.close{
    width: 30px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    background: #666;
    right: 0;
    top: 0;
    position: absolute;
    color: white;
}
.mask{
    background: rgba(0,0,0,0.5);
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
}
/*换肤*/
.window-skin-a .window_header{
        background: #ccc;
}
.window-skin-a .close{
        background: #999;
}
css

5. 自定义事件
本质:观察者模式
优点:跳出原生事件的限制,提高封装的抽象层级

6. 连缀语法
和jQ中的链式操作写法一样,组件的方法中return this,main.js中new出的构造函数后以点的方式进行连缀

7. 自定义组件
Widget抽象类:和UI相关的类型组件
申明Widget模块,window.js中继承widget类,通过$.extend()方法进行混合,接收多个字典对象,对象也是一个字典
Widget类设计统一生命周期

一个属性,两个方法,四个交给子组件的接口

this.boudigBox = null //属性:最外层容器
destroy //方法:销毁组件

render //方法:渲染组件

renderUI //接口:添加dom节点

bindUI //接口:监听事件

synUI //接口:初始化组件属性

destructor //接口:销毁前的处理函数

另外还讲了confirm,prompt,common方法:通用窗体,四种类型的弹窗已完,可自己再进行进阶:组件的MVC。

贴出视频链接:阿当大话西游之WEB组件

 

posted @ 2016-07-22 16:11    阅读(292)  评论(0编辑  收藏  举报