富贵资源网 Design By www.hznty.com
从神奇的"$"函数开始
"$"函数将在文档加载完成之后为一个指定的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>
富贵资源网 Design By www.hznty.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
富贵资源网 Design By www.hznty.com

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。