文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>jquery下组织javascript代码(js函数化)

jquery下组织javascript代码(js函数化)

时间:2010-08-31  来源:缘分星空

这里整理的是jquery下js的一些代码组织方法,大家可以借鉴下整理出基于jquery的自己喜欢的模式。

从神奇的"$"函数开始
"$"函数将在文档加载完成之后为一个指定的button 绑定事件,这些代码在单个网页中工作正常。但是如果我们还有其它的网页,我们将不得不重复这个过程。


<a href="javascript:;" id="sayHello">Say Hello</a>
<script type="text/javascript">
//when dom ready, do something.
//bind click event to a button.
$(function(){
$('#sayHello').click(function(){
alert('Hello world!');
});
});
</script>


如果我们需要另一个行为的button怎么办?比如象这样:


<a href="javascript:;" id="sayUnlike">Unlike it</a>
<script type="text/javascript">
//when dom ready, do something.
//bind click event to a button.
$(function(){
$('#sayUnlike').click(function(){
alert('I unlike it.');
});
});
</script>


接下来,更多的问题出现了,我们需要很多这样的button, 这好象也不难。


<a href="javascript:;" class="sayUnlike">Unlike it</a>
<script type="text/javascript">
//Change to a class selector to match all the button elements.
$(function(){
$('.sayUnlike').click(function(){
alert('I unlike it.');
});
});
</script>


一个页面里面同种出现了两种button ......


<a href="javascript:;" class='sayHello'>Say Hello</a>
<a href="javascript:;" class="sayUnlike">Unlike it</a>
<script type="text/javascript">
$(function(){
$('.sayHello').click(function(){
alert('Hello world!');
});
$('.sayUnlike').click(function(){
alert('I unlike it.');
});
});
</script>


但是呢,不是所有的页面都会用到这两种的button,为了不在页面上使用额外的选择器,我们要作一些必要的调整,因为基于class的选择器的性能相对于id选择器开销很大,需要遍历所有dom元素,并使用正则表达式匹配class属性来选定满足条件的元素。


<? if($page == 'A'){?>
<script type="text/javascript">
$(function(){
$('.sayHello').click(function(){
alert('Hello world!');
});
});
</script>
<? } ?>
<? if($page == 'B'){?>
<script type="text/javascript">
$(function(){
$('.sayUnlike').click(function(){
alert('I unlike it.');
});
});
</script>
<? } ?>


我们的项目功能越来越复杂,经过一段时间以后,变成了这个样子, quick but dirty......


<? if($page == 'A' or $page == "C" and $page is not "D"){ ?>
<script type="text/javascript">
......
</script>
<? } ?>
<? if($page == "B" or $page == "E" and $page is not "X"){ ?>
<script type="text/javascript">
.....
</script>
<? } ?>
<? if($page == "B" or $page == "E" or $page == "C"){ ?>
<script type="text/javascript">
.....
</script>
<? } ?>


这真是太糟糕了,我们需要在一个页面上加载许多个代码片断才能绑定所有的事件,如果我们再将不同的代码分装入多个js文件中这将增加多个页面资源的http请求,不论是管理还是用户体验都将面临挑战,我们需要找到一个更佳的解决方案。
既然 class selector 的开销这么大,我们能不能在一次扫描中绑定所有的事件?我们可以尝试一下:


<script type="text/javascript">
//Register global name space.
var Yottaa = Yottaa || {};
Yottaa.EventMonitor = function(){
this.listeners = {};
}
//Bind all event.
Yottaa.EventMonitor.prototype.subscribe=function(msg, callback){
var lst = this.listeners[msg];
if (lst) {
lst.push(callback);
} else {
this.listeners[msg] = [callback];
}
}
// Create the event monitor instance.
var event_monitor = new Yottaa.EventMonitor();
function load_event_monitor(root){
var re = /a_(\w+)/; //using a regular expression to filter all event object.
var fns = {};
$(".j", root).each(function(i) {
var m = re.exec(this.className);
if (m) {
var f = fns[m[1]];
if (!f) { //如果事件处理函数不存在则创建函数对象.
f = eval("Yottaa.init_"+m[1]);
fns[m[1]] = f;//调用绑定函数.
}
f && f(this);
}
});
}
$(function(){
// when dom ready, bind all event.
load_event_monitor(document);
});
//Here is 2 sample components.
Yottaa.init_sayhello = function(obj){
$(obj).click(function(){
alert('Hello world!');
});
}
Yottaa.init_unlike = function(obj){
$(obj).click(function(){
alert('I unlike it.');
});
}
</script>


我们的DOM元素这样写:
<a href="javascript:;" class="j a_sayhello">Say Hello</a>
<a href="javascript:;" class="j a_unlike">Say Unlike</a>

这样看起似乎好多了,我们只需要在页面加载的时候执行一次class selector(在上面的代码中就是所有'.j'的元素)就可以找到所有需要绑定事件的元素,具体绑定哪一个组件由 class 名称里面的 a_xxx 来决定,对应着 Yottaa.init_xxx,并将当前元素的引用作为参数传入事件逻辑中。
在这个处理模式下,我们不需要再次手动编写事件处理的逻辑并将它放到 $(function(){ .... }); 这样的初始化函数中,所有我们要做的事情仅仅是给组件的“容器”加上两个 class: "j a_XXX"程序即可帮我完成事件绑定工作,是不是很 cool ?象常用的展开/折叠效果,全选/反选效果, tab切换以致于一些其它的简单功能都可以使用这种方式。难道这就是传说中的银弹?不,事情没那么简单,我们应该看到这种处理方式一些弱点:
不能给组件传递初始化参数。
不能体现出组件的包含关系,也不能利用继承和多态等面向对象的特性使程序更容易编写和理解。
对于部分具体关联关系的组件在处理上略显麻烦,没有合理的事件通知机制。
我们来看看第一条:关于参数的传递,在许多场景下对于多个条目的列表,对应每一个条目我们一般会给元素分配一个唯一一的id,这些元素的行为类似,不同之处只是服务器端的编号不同,比如一个留言列表或者是一个产口列表。我们可以利用id属性为我们作一些事情,看下面的代码,我们用id属性把条目对应的服务器端编号告诉javascript,并在接下来的事件逻辑处理中作为服务器回调函数参数的一部分发回服务器端。


<script type="text/javascript">
Yottaa.init_sampleajax = function(obj){
$(obj).click(function(){
var component_id = $(this).attr('id').split('-')[1];
$.get('/server/controller/method', {id: component_id}, function(data){
if(data){
alert('Message from server: ' + data );
}
});
});
}
</script>
<a href="javascript:;" class='j a_sampleajax' id='item-a'>Show server message. </a>
<a href="javascript:;" class='j a_sampleajax' id="item-b">Another button with same action but different server side identifier.</a>


在更复杂的一些场景中我们可以利用页面上的inline code给组件传递一些必要的信息。


Yottaa.globalConst = {
User:{
familyName: "Jhone",
givenName: 'bruce'
},
Url:{
siteName: 'yottaa.com',
score: 98
}
}
Yottaa.componentMetaData = {
compoment_id_1:{ ...... },
component_id_2:{ ...... }
};


上面讨论了一种可能的代码组织办法,但是并非适用于所有的项目,我们要做的是:针对于目前的现状,找到一个在代价比较小的重构方案。我们考虑如下几点:
分离元素的事件绑定代码和组件代码:组件代码包括jquery库,相关扩展插件,以及我们自己编写的小部件,如chartbox等内容。
事件绑定及处理逻辑:按不同的组件划分为多个模块,每个模块放入一个function中。
页面需要指定哪些模块要在本页面上初始化,提供一个列表交由全局的事件绑定器统一处理。
下面来演示一下部分代码:


<script type="text/javascript">
function init_loginPanel = function(){
var container = $('login_panel');
$('#login_button').click(function(){
......
});
}
function init_chart = function(){
......
}
//global static init method
Yottaa.initComponents = function(components){
for(var i = 0;i<components.length;i++){
if(typeof window[components[i]] == 'Function'){
window[components[i]]();
}
}
}
// above is in the 'all-in-one' assets file which is compressed to one file in production.
var components = ['init_loginPanel', 'init_chart'];
var metaData = {
loginPanel: {},
chart: {},
......
};
$(function(){
Yottaa.initComponents(components);
});
//here is inline script on the page.
</script>

 


Louis Vuitton Collection Beach Cabas Ipanema GM Navy M95987 HandbagsGucci G177139-08 black canvass Handbags Gucci-177139-11Imitation Chanel Lambskin Shoulder Bag 36030 Dark Blue 36030DarkBlue HandbagsLouis Vuitton Cruise 2009 Rider Black M92810 HandbagsLouis Vuitton Monogram Canvas Swing Pack M50205 HandbagsLouis Vuitton Damier Geant Canvas Couguar Black M93085 HandbagsLouis Vuitton Show Spring Summer 2009 Flight Bag Savane Blue M97008 M97008-Blue HandbagsLouis Vuitton Monogram Vernis Brentwood Black M91989 HandbagsLV M30052 Louis Vuitton Handbags Lozan - Porte DocumentsLouis Vuitton Mahina Boétie MM White LV 45714WT Handbagschanel Handbags Chanel 2008 new Clutch 225 - grey chanel-225--greyLouis Vuitton Damier canvas Designer Hottest Clutch Bag N52132 HandbagsGucci GG Fabric Handbagss G203517-White Gucci-203517LV M95698 Louis Vuitton LV Handbags Galliera PMGucci wallet-Silver Gucci-3347 HandbagsGucci 07 new bag G170010-03 HandbagsGucci GG Fabric Handbagss Shoulder 137621 gucci-137621CAChanel Wallet Cambon Wallet Fold - Black Snake Chanel-CC1370 HandbagsLV M40156 Louis Vuitton LV Handbags Neverfull Saint Tropez - MM M40156NWLouis Vuitton Show Summer 2009 Sequins Monogram Speedy 30 Match Handbags Separable 41528 chanel Handbags Love Bow Satin Bag Black 2008 New chanel-080428Louis Vuitton Monogram Mini Lin Noelie Green M92685 HandbagsLV M40125 Louis Vuitton LV Handbags RitaLV M803R Louis Vuitton LV Handbags Montaigne Bag - RedChanel Wallet Cambon Wallet Bifold - Beige Snake Chanel-CC1310 HandbagsLouis Vuitton Suhali Leather Le Panouis Blue M91850 M91850-blue HandbagsLouis Vuitton Epi Leather Madeleine GM Bag Purple M59342 HandbagsLouis Vuitton Damier Canvas Pochette Bosphore N51111 HandbagsGucci 218513 BCC8G 4308 large backpack GUCCI-218513-BCC8G-4308 HandbagsGucci 146002-bronze HandbagsGucci Peggy Bag with Bamboo Handle in white leather gucci-g169976B HandbagsLouis Vuitton A Grade Monogram Canvas Bulles GM - Black Handbags09 New Chanel Funny Tweed Patent Leather Shoulder Bag 36016 - Black 36016black HandbagsLV NM95333 Louis Vuitton LV Handbags Cruise Mini Pleaty CustomizChanel Rugosity Leather Stitching Shoulder Bag 35987-Black 35987black HandbagsLouis Vuitton Cruise Collection 2010 Bulles PM M40238 HandbagsGucci 177139 Indy top handle-Black Patent gucci-177139BP HandbagsLV M93082B Louis Vuitton Handbags Yack - BlackLouis Vuitton Monogram Miroir Show Spring 2010 Tote Bag Silver M40268 M40268-Silver HandbagsGucci Sabrina-Dark brown Gucci-189847-01 HandbagsGucci leather wallet Black Gucci-52185 HandbagsGucci 190336-white Gucci-190336 HandbagsLouis Vuitton Show Fall Winter 2009 LV Stamp Bag Black M95067 HandbagsLouis Vuitton Monogram Canvas Cupertino LV M56398 HandbagsLouis Vuitton Multicolor Sologne Black M92639 HandbagsGucci GG Fabric Handbagss speedy G1989895 Gucci-1989895Louis Vuitton Monogram Denim Porte Epaule Raye MM M95334 HandbagsLouis Vuitton Stephen Sprouse Collection Speedy 30 Green M93706 HandbagsLouis Vuitton Epi Leather Alma Bag Black GM M52892 HandbagsGucci 162886 tote G162886 Handbags
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载