论坛首页 Web前端技术论坛

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

浏览 7571 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-05-19  
“EXT典型范例 Image Chooser源码大剖析”

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

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

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中, 一个函数有括号 和没有括号,是不同的。
		 * 通常来说括号()可理解为对函数的执行,表示一个动作;
		 * 使用不带括号的函数名称,则表示 “获取函数的地址”。
		 * 具体说明参阅微软文档:http://jstang.5d6d.com/thread-64-1-1.html
		 */
	
	});
     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合二为一,拷贝config对象的所有属性给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中 以图片名称为关键字缓存data中的数据,方便查找对象
    	return data;
    };
    this.lookup = lookup;//用lookup初始化对象的lookup成员变量 成为对象的一员
    /*
     * this.width, this.height哪里来?由config配置项对象获得(前面已经apply())
     */
	dlg.resizeTo(this.width, this.height);

	this.loaded = false;
};
   发表时间:2007-05-19  
呵呵 不错 ,我觉得在来点基础知识的铺垫就更好了
0 请登录后投票
   发表时间:2007-05-19  
pengjun_lovecoding@hotmail.com 写道
呵呵 不错 ,我觉得在来点基础知识的铺垫就更好了


对于新手补习基础知识可以看这里:

http://extjs.com/tutorials/beginner

http://extjs.com/forum/showthread.php?t=441

http://extjs.com/forum/showthread.php?t=876
0 请登录后投票
   发表时间:2007-05-21  
Thanks to lonelyblue 的建议。
注释部分略为修改
0 请登录后投票
   发表时间:2007-05-21  
标题取得太过火了,想看都不想看了
0 请登录后投票
   发表时间:2007-05-21  
boogie 写道
标题取得太过火了,想看都不想看了

呵呵 不好意思 抱歉! 犯众憎了 我已修改
其实在下的原意是自己先带个头,让大家一起讨论源码!
0 请登录后投票
   发表时间:2007-05-21  
先来个Image Choose总体介绍效果回更好
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics