EXT典型范例 Image Chooser源码大剖析

EXT做出来的效果不用多说。但EXT只是JS+CSS,究竟是什么 能量 或者说“技术”吸引大家的眼球呢?
Jack自然是最清楚的,不过好歹小弟我也研究多时,且让我慢慢揣摩其奥秘之处!

p.s:下列代码肯定是重构过,一般写JS开始时不会有如此有条理的,--可先不理条理、优雅的代码 反正先弄懂API再说

Image Chooser Demo:http://extjs.com/deploy/ext/examples/view/chooser.html

chooser-example.js:

Ext.onReady(function(){
       
        //先声明一些变量
    var chooser, btn;
   
//    创建一个Button XHTML页面中必须有下列makup容器(style可根据需求修改):
//    <div id="buttons" style="margin:20px;"></div>
     btn = new Ext.Button('buttons', {
            text: "Insert Image",
                handler: choose //当按钮被按下的时候,接着发生的事情。注意是没有括号的函数名称
                /**
                 * 在JS中, 一个函数有括号 和没有括号,是不同的。
                 * 通常来说括号()可理解为对函数的执行,表示一个动作;
                 * 使用不带括号的函数名称,则表示 “获取函数的地址”。
                 * 具体说明参阅微软文档:[url]http://jstang.5d6d.com/thread-64-1-1.html[/url]
                 */
       
        });
     function choose(btn){
             //判断是否已有chooser (Singleton)
            if(!chooser){
                    chooser = new ImageChooser({
                            url:'get-images.php',
                            width:515,
                            height:400
                    });
            }
            chooser.show(btn.getEl(), insertImage); //show()为ImageChooser的方法
    };
    function insertImage(data){
            //利用DomHelper动态加入元素,而这些都是div id="images“的子元素。
            //img的url地址由参数传入的data中的url属性决定(data的类型为object)
            //初始样式为外补丁10px,不可见       
            Ext.DomHelper.append('images', {
                    tag: 'img', src: data.url, style:'margin:10px;visibility:hidden;'
            }, true).show(true);// 这里先隐藏在show()的目的是做出动画效果,true为带有动画。
            btn.getEl().focus();
    };

});


chooser.js

var ImageChooser = function(config){
        // 创建一个对话框 -开始
    /*
     * config.id || Ext.id() 意思为:优先使用config.id;没有的话,用Ext.id()
     * 【逻辑运算符”||“常用与设置默认值】
     * Ext.id()方法能动态生成不重复的id,如:
              Ext.id()
                        "ext-gen87"
                Ext.id()
                        "ext-gen88"
                Ext.id()
                        "ext-gen89"
     */
   
    var dlg = new Ext.LayoutDialog(config.id || Ext.id(), {
                autoCreate : true,
                minWidth:400,
                minHeight:300,
                syncHeightBeforeShow: true,
                shadow:true,
        fixedcenter:true,
        center:{autoScroll:false},
                east:{split:true,initialSize:150,minSize:150,maxSize:250}
        });
        dlg.setTitle('Choose an Image');
        dlg.getEl().addClass('ychooser-dlg');
        dlg.addKeyListener(27, dlg.hide, dlg); // Esc键可隐藏
       
    // 创建一个对话框 -结束
    //在对话框上加入‘ok'按钮,
    // this.ok指针指向该按钮对象(对象由addButton()执行后返回),
    // 并分配一个callback( this.doCallback 作用:将选好的图片,加入背景中)
   
    this.ok = dlg.addButton('OK', this.doCallback, this);
    this.ok.disable();//先禁止,因为刚开始时数据加载中
    /**
     * 这里完成了两件事情:a.新建一个cancel按钮 b.设置这个按钮为默认的
     */
    dlg.setDefaultButton(dlg.addButton('Cancel', dlg.hide, dlg));
    dlg.on('show', this.load, this); //当对话框显示时,立刻加载数据
        this.dlg = dlg;
        var layout = dlg.getLayout();
       
        // filter/sorting toolbar
        this.tb = new Ext.Toolbar(this.dlg.body.createChild({tag:'div'}));
        this.sortSelect = Ext.DomHelper.append(this.dlg.body.dom, {
                tag:'select', children: [
                        {tag: 'option', value:'name', selected: 'true', html:'Name'},
                        {tag: 'option', value:'size', html:'File Size'},
                        {tag: 'option', value:'lastmod', html:'Last Modified'}
                ]
        }, true);
        this.sortSelect.on('change', this.sortImages, this, true);
       
        this.txtFilter = Ext.DomHelper.append(this.dlg.body.dom, {
                tag:'input', type:'text', size:'12'}, true);
               
        this.txtFilter.on('focus', function(){this.dom.select();});
        this.txtFilter.on('keyup', this.filter, this, {buffer:500});
       
        this.tb.add('Filter:', this.txtFilter.dom, 'separator', 'Sort By:', this.sortSelect.dom);
       
        // 在布局中加入一些面板panel beginUpdate()
        layout.beginUpdate();
        var vp = layout.add('center', new Ext.ContentPanel(Ext.id(), {
                autoCreate : true,
                toolbar: this.tb,
                fitToFrame:true
        }));
        var dp = layout.add('east', new Ext.ContentPanel(Ext.id(), {
                autoCreate : true,
                fitToFrame:true
        }));
    layout.endUpdate();
        // 在布局中加入一些面板panel endUpdate()       
        var bodyEl = vp.getEl();
        bodyEl.appendChild(this.tb.getEl());
        //
        /*vp-->包含this.tb(工具条)和 viewBody(视图view的主体)
         * 试比较appendChild()和createChild()的区别
         * appendChild()->"Appends the passed element(s) to this element "
         *   
     *                         加入传入的element(s)到该element
     *                         @param {String/HTMLElement/Array/Element/CompositeElement} el
     *                         @return {Ext.Element} this
     *
         * createChild()-->"Creates the passed DomHelper config and
         * appends it to this element or optionally inserts it before the passed child element. "
         */
        var viewBody = bodyEl.createChild({tag:'div', cls:'ychooser-view'});
        vp.resizeEl = viewBody;
       
        this.detailEl = dp.getEl();
       
        // 创建缩略图的HTML模板
        this.thumbTemplate = new Ext.Template(
                '<div class="thumb-wrap" id="{name}">' +
                '<div class="thumb"><img src="{url}" title="{name}"></div>' +
                '<span>{shortName}</span></div>'
        );
        this.thumbTemplate.compile();        //编译DOM加速
        // 创建详细资料的HTML模板
        this.detailsTemplate = new Ext.Template(
                '<div class="details"><img src="{url}"><div class="details-info">' +
                '<b>Image Name:</b>' +
                '<span>{name}</span>' +
                '<b>Size:</b>' +
                '<span>{sizeString}</span>' +
                '<b>Last Modified:</b>' +
                '<span>{dateString}</span></div></div>'
        );
        this.detailsTemplate.compile();        //编译DOM加速
   
    //初始化view视图
        this.view = new Ext.JsonView(viewBody, this.thumbTemplate, {
                singleSelect: true,
                jsonRoot: 'images',
                emptyText : '<div style="padding:10px;">No images match the specified filter</div>'
        });
    this.view.on('selectionchange', this.showDetails, this, {buffer:100});//事件触发后延时100才执行
    this.view.on('dblclick', this.doCallback, this); //双击图片,加入背景中
    this.view.on('loadexception', this.onLoadException, this);
    this.view.on('beforeselect', function(view){
        return view.getCount() > 0;
    });
    //将配置项对象的属性 和this合二为一
    Ext.apply(this, config, {
        width: 540, height: 400
    });
    //格式化kb的小函数
    var formatSize = function(size){
        if(size < 1024) {
            return size + " bytes";
        } else {
            return (Math.round(((size*10) / 1024))/10) + " KB";
        }
    };
   
    // 创建一个lookup对象,用查找图片名时用
    var lookup = {};
    //这里override了prepareData(),可在模板中使用自定义的属性
    this.view.prepareData = function(data){
            data.shortName = data.name.ellipse(15);
            data.sizeString = formatSize(data.size);
            data.dateString = new Date(data.lastmod).format("m/d/Y g:i a");
            lookup[data.name] = data;//保存到lookup的hash table中
            return data;
    };
    this.lookup = lookup;//成为对象的一员
    /*
     * this.width, this.height哪里来?由config配置项对象获得(前面已经apply())
     */
        dlg.resizeTo(this.width, this.height);

        this.loaded = false;
};

你可能感兴趣的:(html,PHP,css,XHTML,ext)