存档

2010年9月 的存档

js项目中的事件通讯。

2010年9月19日 effect 没有评论

说明:本文是对文章:http://web302.com/2010/08/js-function-of-several-useful/的补充

很多的web应用都是基于事件驱动的,比如tab切换。有两个选项卡,通过click或者mouseover事件来驱动展现情况。类似这种应用场景数不胜数。像这种应用是给dom对象绑定click事件就可以完成,非常之简便。

像上面那个例子,就是典型的事件驱动的应用场景。现在有个社区型的应用场景:有一个用户中心页面,首先从服务器拉取用户的个人信息,然后再根据用户的信息分表去拉取用户的好友列表,站内信个数等信息。

常规处理:

这个很简单,异步拉取用户信息,拉取成功之后就分别执行对应的方法,如拉取好友列表,拉取站内信个数等。下面贴下伪代码:

ajax('/getuser?uid=123',function(response){
    loadFriend(response);//拉取好友列表
    loadMsgNum(response);//拉取消息个数
    ...............
});

这个处理方式没有任何问题。现在假设某台需求有变更,还要拉取用户的动态信息,现在是不是又要更改这个回调,加上loadDt(response)。假设需求又有变动,拉取好友从loadFriend函数改为loadFriendTwo()。想象一下,如果处理好友列表和拉取个人信息的模块不是同一个职员在处理,那么每次改动都要涉及到两个人的改动,也许更多。而且两者之间的耦合性也是非常之强的!有没有更好的处理方式吗?

现在回到本文开头提到的事件处理。如果有个DOM,当用户点击这个DOM之后,A同事要处理一些事情,B同事也要处理一些事情。那么很自然的A同事监听这个DOM的CLICK事件,B同事也是可以注册自己的事件监听,这样是不是没有任何的耦合?

事件处理:

这样我们就可以用事件的方式来处理这个应用场景,让各个模块注册自己的监听回调,等拉取个人信息成功之后就触发这个事件。下面看第二种方式的伪代码:

function user(uid){
   this.uid=uid;
}
event(user,EventSource);//让user继承EventSource。
user.prototype.load=function(){
         var that=this;
         ajax("/getuser?uid="+this.uid,function(response){
                  that.fireEvent('onUserReady',response);
         });
}
 
var userObj=new user(123);
 
//加载好友模块开始
userObj.addEventListener(userObj,'onUserReady',loadFriend);
function loadFriend(that,event,response){
 
}
//加载好友模块结束
 
 
//加载消息个数模块
userObj.addEventListener(userObj,'onUserReady',loadMsgNum);
function loadMsgNum(that,event,response){
 
}
//结束

如果以后有别的业务逻辑就继续增加监听而不是硬编码的回调,大大降低了耦合性。 阅读全文…

多选项的保存

2010年9月10日 effect 没有评论

先贴上代码,稍候来阐述

function selectToDec($select,$all){
	$bin='';
	foreach($all as $s){
		if(in_array($s,$select)){
			$bin.='1';
		}
		else $bin.='0';
	}
	return bindec($bin);
}
function DecToSelect($dec,$all){
	$bin=decbin($dec);
	if(strlen($bin)<count($all)){
		$bin = str_pad($bin, count($all), "0", STR_PAD_LEFT); 
	}
	var_dump($bin);
	$select=array();
	for($i=0;$i<strlen($bin);$i++){
		if($bin[$i]==1) $select[]=$all[$i];
	}
	return $select;
}
分类: php 标签:

编写js模板引擎:TrimPath的扩展

2010年9月9日 effect 没有评论

1.TrimPath是什么?
javascript模板引擎。

2.主要用途是?

想象一下有这么一个应用场景:在我的个人中心页面,客户端通过异步请求,去拉取自己的好友列表的裸数据,然后把这些好友展示出来。当然可以通过传统的方法,ajax请求,然后通过JS代码拼装一段字符串,然后展示在页面上的某个地方。这个方法真痛苦,有时候要处理那种单引号,双引号,会让你抓狂,及其容易出现低级失误。所以这个模板引擎就是来拯救你的。

3.基本资料和教材

http://code.google.com/p/trimpath/wiki/JavaScriptTemplates   下载地址,API,DOC等信息

http://bbs.chinaunix.net/thread-735901-1-1.html   CU上面比较详细的教程。

4.重头戏,增加扩展

假设有这么一个应用场景:注册到模板里面的某个变量是一个数组,现在要你把这个数组用中文的分号(;)连接成一个字符串。类似这样的场景很多,比如给你一个时间,格式化成相对现在的相对时间(如:5分钟前,昨天,刚刚等)。

官方提供的扩展有:default、capitalize、eat、escape、h。这些扩展的用途见:http://code.google.com/p/trimpath/wiki/JavaScriptTemplateModifiers

好了,现在回到上面的那个需求:用中文分号连接数组,其实很简单:

TrimPath.parseTemplate_etc.modifierDef.join=function(array,split){
	if(!$.isArray(array)) return '';
	split=split||';';
	return array.join(split);
}

在你的模板里面可以这样使用:
$[arrName|join:';']

搞定!

分类: javascript 标签: , ,

v哥的pop弹出插件的几点改动

2010年9月6日 effect 2 条评论

v哥哥的弹出插件在:http://www.myquickphp.com/archives/163
这个插件存在的问题:
1.暴露给$.fn的接口过多
2.会影响其他的window.onresize window.onscroll document.onmousemove事件
3.谷歌浏览器chrom不兼容(表现在scroll事件和resize事件失效)

修改过后的代码:

(function($){
	function divDragGable(titleDivid , dragDivid)
	{
		document.getElementById(titleDivid).style.cursor = "move";
		document.getElementById(titleDivid).onmousedown=function(e){
			var posX;
			var posY;  
			var fdiv = document.getElementById(dragDivid); 
			if(!e) e = window.event;
			posX = e.clientX - parseInt(fdiv.style.left);
			posY = e.clientY - parseInt(fdiv.style.top);
			function mousemove(ev){
				if(ev==null) ev = window.event;
				fdiv.style.left = (ev.clientX - posX) + "px";
				fdiv.style.top = (ev.clientY - posY) + "px";
				return false;
			}
			$(document).mousemove(mousemove).mouseup(function(){
				$(document).unbind('mousemove',mousemove);
			});
		}
	}
	function setDivPox(jqBackDiv,jqPopDiv,isScrollEvent)
	{
		//自动判断当前是否支持W3C标准的
		var bodyObj = document.documentElement;
		//文档没有DOCTYPE声明,是 HTML文档,否则是XHTML文档
		if(document.compatMode == 'BackCompat'){
			bodyObj = document.body;
		}
		//--设置遮罩层为满屏
		jqBackDiv.width(Math.max(bodyObj.scrollWidth, document.documentElement.clientWidth));
		jqBackDiv.height(Math.max(bodyObj.scrollHeight, document.documentElement.clientHeight));
		//调整要显示的DIV的位置
		var dleft = bodyObj.clientWidth/2 - jqPopDiv.width()/2;
		var dtop = bodyObj.clientHeight/2 - jqPopDiv.height()/2;
		//如果是Scroll事件
		if(typeof(isScrollEvent)!= 'undefined' && isScrollEvent){
			dleft += bodyObj.scrollLeft + document.body.scrollLeft;
			dtop += bodyObj.scrollTop + document.body.scrollTop;
		}
		jqPopDiv.css({left:dleft,top:dtop,position:'absolute',zIndex:1001});
	}
	function pop(options,jq){
		$.extend(this.options,options || {});
		this.jq = jq;
	}
	pop.prototype={
		options:{
			closeId:'',//可以执行关闭当前层的DOM ID,这个值是可选项
			titleId:'', //层移动的DOM ID,这个值是可选项,
			backDivColor:'#333',//遮罩层的颜色
			showAnimate:true, //弹出层显示时是否有动画效果
			backDivId:'pop__div__id'//遮罩层的ID,一般不在程序中设置
		},
		show:function(){
			//弹出一个遮罩层
			var backDivId = this.options.backDivId;
			//--如果弹出层不存在则添加
			if($('#'+backDivId).length < 1){
				//--遮罩层追加到 body  //#333
				var divStr = '<div id="'+backDivId+'" style="background-color:'+this.options.backDivColor+';filter: Alpha(Opacity=40); -moz-opacity:.1; opacity:0.5;  position:absolute; left:0px;top:0px; z-index:1000"></div>';	
				$(divStr).appendTo('body');
			}
 
			//设置位置
			setDivPox($('#'+backDivId),this.jq);
 
			//动画效果显示出来
			$('#'+backDivId).show();
			this.options.showAnimate ? this.jq.fadeIn("slow") : this.jq.show();
 
			//将当前jQuery对象保存,在绑定事件中会用到
			var that = this;
 
			//绑定关闭事件的DOM
			var ary = this.options.closeId.split(',');
			for(var i=0; i<ary.length; ++i){
				$('#'+ary[i]).click(function(){
					that.hide();
				});
				//鼠标显示手型
				$('#'+ary[i]).css({cursor:'pointer'});
			}
 
			//绑定弹出层的移动效果
			if(this.options.titleId != ''){
				divDragGable(this.options.titleId , this.jq.attr('id'));
			}
 
			this.jq.data('resize',function(){
				setTimeout(function(){
					setDivPox($('#'+backDivId),that.jq);
				},10);
			});
			this.jq.data('scroll',function(){
				setTimeout(function(){
					setDivPox($('#'+backDivId),that.jq,true);
				},10);
			});
			$(window).resize(this.jq.data('resize')).scroll(this.jq.data('scroll'));
			return this;
		},
		hide:function(){
			//隐藏层
			var that = this;
			this.jq.hide();
			$('#'+this.options.backDivId).hide();
			//取消绑定的事件
			$(window).unbind('resize',this.jq.data('resize')).unbind('scroll',this.jq.data('scroll'));
			return this;
		}
	};
	$.fn.extend({pop:function(config){
		return new pop(config,this);
	}});
})(jQuery);

使用方法:

var api = $('#div1').pop({closeId:'close1,close2',titleId:'title1'}).show();
//api有show和hide两个方法,可以手动调用api.hide()来关闭层
分类: javascript 标签:

kohana3.0之分页

2010年9月2日 effect 没有评论

说实话,如果用route模式的话,真的很难用,建议用query_string

都一点了,困死了,直接上代码吧,在控制器里面:

$view = new View('test');
$this->pagination = new Pagination(array(
								'current_page'   => array('source' => 'query_string', 'key' => 'page'), // source: "query_string" or "route"
							    'total_items'    =>80, // use db count query here of course
							    'items_per_page' =>3, // it may be handy to set defaults for stuff like this in config/pagination.php
							    'view'          => 'pagination/floating',
							));
$view->set('page',$this->pagination);
$this->request->response = $view->render();

上面参数不解释。

在view中:

<?php echo $page->render();?>

不解释,收工睡觉!

分类: php 标签:

Kohana3.0之路由(router)

2010年9月2日 effect 没有评论

废话不多说,先上代码:

Route::set('static', '&lt;page&gt;',array('page'=&gt;'about|faq|location'))
	-&gt;defaults(array(
		'controller' =&gt; 'static',
		'action'     =&gt; 'index',
	));

意义:/about或者/faq或者/location这样的链接就直接路由到控制器:static,action:index。

Route::set('info', 'info/&lt;id&gt;',array('id'=&gt;'\d+'))
	-&gt;defaults(array(
		'controller' =&gt; 'product',
		'action'     =&gt; 'info',
	));

意义:info/123路由到:/product/info/123

Route::set('xiaozu', 'xiaozu/&lt;id&gt;(/&lt;controller&gt;(/&lt;action&gt;))',array('id'=&gt;'\d+'))
	-&gt;defaults(array(
		'directory'  =&gt; 'group',
		'controller' =&gt; 'main',
		'action'     =&gt; 'index',
	));

意义:/xiaozu/123 这样的链接路由到:/group/main/index。

参考文档:http://v3.kohanacn.com/guide/tutorials.urls

分类: php 标签: