不只是口号 jQuery的设计艺术

开发 开发工具 前端
jQuery是一个了不起的轻量级的JavaScript框架,事实上在jQuery发布之前,就已经有无数功能强大得多的JavaScript框架在流行。jQuery的口号是“write less, do more”,但这并不是jQuery的全部设计哲学。

jQuery是一个了不起的轻量级的JavaScript框架,事实上在jQuery发布之前,就已经有无数功能强大得多的JavaScript框架在流行。从功能列表上来说,jQuery在JavaScript框架中只能算是很不起眼的小弟。

但这个小弟在短短的时间内,就成为了最流行的JavaScript框架之一。当然jQuery成功的原因有很多,跨浏览器兼容、轻巧、不算很差的性能,以及jQuery的“口号”:write less, do more。

51CTO推荐阅读:jQuery四大天王:核心函数详解

有人会说,write less, do more就是jQuery的全部设计哲学,但我不这么认为。在我看来,write less, do more是任何一个框架都必须去做的事情。很难想象会有人选择一个write more, do less的框架吧。所以,对于一个框架而言,这是最基本的事情,要成为一个伟大的框架,显然这很不够。

在这里我想谈谈jQuery的一个设计的艺术,select then do。CSS选择器是jQuery最重要的函数$(或者说jQuery)最常见的参数。尽管这个函数可以接受的参数还有HTML元素或是HTML代码。但最常用的显然是传入一个CSS选择器,jQuery会帮你选择文档中符合要求的元素。然后,你就可以对这个元素集进行操作:

  1. $("li").css("font-style", "italic"); 
  2.  

这段脚本可以将所有li元素设置为斜体。这是jQuery最常见的用法,利用选择器选择自己所需的元素,然后对其执行某些操作。为了方便进行多个操作,jQuery绝大多数的函数都返回执行函数的原对象,在这里也就是$("li")。所以我们可以简单的继续写:

  1. $("li").css("font-style", "italic").hide();
  2.  

这里面透露出来了一个jQuery设计的哲学,即select then do,select就是选择所需的元素,do就是执行某些操作。绝大多数时候,我们都是select.do.do.select.do.do.do,比如说:

  1. $("li").css("font-style", "italic").show().find("a").text("删除").attr("href", "javascript:void(0);").click(function ()   
  2. { $(this).parent().hide(); }); 

很明显的,$("li")在select然后接着两个do,再然后.find("a"),这里在进一步进行select,然后继续执行一系列的do。注意在click绑定的事件处理函数里:$(this).parent().hide()也是一个非常经典的select.select.do。这非常接近我们的自然语言,比如说上面那一段脚本,其实是这个意思:

“所有的li元素听好了,把你们的字体搞成斜的,再给我显示出来,然后看看你们后代里面有没有a元素,让它把显示文字变成“删除”,再把href属性设置为"javascript:void(0);",最后他们被点击的时候,把他们的父亲隐藏掉。”是的,我完全是照着脚本直接就可以说出来,不需要任何思考和变换。接下来,我们来看看一个糟糕的例子:

  1. var items = document.getElementsByTagName("li" );  
  2.      for (var i = 0; i < items.length; i++)  
  3.           {  var li = items.item(i);    
  4.              li.style.fontStyle = "italic";    
  5.              li.style.display = "";     
  6.              var childs = li.childNodes;    
  7.              for (var j = 0; j < childs.length; j++)    
  8.           {    var a = childs[j];       
  9.               if (a.tagName != "A")        
  10.               continue;       
  11.                a.innerText = "删除";      
  12.                a.href = "javascript:void(0);";       
  13.                a.onclick = function ()      
  14.            {   this.parentNode.style.display = "none";      
  15.              };    
  16.             }  

很难想象这段脚本只是完成了相同的事情。照着这段脚本你能简单的描述它是干什么的么?

当然,select then do并不仅仅只是帮我们节省了代码。更大的优势在于,它使得我们可以将我们的逻辑和HTML文档彻底的分开。简单的说,在Web开发中,我们经常会遇到这样的需求,按下一个按钮,弹出一个选择框让用户决定是否提交表单,传统的方式是这样:

  1. <input type="button" id="submitButton" value="提交" onclick="if   
  2. ( confirm( '您确定要提交这些信息么' ) )   
  3. document.getElementById('registerForm').submit();" /> 

显然这很糟糕,他将行为和HTML元素死死的捆在了一起,如果我们希望这个按钮同时干两件事情,那真是一件灾难。jQuery的选择器可以很好的帮助我们分离我们的行为,select then do:

  1. $("#submitButton").click(function ()  
  2. { if (confirm('您确定要提交这些信息么'))   
  3. $('#registerForm').submit(); }); 

如果是要处理复杂的事情,这会更惬意。其实到现在并没有什么神奇的事情发生,没有jQuery我们也可以通过DOM提供的方法简单的通过脚本进行事件的注册,而不是直接写在HTML里面。只是我们要处理一下不同的浏览器之间的差异而已。

#p#

我们来考虑另一个场景。譬如说在页面上有一个登陆的小区域,里面有三个输入框,用户名、密码和验证码,然后有一个登陆按钮,像这样:

  1. <form action="/login" id="loginForm">    
  2.      <table border="0" cellpadding="5" cellspacing="0">      
  3.            <tr>        
  4.                <td>用户名:</td>        
  5.                <td><input type="text" name="username" style="width: 100px;" /></td>      
  6.                </tr>      
  7.                <tr>        
  8.                <td>密码:</td>        
  9.                <td><input type="password" name="password" style="width: 100px;" /></td>      
  10.                </tr>      
  11.                <tr>        
  12.                <td>验证码:</td>        
  13.                <td><input type="text" name="validateCode" style="width: 50px;" /><img src="validateCode.img" /></td>      
  14.                </tr>      
  15.                <tr>        
  16.                <td colspan="2"><input type="submit" value="登陆" /></td>      
  17.                </tr>    
  18.                </table> 
  19. </form> 

有一个很不幸的事情,这种登陆框到处都有。而你,还不得不给这个登陆框加上一些必须处理的事情,例如在提交的时候检查一下输入框是不是空的。显然我们并不希望在所有的这些页面都去写一小段脚本,我们希望有一段脚本,能够自动的在有这种登陆框的页面处理这些事情。最好是,在没有登陆框的页面,它也不会有任何副作用,那么这样的脚本真的存在么?

  1. $("form#loginForm input[type=submit]").click(function ()  
  2.            {    
  3.                var form = $("form#loginForm");    
  4.                var flag = true;    
  5.                form.find("input[type=text] , input[type=password]").each(function ()    
  6.           {    if (this.value == "" && flag)      
  7.                {      window.alert("请将登陆信息填写完整");        
  8.                      flag = false;      
  9.           }    
  10.  });     
  11.              return flag;  
  12. }  
  13. ); 

注意这段脚本中选择器的运用,通过id限定和find方法的范围限定,我们牢牢地将这段脚本所影响的范围控制在了一个id为loginForm的表单中。更绝妙的是,即使这个表单不存在于页面,这段脚本也没有任何的问题。不会在你IE的状态栏弄一个黄色的感叹号告诉你脚本出现了错误。你可以将这段脚本大胆放心的放在每一个页面的JavaScript的引用中(这对于现有的技术来说再简单不过),也不用担心明天哪个页面多了一个登陆块你会需要去写什么脚本。

这就是选择器的绝妙之处,它使得我们的页面元素可以通过约定来获得某些行为,例如在这里,只要我们将登陆用的表单的id设置为loginForm,那么这个表单就会自动获得提交的时候检查所有输入框的行为。这种约定的威力完全不仅如此,我们再来看一段神奇的脚本:

  1. $("form").submit(function ()  
  2.   {    
  3.      var flag = true;      
  4.      $(this).find("input[type=text][requiredrequired=required] , input[type=password][requiredrequired=required]").each(function ()    
  5.             {      
  6.                 if ($(this).val() == "")      
  7.                    {      window.alert("信息没有填写完整,请认真检查必填项");        
  8.                           flag = false;      return false;      
  9.                    }    
  10.              }  
  11.     );     
  12.                 return flag;  
  13.    }  
  14. ); 


这段神奇的脚本可以让你只需要在你的输入框上加一个属性required="required",然后表单提交的时候就会自动验证这些输入框里面是不是填了东西。这太神奇了,我们利用jQuery提前享受了HTML 5的新特性。

当我意识到jQuery的选择器如此强大的威力的时候,我马上想到,事实上如果将选择器运用于我们传统的页面数据绑定,也会是一件非常棒的事情。这便是Jumony引擎的由来。Jumony将jQuery的选择器和select then do艺术几乎完整的搬到了C#中。在项目开发中带来的效率提升和畅快的感觉,完全的超出了我原本的设想。

在这里,我仍不愿意过多的去谈Jumony的功能细节。由于这个引擎仍在不断的开发修改和内部测试中,现在并没有可以公开的预览,我只能说,敬请期待。我会继续分享在Jumony开发和设计中过程中的。

最新的Jumony build已经实现如下选择器支持:

  1. *、E、E E、E + E、E > E、E ~ E  
  2.  
  3. #identity、.class-name、[attr]、[attr=value]  
  4. [attr!=value]、[attr^=value]、[attr$=value]  
  5.  
  6. :nth-child、:nth-last-child、:nth-of-type、  
  7. :nth-last-of-type、:first-child、:last-child、  
  8. :first-of-type、:last-of-type 

 

【编辑推荐】

  1. jQuery核心部分原理的模拟代码
  2. jQuery应用程序性能指标和调优
  3. jQuery高级应用:优化Web应用程序的最后绝招
  4. jQuery四大天王:核心函数详解
  5. 抛砖引玉 自定义jQuery扩展接口
责任编辑:王晓东 来源: 博客园
相关推荐

2017-03-25 21:13:38

JavaScript排序

2013-04-25 13:58:15

编程

2010-04-08 08:18:55

iPad软件开发iPhone

2015-11-24 10:05:07

私有云虚拟化负载迁移

2018-03-13 15:00:22

智慧交通高铁无人驾驶

2021-11-05 11:17:45

互联网996大厂

2022-11-02 11:48:03

Vanilla OSGNOMEUbuntu

2018-06-27 17:24:24

华为

2015-03-31 09:28:28

Hadoop大数据技术大数据未来道路

2021-07-26 22:33:41

切片结构体代码

2021-01-06 10:51:39

云计算云服务IT

2018-06-28 18:10:41

华为

2016-10-13 18:06:09

云计算多云模型

2015-02-04 09:45:40

2015-12-15 17:19:55

戴尔云计算

2011-09-15 13:25:02

2011-11-17 13:25:43

垃圾邮件

2013-12-20 09:55:11

飞鱼星无线云飞鱼星路由器飞鱼星

2020-05-03 10:09:46

红帽开源开放混合云

2010-12-28 13:48:14

点赞
收藏

51CTO技术栈公众号