这个标题后跟着的(二)会比较让人奇怪,因为在我的博客上找不到“jQuery的设计艺术和选择器(一)”这样的文章。
这篇文章的同系列上一篇文章是从扩展方法到流畅的程序体验(一),这是Jumony引擎的介绍系列文章第二篇。
jQuery是一个了不起的轻量级的JavaScript框架,事实上在jQuery发布之前,就已经有无数功能强大得多的JavaScript框架在流行。从功能列表上来说,jQuery在JavaScript框架中只能算是很不起眼的小弟。但这个小弟在短短的时间内,就成为了最流行的JavaScript框架之一。当然jQuery成功的原因有很多,跨浏览器兼容、轻巧、不算很差的性能,以及jQuery的“口号”:write less, do more。
有人会说,write less, do more就是jQuery的全部设计哲学,但我不这么认为。
在我看来,write less, do more是任何一个框架都必须去做的事情。很难想象会有人选择一个write more, do less的框架吧。所以,对于一个框架而言,这是最基本的事情,要成为一个伟大的框架,显然这很不够。
在这里我想谈谈jQuery的一个设计的艺术,select then do。
CSS选择器是jQuery最重要的函数$(或者说jQuery)最常见的参数。尽管这个函数可以接受的参数还有HTML元素或是HTML代码。但最常用的显然是传入一个CSS选择器,jQuery会帮你选择文档中符合要求的元素。然后,你就可以对这个元素集进行操作:
$("li").css("font-style", "italic");
这段脚本可以将所有li元素设置为斜体。
这是jQuery最常见的用法,利用选择器选择自己所需的元素,然后对其执行某些操作。为了方便进行多个操作,jQuery绝大多数的函数都返回执行函数的原对象,在这里也就是$(“li”)。所以我们可以简单的继续写:
$("li").css("font-style", "italic").hide();
这里面透露出来了一个jQuery设计的哲学,即select then do,select就是选择所需的元素,do就是执行某些操作。绝大多数时候,我们都是select.do.do.select.do.do.do,比如说:
$("li").css("font-style", "italic").
show().find("a")
.text("删除")
.attr("href", "javascript:void(0);")
.click(function () { $(this).parent().hide(); } );
很明显的,$(“li”)在select然后接着两个do,再然后.find(“a”),这里在进一步进行select,然后继续执行一系列的do。
注意在click绑定的事件处理函数里:$(this).parent().hide()也是一个非常经典的select.select.do。
这非常接近我们的自然语言,比如说上面那一段脚本,其实是这个意思:
“所有的li元素听好了,把你们的字体搞成斜的,再给我显示出来,然后看看你们后代里面有没有a元素,让它把显示文字变成“删除”,再把href属性设置为”javascript:void(0);”,最后他们被点击的时候,把他们的父亲隐藏掉。”
是的,我完全是照着脚本直接就可以说出来,不需要任何思考和变换。接下来,我们来看看一个糟糕的例子:
var items = document.getElementsByTagName( " li " );
for ( var i = 0 ; i < items.length; i ++ )
{
var li = items.item(i);
li.style.fontStyle = " italic " ;
li.style.display = "" ;
var childs = li.childNodes;
for ( var j = 0 ; j < childs.length; j ++ )
{
var a = childs[j];
if (a.tagName != " A " )
continue ;
a.innerText = " 删除 " ;
a.href = " javascript:void(0); " ;
a.onclick = function ()
{
this .parentNode.style.display = " none " ;
};
}
}
很难想象这段脚本只是完成了相同的事情。
照着这段脚本你能简单的描述它是干什么的么?
当然,select then do并不仅仅只是帮我们节省了代码。更大的优势在于,它使得我们可以将我们的逻辑和HTML文档彻底的分开。简单的说,在Web开发中,我们经常会遇到这样的需求,按下一个按钮,弹出一个选择框让用户决定是否提交表单,传统的方式是这样:
< input type = " button " id = " submitButton " value = " 提交 "
onclick = " if ( confirm( '您确定要提交这些信息么' ) )
document.getElementById('registerForm').submit(); " / >
显然这很糟糕,他将行为和HTML元素死死的捆在了一起,如果我们希望这个按钮同时干两件事情,那真是一件灾难。
jQuery的选择器可以很好的帮助我们分离我们的行为,select then do:
$("#submitButton").click(function () {
if (confirm('您确定要提交这些信息么'))
$('#registerForm').submit();
});
如果是要处理复杂的事情,这会更惬意。
OK,其实到现在并没有什么神奇的事情发生,没有jQuery我们也可以通过DOM提供的方法简单的通过脚本进行事件的注册,而不是直接写在HTML里面。只是我们要处理一下不同的浏览器之间的差异而已。
我们来考虑另一个场景。譬如说在页面上有一个登陆的小区域,里面有三个输入框,用户名、密码和验证码,然后有一个登陆按钮,像这样:
< form action ="/login" id ="loginForm" >
< table border ="0" cellpadding ="5" cellspacing ="0" >
< tr >
< td > 用户名: </ td >
< td >< input type ="text" name ="username" style ="width: 100px;" /></ td >
</ tr >
< tr >
< td > 密码: </ td >
< td >< input type ="password" name ="password" style ="width: 100px;" /></ td >
</ tr >
< tr >
< td > 验证码: </ td >
< td >< input type ="text" name ="validateCode" style ="width: 50px;" />< img src ="validateCode.img" /></ td >
</ tr >
< tr >
< td colspan ="2" >< input type ="submit" value ="登陆" /></ td >
</ tr >
</ table >
</ form >
有一个很不幸的事情,这种登陆框到处都有。而你,还不得不给这个登陆框加上一些必须处理的事情,例如在提交的时候检查一下输入框是不是空的。
显然我们并不希望在所有的这些页面都去写一小段脚本,我们希望有一段脚本,能够自动的在有这种登陆框的页面处理这些事情。最好是,在没有登陆框的页面,它也不会有任何副作用,那么这样的脚本真的存在么?
$( " form#loginForm input[type=submit] " ).click( function ()
{
var form = $( " form#loginForm " );
var flag = true ;
form.find( " input[type=text] , input[type=password] " ).each( function ()
{
if ( this .value == "" && flag)
{
window.alert( " 请将登陆信息填写完整 " );
flag = false ;
}
});
return flag;
});
注意这段脚本中选择器的运用,通过id限定和find方法的范围限定,我们牢牢地将这段脚本所影响的范围控制在了一个id为loginForm的表单中。更绝妙的是,即使这个表单不存在于页面,这段脚本也没有任何的问题。不会在你IE的状态栏弄一个黄色的感叹号告诉你脚本出现了错误。你可以将这段脚本大胆放心的放在每一个页面的JavaScript的引用中(这对于现有的技术来说再简单不过),也不用担心明天哪个页面多了一个登陆块你会需要去写什么脚本。
这就是选择器的绝妙之处,它使得我们的页面元素可以通过约定来获得某些行为,例如在这里,只要我们将登陆用的表单的id设置为loginForm,那么这个表单就会自动获得提交的时候检查所有输入框的行为。
这种约定的威力完全不仅如此,我们再来看一段神奇的脚本:
$( " form " ).submit( function ()
{
var flag = true ;
$( this ).find( " input[type=text][required=required] , input[type=password][required=required] " ).each( function ()
{
if ($( this ).val() == "" )
{
window.alert( " 信息没有填写完整,请认真检查必填项 " );
flag = false ;
return false ;
}
});
return flag;
});
这段神奇的脚本可以让你只需要在你的输入框上加一个属性required=”required”,然后表单提交的时候就会自动验证这些输入框里面是不是填了东西。这太神奇了,我们利用jQuery提前享受了HTML5的新特性。
OK,当我意识到jQuery的选择器如此强大的威力的时候,我马上想到,事实上如果将选择器运用于我们传统的页面数据绑定,也会是一件非常棒的事情。。。
这便是Jumony引擎的由来。Jumony将jQuery的选择器和select then do艺术几乎完整的搬到了C#中。在项目开发中带来的效率提升和畅快的感觉,完全的超出了我原本的设想。
在这里,我仍不愿意过多的去谈Jumony的功能细节。由于这个引擎仍在不断的开发修改和内部测试中,现在并没有可以公开的预览,我只能说,敬请期待。我会继续分享在Jumony开发和设计中过程中的,嗯,心得。
最新的Jumony build已经实现如下选择器支持:
* 、E、E E、E + E、E > E、E ~ E
#identity、.class - name、[attr]、[attr = value]、[attr != value]、[attr ^= value]、[attr$ = value]
:nth - child、:nth - last - child、:nth - of - type、:nth - last - of - type、
:first - child、:last - child、:first - of - type、:last - of - type
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容