IE:filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1); 谷歌:-webkit-filter: grayscale(100%);
View Details如果不是不可能,你也很难拒绝承认性能目前已是任何正规网站项目的最关键方面之一,无论它是一个小型的网站组合,一个移动优先的web应用,一直到一个大规模的商业项目。研究,论文和个人体验都告诉我们快速是最好的。 性能不仅仅是非常重要,它也相当的有趣,而且这也是我越来越投入的事,不仅在工作方面(我一直在烦我们的首席性能工程师),也在项目与CSS魔法网站方面(我一直在烦Andy Davies)。 在这篇长文章中,我将分享收获,关于快速,简单且非常有趣的性能知识的点点滴滴,以便使你的行为可以像一个初级的网页设计师和前端开发者;希望对任何想开始学习性能的人,这篇文章可以成为一个正规的介绍,并使它们的前端变得超快。这些技巧是你能非常容易实现的。它只需要一点小技巧,以及一些浏览器怎样工作的基础知识,你就能开始玩转系统了! 这篇长帖子不会讲到模糊图像的加载和数据处理,取而代之的是有关理论与第一手的性能方面的技术资料,这些技术是我通过阅读,观察,搜集和整理获得的(我花费了许多时间沉浸于CSS魔法的瀑布图)。我也会链接到其它相似话题的文章,以便帮助强化一些关键要点。享受吧! 注意 本文需要预先知晓一些基础的性能知识,如果有任何你不熟悉的就Google搜索一下好了! 基础 顶部的Styles,底部的scripts 更少的请求 尽可能并行 HTTP 请求与 DNS查询 DNS 预取 资源预取 CSS与性能 压缩与简化 优化图像 精灵 视网膜图像 渐进的 JPGs 完全不用图片 进一步阅读 基础知识 关于性能,有一些知识在所有的设计师和前端开发者中广为传播。例如,尽可能少的请求,优化图片,把样式表(stylesheets)放在<head>, 把JS放在</body>之前, 最小化(minifying) JS 和 CSS 等等。这些基础知识已经被用来加快用户响应了,但还有更多更多需要学习。 虽然在我们每天的工作生活中,浏览器给我们制造麻烦,使我们头疼,但请记住,他们也是很聪明的; 它们为我们做了很多性能优化工作, 所以大量的性能调优知识不但要知道浏览器在哪里给我们做了优化,还要知道怎么更好的挖掘它们。大量性能调优诀窍只是理解,利用和操纵浏览器已经替我们做好的优化工作。 顶部的Styles, 底部的scripts 这真的是一条基本规则,每个人都能非常容易的在大多数时间遵守,但为什么它重要?简短的说: CSS 块渲染, 因此你需要立即处理它(即在文档的顶部,在你的<head>之中)。 JS 块下载, 因此你需要最后处理它们,以确保它们没有耽误页面中任何其它东西。 CSS块渲染是因为浏览器总是试图渐进式的渲染页面;它们想在元素到达的时候顺序的渲染它。如果style在距离很远的页面下部,浏览器在获得它之前没有办法渲染那个CSS。因为这个原因,如果浏览器在渲染文档过程中,改变了之前渲染的东西,它们可以避免style的重绘。浏览器在它获得所有需要的style信息之前不会渲染页面,如果你将style放在文档底部,你就是在使浏览器等待,阻塞了渲染。 所以,只要你将CSS放在页面的顶部,那么浏览器就可以立刻开始渲染。 JavaScript块下载是由于好几个原因(这又是浏览器聪明之处),但首先我们需要知道浏览器里的资源下载是如何实际发生的;简单的说,浏览器会从一个单一的域名并行的尽可能多的下载资源。它从越多的域名下载,就能在一瞬间并行的获得更多的资源。 JavaScript中断了这个过程,阻塞了从任何一个域名的并行的下载,因为: 被调用的脚本可能改变页面,即浏览器在继续别的事情以前,将不得不处理它。因此为了处理那个不测事件,浏览器停止了任何其它东西的下载,以便集中精力关注于它。 脚本正常工作经常需要依照一定的顺序加载,例如,要在加载一个插件之前加载jQuery。浏览器阻止了JavaScript的并行下载,因此它不会同时下载jQuery和你的插件;很显然如果你同时并行下载二者,你的插件会在jQuery之前到达。 所以,由于浏览器在获取JavaScript的时候停止了所有其他下载,将你的JavaScript脚本放在文档中尽可能晚加载的地方是一个好主意。我相信你们都看到过页面中的空白片段,在那里第三方的JS脚本被花时间加载,并且它还阻止了页面其他资源的获取和渲染;这就是JavaScript的阻塞在作用了。 但是显然,现代浏览器还是变得聪明了。我将给你一个Andy Davies寄给我的电子邮件的摘录,因为他解释的比我清楚: 现代浏览器将并行下载JS,只有在脚本被执行的时候阻塞渲染(显然脚本必须也被下载了)。 脚本下载常常被浏览器的预加载器所完成。 当浏览器页面渲染被阻塞,即等待CSS,或JS被执行,预分析器将扫描页面剩余部分,寻找它能下载的资源。 有些浏览器如 Chrome, 将分先后下载资源,例如,如果脚本与图片同时在等待下载,它将先下载脚本。 漂亮的内容! 所以,要使页面被尽可能快的渲染,将styles放在顶部。为了阻止JS的阻塞影响到渲染,将scripts放在底部。 更少的请求 另一个明显而基本的性能优化方法是少下载。页面需要的每一个资源就是一次额外的HTTP请求;浏览器不得不停下来去获取每一个用于渲染页面所需的资源。每一次HTTP请求都可能引发DNS查询,重定向,404,等等。每一次HTTP请求,无论为了样式表,图片,web字体,JS文件还是其它你能想到的,都可能是一次非常昂贵的操作。尽量减少这些请求是你可以做的最快的优化方法中的一种. 再谈到浏览器和并行;大多数浏览器一次只从每个引用的域下载一些资源,而JS会阻塞这些下载。所以,你做的每一个HTTP请求都应该仔细考虑,而不是随便随便做的。 尽可能并行 为了让浏览器能并行的下载更多资源,你可以由不同的域名提供服务。如果说,浏览器只能一次从一个域名获取两个资源,那么由两个域名提供服务意味着它可以一次性获取四个资源;三个域名意味着六个并行下载。 许多网站有静态/资源 域名;你可以发现, Twitter, 用 si0.twimg.com 来做静态资源:
1 |
<link rel="stylesheet" href="https://si0.twimg.com/a/1358386289/t1/css/t1_core.bundle.css" type="text/css" media="screen"> |
Facebook 用fbstatic-a.akamaihd.net:
1 |
<link rel="stylesheet" href="https://fbstatic-a.akamaihd.net/rsrc.php/v2/yi/r/76f893pcD3j.css"> |
通过这些静态的资源域名, Twitter与Facebook能提供更多的并行资源服务;来自twitter.com和si0.twimg.com的资源可以协作方式下载。这真的是使你的页面上获得更多并发下载的简单方法,如果再加上实际的CDN技术就会更好,CDN技术通过从一个更加合适的物理位置提供资源服务的方法来减少延迟。 这全部都很好,但后面我们将讨论在特定环境下,怎样从子域名提供服务却会实际上对性能有害。 因此,现在有了我们关于性能的基础知识: 将样式表放在文档的顶部 将JavaScript放在底部(可能的地方) 尽可能减少HTTP请求 从多个域名提供资源服务能增加浏览器并行下载的资源数量。 HTTP 请求与 […]
View Details【51CTO译文】在《从零开始构建HTML 5页面》一文中,我们了解到HTML 5的一些新增特性并通过实例打造了一个完整的HTML 5页面。但HTML 5标准不只局限于传统的标记语言,它还拥有很多让人期待的API接口,利用这些接口,开发者可以创建更加丰富、更加引人注目的应用程序。之前我们介绍过支持文件拖放上传功能的HTML 5 File API,今天,我们一起来了解HTML 5的Web SQL Database API,使用本地和会话存储实现简单的对象持久化。 对于HTML 5,也许最为有用的就是它新推出的“Web Storage”(Web 存储)API。对简单的关键值对(比如应用程序设置)或简单对象(如应用程序状态)进行存储,使用本地和会话存储能够很好地完成,但是在对琐碎的关系数据进行处理之外,它就力所不及了。而这正是 HTML 5 的“Web SQL Database”API 接口的应用所在。 先提个醒,该文下面的内容需要读者对 JavaScript 和面对对象编程(尤其是匿名内的内部函数)以及SQL具有很好的理解。 打开链接 为了打开一个连接,我们执行以下代码:
1 |
<ol class="dp-sql" style="padding:5px 0px;color:#5c5c5c;list-style-position:initial;list-style-image:initial;word-wrap:break-word;word-break:normal;border:none;background-color:#f7f7f7;margin-top:0px !important;margin-right:0px !important;margin-bottom:1px !important;margin-left:55px;"><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"><span style="margin:0px;padding:0px;border:none;background-color:inherit;">db = openDatabase(</span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">"ToDo"</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">, </span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">"0.1"</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">, </span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">"A list of to do items."</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">, 200000); </span></span></p></li></ol> |
以上代码创建了一个数据库对象 db,名称是 Todo,版本编号为0.1。db 还带有描述信息和大概的大小值。用户代理(user agent)可使用这个描述与用户进行交流,说明数据库是用来做什么的。利用代码中提供的大小值,用户代理可以为内容留出足够的存储。如果需要,这个大小是可以改变的,所以没有必要预先假设允许用户使用多少空间。 为了检测之前创建的连接是否成功,你可以检查那个数据库对象是否为null:
1 |
<ol class="dp-xml" style="padding:5px 0px;color:#5c5c5c;list-style-position:initial;list-style-image:initial;word-wrap:break-word;word-break:normal;border:none;background-color:#f7f7f7;margin-top:0px !important;margin-right:0px !important;margin-bottom:1px !important;margin-left:55px;"><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;">if(!db) </span></p></li><li style="list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;margin:0px !important;padding:0px 3px 0px 10px !important;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"> alert("Failed to connect to database."); </span></p></li></ol> |
绝不可以假设该连接已经成功建立,即使过去对于某个用户它是成功的。为什么一个连接会失败,存在多个原因。也许用户代理出于安全原因拒绝你的访问,也许设备存储有限。面对活跃而快速进化的潜在用户代理,对用户的机器、软件及其能力作出假设是非常不明智的行为。比如,当用户使用手持设备时,他们可自由处置的数据可能只有几兆字节。 执行查询 执行一个查询,你可以使用database.transaction()函数。该函数具有单一参数,负责查询实际执行的函数。 该函数(通常是匿名的)具有一个类型事务的参数。
1 |
<ol class="dp-sql" style="padding:5px 0px;color:#5c5c5c;list-style-position:initial;list-style-image:initial;word-wrap:break-word;word-break:normal;border:none;background-color:#f7f7f7;margin-top:0px !important;margin-right:0px !important;margin-bottom:1px !important;margin-left:55px;"><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"><span style="margin:0px;padding:0px;border:none;background-color:inherit;">db.</span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">transaction</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">( </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">function</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">(tx) { </span></span></p></li></ol> |
该事务具有一个函数:executeSql。这个函数使用四个参数:表示查询的字符串,插入到查询中问号所在处的字符串数据(很像 Java 的预先准备好的语句),一个成功时执行的函数和一个失败时执行的函数。
1 |
<ol class="dp-sql" style="padding:5px 0px;color:#5c5c5c;list-style-position:initial;list-style-image:initial;word-wrap:break-word;word-break:normal;border:none;background-color:#f7f7f7;margin-top:0px !important;margin-right:0px !important;margin-bottom:1px !important;margin-left:55px;"><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"><span style="margin:0px;padding:0px;border:none;background-color:inherit;">tx.executeSql(</span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">"SELECT COUNT(*) FROM ToDo"</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">, [], </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">function</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">(result){}, </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">function</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">(tx, error){}); </span></span></p></li><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"><br style="clear:both;width:0px;height:0px;" /><br style="clear:both;width:0px;height:0px;" /><br style="clear:both;width:0px;height:0px;" /><br style="clear:both;width:0px;height:0px;" /></span></p></li></ol><p style="padding:0px;background-color:transparent;text-indent:28px;margin-top:10px;margin-bottom:10px;"><br /></p><p style="padding:0px;background-color:transparent;text-indent:28px;margin-top:10px;margin-bottom:10px;"><br /></p><p style="padding:0px;background-color:transparent;text-indent:28px;margin-top:10px;margin-bottom:10px;"><br /></p><p style="padding:0px;background-color:transparent;text-indent:28px;margin-top:10px;margin-bottom:10px;"><br /></p><p style="padding:0px;background-color:transparent;text-indent:28px;margin-top:10px;margin-bottom:10px;"><br /></p><p style="padding:0px;background-color:transparent;text-indent:28px;margin-top:10px;margin-bottom:10px;"><br /></p> |
查询成功时 当查询成功执行时,应用程序跳转至一个具有一对参数的查询,一个是 transaction,另一个是它搜集的 results。对于实际上将你的数据传递至用户,这是非常完美的,比如显示 ToDo 列表。有关这个话题后面再讲。 查询失败失败时 当查询没能执行时执行。由于你将 transaction 对象作为函数的第一个参数进行传递,当出现错误时你可以继续执行查询。例如,如果是因为缺少表格(table)而查询无法运行,这是创建一个表格并在此执行该语句的绝佳时机。从该函数的第二个参数,你可以获得有关该错误的信息(包括描述)。 示例 假设我们想要使用上面的例子,想要查询数据库中的某个表格,如果该表格不存在,我们就创建一个表格。 在这个示例中,我们将调用具有一个函数参数的 db.transaction()。这个参数中,我们调用 tx.executeSql()。如果这个步骤成功,我们不做任何操作(因此是一个null参数)。或者我们将该事务和执行失败的函数一起传递,并再次调用 tx.executeSql()。这一次使用创建查询。
1 |
<ol class="dp-sql" style="padding:5px 0px;color:#5c5c5c;list-style-position:initial;list-style-image:initial;word-wrap:break-word;word-break:normal;border:none;background-color:#f7f7f7;margin-top:0px !important;margin-right:0px !important;margin-bottom:1px !important;margin-left:55px;"><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"><span style="margin:0px;padding:0px;border:none;background-color:inherit;">db.</span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">transaction</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">( </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">function</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">(tx) { tx.executeSql(</span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">"SELECT COUNT(*) FROM ToDo"</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">,<br style="clear:both;width:0px;height:0px;" /> [], </span><span class="op" style="margin:0px;padding:0px;border:none;color:#808080;background-color:inherit;">null</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">, </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">function</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">(tx, error) { tx.executeSql(</span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">"CREATE TABLE ToDo (id REAL UNIQUE, label TEXT, timestamp REAL)"</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">,<br style="clear:both;width:0px;height:0px;" /> [], </span><span class="op" style="margin:0px;padding:0px;border:none;color:#808080;background-color:inherit;">null</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">, </span><span class="op" style="margin:0px;padding:0px;border:none;color:#808080;background-color:inherit;">null</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">); } ); } ); </span></span></p></li><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p> </p></li></ol> |
使用所有这些内部方法,可能有点麻烦,所以你也许想在外部创建一个调用 db.transaction() 的函数。比如,我们可以让错误函数是自包含的,并将其命名为“createToDoTable()”。 插入 为了让代码更加简洁和安全,Web SQL Database API 允许你为 transaction.executeSql() 函数提供字符串数据,用以表示调用的 SQL 语句中的变量。我们使用以下的代码进行演示:
1 |
<ol class="dp-sql" style="padding:5px 0px;color:#5c5c5c;list-style-position:initial;list-style-image:initial;word-wrap:break-word;word-break:normal;border:none;background-color:#f7f7f7;margin-top:0px !important;margin-right:0px !important;margin-bottom:1px !important;margin-left:55px;"><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"><span style="margin:0px;padding:0px;border:none;background-color:inherit;">db.</span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">transaction</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">( </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">function</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">(tx) { tx.executeSql(</span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">"INSERT INTO ToDo (label, timestamp) values(?, ?)"</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">, <br style="clear:both;width:0px;height:0px;" />[label, new </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">Date</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">().getTime()], </span><span class="op" style="margin:0px;padding:0px;border:none;color:#808080;background-color:inherit;">null</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">, </span><span class="op" style="margin:0px;padding:0px;border:none;color:#808080;background-color:inherit;">null</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">); } ); </span></span></p></li><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p> </p></li></ol> |
在这个示例中,第一个参数中的两个问号将被后面数组中对应的项替代。第一个是为该任务设置的标签(也许是我们之前在代码中定义的一个变量),以及调用函数生成的时间戳。 执行该查询,其结果与下面语句类似:
1 |
<ol class="dp-sql" style="padding:5px 0px;color:#5c5c5c;list-style-position:initial;list-style-image:initial;word-wrap:break-word;word-break:normal;border:none;background-color:#f7f7f7;margin-top:0px !important;margin-right:0px !important;margin-bottom:1px !important;margin-left:55px;"><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">INSERT</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;"> </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">INTO</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;"> ToDo (label, </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">timestamp</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">) </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">values</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;"> (</span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">"Test"</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">, 1265925077487) </span></span></p></li></ol> |
对结果进行处理 成功执行的函数对结果对象包含集合或行。每一列表示一个结果。该结果包含分配给它的一组值,表示该特定结果的数据库中的每一列的值。通过调用 result.rows.item(i) 可以访问一个行,其中 i 是你想要查询的行的指针。想要从一行中选择一个值,你可以传递给该行一个数组格式的字符串指针,它表示你需要查询的列。例如,如果想要标签(label)列,我们可以调用 row['label']。 以下代码使用结果对象来输出一个查询的结果:
1 |
<ol class="dp-sql" style="padding:5px 0px;color:#5c5c5c;list-style-position:initial;list-style-image:initial;word-wrap:break-word;word-break:normal;border:none;background-color:#f7f7f7;margin-top:0px !important;margin-right:0px !important;margin-bottom:1px !important;margin-left:55px;"><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"><span style="margin:0px;padding:0px;border:none;background-color:inherit;">db.</span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">transaction</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">( </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">function</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">(tx) { tx.executeSql(</span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">"SELECT * FROM ToDo"</span><span style="margin:0px;padding:0px;border:none;background-color:inherit;">, [], </span></span></p></li><li style="list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;margin:0px !important;padding:0px 3px 0px 10px !important;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"> </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">function</span><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;">(tx, result) { </span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">for</span><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;">(var i = 0; i < result.</span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">rows</span><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;">.length; i++) </span></p></li><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;">{ document.write(</span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">'<b>'</span><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;"> + result.</span><span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">rows</span><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;">.item(i)[</span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">'label'</span><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;">] + </span><span class="string" style="margin:0px;padding:0px;border:none;color:blue;background-color:inherit;">'</b><br />'</span><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;">); } }, </span><span class="op" style="margin:0px;padding:0px;border:none;color:#808080;background-color:inherit;">null</span><span style="margin:0px;padding:0px;border:none;color:black;background-color:inherit;">); } ); </span></p></li><li class="alt" style="margin:0px !important;padding:0px 3px 0px 10px !important;color:inherit;list-style:none;word-wrap:break-word;word-break:normal;border:none;background-image:url(http://images.51cto.com/images/art1105/images/0.gif);background-attachment:scroll;background-color:transparent;line-height:18px;background-position:-498px -70px;background-repeat:no-repeat repeat;"><p><br /></p></li></ol> |
结论 […]
View Details深知各位开发者们折腾个界面绞尽脑汁、费九牛二虎之力也捯饬不出来一个像样的界面,特奉上 25 个免费界面模板以供参考,不用谢 Flat UI Kit (PSD) by VisualCreative Flat Web Elements (PSD) by Alexey Anatolievich Square UI (PSD) by DesignModo Vector Social Icons (EPS) Flat Vector Chrome Frame (PSD & AI) by Jeffrey Kam Minimal UI Kit (PSD) by ThemeDesigner Web App Flat UI (PSD) by Blaz Robar Flat Blog UI Kit (PSD) by PSDExplorer Flat Mini Browser (PSD) by Joe Barber Flat Browser Freebie (PSD) by Keyners Flat Apple Family Templates (PSD) by NumarisLP Flat Event Creation (PSD) by Seth Ely Flat Mini UI Player (PSD) […]
View Details高效的CSS已经不是一个新话题,也不是一个我非得重拾的话题,但是,它却是自我在SKY工作以后,真正感兴趣并始终关注的一个话题。 很多人或者忘记了,或者仅仅是没有意识到,CSS可以是高效的也可能导致低能。然而,我们可以不考虑当你自认为会的太少而使用了低效的CSS这种情况。 这些规则只真正用在性能要求很高的网站上,这些网站对速度要求很高,任何一个页面可能含有成百上千个DOM元素。但是实践出真理,不管你是在打造下一个facebook 还是在开发一个本地的展示网页,多学点总是好的…. CSS 选择器 CSS 选择器对我们大多数人来说并不新鲜,较基础的选择器分别是类型(如 div),ID(如#header)和类(如.tweet)。 较不寻常的包括基础的伪类(如:hover)和更复杂的CSS3以及 '正则'(‘regex’)选择器,比如:first-childor[class^="grid-"]。 选择器具有固有效率,引用Steve Souders的话来说,较有效到较不有效的CSS选择器的顺序是这样的: ID,如#header Class, 如.promo Type, 如div Adjacent sibling, 如h2 + p Child, 如li > ul Descendant,如ul a Universal,即* Attribute, 如[type="text"] Pseudo-classes/-elements, 如a:hover 引用自Steve Souders的Even Faster网站 认识这很重要,虽然一个ID技术上更快而且表现更优,但几乎都不这样用。用Steve Souders的CSS测试器,我们可以发现一个 ID 选择器 和 一个类选择器 在再渲染速度方面差别很小。 在一台Windows机器上的Firefox6中,我获得了关于一个简单的类选择器的平均再渲染数据。ID选择器给出了12.5的平均值,所以实际上它要比一个类再渲染得慢一点。 ID与类之间的速度差异几乎是不相干的。 对一个类型(<a>)的选择测试,相比一个类或ID给出了慢得多的再渲染。 对一个层次非常多的子孙选择器的测试给出了 大约440的数值! 通过这我们可以发现IDs/classes与types/descendants的差别非常巨大…它们自身之间的差异很细微。 注意 这些数值在不同的机器和浏览器变化非常大。我极力建议你自己运行一下。 组合选择器 你可以单独使用一种标准选择器,如#nav,来选择所有以"nav"为ID的元素,你也可以使用组合选择器,如#nav a,来选择任何在ID为’nav’的元素里面的链接元素。 现在,我们从左到右读这个组合标签。我们先找到#nav ,然后再找到里面的元素。但是我们的浏览器不是这样解析的,它是从右到左来解析这些组合选择器的。 当我们看到#nav里面有个a,而浏览器看到的却是有个a在 #nav里面,这些细微的差异对浏览器的性能有重大影响,同事学习他们是很有价值的。 如果想知道浏览器这样解析的原因,请参考this discussion on Stack Overflow. 对浏览器来说,从最右边的元素(它最想渲染的元素)开始,然后回溯到DOM树比从DOM树的最高层开始选择向下寻找,甚至可能达不到最右边的选择器(关键的选择器)要高效。 这对CSS选择器的性能有重大影响…. 关键选择器 这里讨论的关键选择器, 是处在复杂选择器最右端的选择器,也是浏览器最先解析的选择器。 让我们回到讨论开始的地方,哪种选择器最高效?哪种选择器作为关键选择器会影响选择器的性能;当我们书写CSS代码的时候,正是这个关键选择器影响选择器的效率。 一个关键选择器是这样的:
1 |
#content.intro{} |
天生高效选择器如类型选择器是不是就会有更高的性能?浏览器会寻找.Intro的所有实例(数量不会很多),然后向上查找DOM树,以确定该关键选择器是否在以“content’”为ID的元素里面。 然后,以下的选择器性能就不怎么好了:
1 |
#content*{} |
这个选择器做的工作是这样子的,它先查找每个页面(是每个单个的页面),然后去看看它们是否有一个 #content 的父元素。这是一个非常不高效的选择器,因为它的关键选择器执行开销太大了。 运用这些知识我们就能在分类和选择元素时做更好的选择。 假设我们有一个非常庞大的页面,非常的大并且是一个还有一个庞大的网站。在这个页面上,有上百甚至上千个<a>标签。社交媒体的链接只占很少的一部分,并且包含在ID为#social的<ul>里面。假设这些链接是,Twitter, facebook, Dribble 和 Google+。我们在这个页面上有四个社交媒体链接,还有上百个其他的链接。 以下这个选择器代价很高而且性能不好:
1 |
#social a{} |
浏览器将访问扫描页面上的上千个链接,然后才选择上#social节点下的四个链接。我们的关键选择器匹配了大量的我们并不感兴趣的标签。 为了消除这个问题,我们可以为每一个包含在社交媒体<ul>块下面的<a>标签指定更明确和显式的选择器.social-link。但是这跟我们所知道的恰恰相反;我们知道了,当我们使用精简的标签的时候,尽量不要使用多余的类。 这就是为什么我觉得性能是如此的有意思;在网页标准最佳实践和速度之间,需要一个平衡。 […]
View Detailshtml, body, div, span, object, iframe,h1, h2, h3, h4, h5, h6, p, blockquote, pre,a, abbr, acronym, address, big, cite, code,del, dfn, em, img, ins, kbd, q, s, samp,small, strike, strong, sub, sup, tt, var,b, i, dl, dt, dd, ol, ul, li,fieldset, form, label, legend,table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-size: 100%; vertical-align: baseline; background: transparent;}body { line-height: 1;}ol, ul { list-style: none;}blockquote, q { quotes: none;}blockquote:before, blockquote:after,q:before, q:after { content: ''; content: none;} /* remember to define focus styles! */:focus { outline: 0;} /* remember to highlight inserts somehow! */ins { text-decoration: none;}del { text-decoration: line-through;} /* tables still need 'cellspacing="0"' in the markup */table { border-collapse: collapse; border-spacing: 0;} /* Resetting HTML5! */section, article, aside, header, footer, nav, dialog, figure { display:block; }
View Details3.1框架中的工具 这个CSS中工具有点像C#中的static class,把一些常用的方法放到类里面达到可复用的效果.在CSS中.有很多CSS class是在我们在项目设计中一遍又一遍的要用到的.因此这些tool是CSS框架中必不可少的一部分。 3.2工具类的组成和组织方法 一般现有框架会把这个.class的定义放到各个不同的文件中比如,from.css(用于格式化表单),typography.css(用于格式化布局),但是这个工具类却是我们自己写框架的精髓所在,因为这是我们框架中可以扩展的部分,所以我更喜欢把css class单独命名为tool.css来存放这些工具类.(因为这样在网站改版时就要愉快很多) 也许废话太多了.下面简单给出几行代码,让大家对所谓的Tool.css有初步了解。 Code 1/* 用于格式化Form的CSS Tool 2 3————————————————————-- */ 4 5 6 7.error, 8 9.notice, 1011.success { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd;}12131415.error { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4;}1617.notice { background: #FFF6BF; color: #514721; border-color: #FFD324;}1819.success { background: #E6EFC2; color: #264409; border-color: #C6D880;}202122 这是用于表单的一些CSS类.有了这些.我可以让项目中每一个使用表单的地方风格实现统一. 而使用JS的地方可以更加简洁.下面一小部分代码是使用了JQUERY从服务器获得AJAX响应后的代码片段 Success:function(data){ $(“<span>”+data+”</span>”).addClass(“success”).appendTo(“#result”); } 恩.是不是简单多了? PS:看客:你不是号称CSS框架吗.这样写不就是把css放一起吗?吹的那么玄乎. 别急嘛.下面讲到CSS之间的组织方式 在我被CSS蹂躏的经历里,其实有很多CSS布局,以及CSS选择符方面问题,大部分是因为CSS选择符之间优先级的关系,这些问题因为简单,所以折磨的各位Developer痛不欲生.但是这些问题就像枪一样,好好利用可以保护你,如果利用不当会让你遭殃。 下面说说我总结的CSS的OCP原则(开放封闭原则),这个规则是设计模式里的,但我发现在CSS中同样适用. 当你针对项目的CSS基本框架写好后,可以添加你所需要的元素,但如非必要,不要去修改它,而是在需要修改的地方重载。 重载: 以上面的例子为例.如果我们在一个特定页面里,想让error颜色变得更加刺眼比如让error的color变成red,只需在你需要修改的特定页面头部的<style>标签中设置 1.error{23Color:red;45}6 因为内页 style比外联style有更高的权值(如果你对CSS的优先级问题不太了解,参考这个文章http://www.xker.com/page/e2009/0622/72573.html),所以error显示的字就会变成红的,但同时又会保留了background和border-color的属性.因此我可以更优雅的覆盖原有CSS,达到重载的目的. 扩展: 当我们需要一组新的css类时,只需要在tool.css相应部分增加即可,比如我们需要表单增加一个介于notice和error之间警告程度的alert用于显示那些有点警告意味的信息.我们只需要加入 1.alert23{45/*——代码写在这—-*/67}8 这样做的优势: 1.代码更加优雅,维护更加方便 2.容易变换网站风格,举个例子,如果你原来的颜色风格偏深,那么你想换一套浅颜色的风格,只需要改变你所需要改变的部分,把你需要改变的部分重新写一个CSS来覆盖原来的CSS,示例代码如下: <link href="css/tool.css" rel="stylesheet" type="text/css"/><link href="css/toolBlue.css" rel="stylesheet" type="text/css"/> 这样看起来tool.css是不是很“面向对象”,很像基类,而toolBlue像子类,继承那些padding和magin之类的布局属性,而重载color等风格属性,oh yes,life seems like more easier than ever bofore:–) 3.3写在最后 下面我拿出一个简单的tool.css展示出来,让大家有个更直观的了解。 Code/*用于格式化Form的CSS Tool ————————————————————-- */ .error, .notice, .success { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd;} .error { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4;} .notice { background: #FFF6BF; color: #514721; border-color: #FFD324;} .success { background: #E6EFC2; color: #264409; border-color: #C6D880;} .error a { color: #8a1f11;} .notice a { color: #514721;} .success a { color: #264409;} /*用于布局方面的css tool ————————————————————-- */ .clear { clear: both; display: block; overflow: hidden; visibility: hidden; width: 0; height: 0; } .clearfix { display: inline-block; } //用于显示方框,实际应用中我喜欢加边框 .box { padding: 1.5em; margin-bottom: 1.5em; background: #E5ECF9; } /*根据项目自定义的css tool ————————————————————-- */ //以下几个是用于和js交互时使用 .hide { display: none;} .highlight { background:#ff0;} .added { background:#060; color: #fff;} .removed { background:#900; color: #fff;} //下面是关于字体的 .small { font-size: .8em;; } .large { font-size: 1.2em; } //还有其他你自定义的class….etc… 恩.基本经常要用到的就是这些,但tool.css的重点在于随着你项目的进展,这个tool.css也会越来越胖. J […]
View Details2.1浏览器的差异在何处 我想写CSS的人大多遇见过在IE里写的页面美轮美奂,而用FF打开却是分崩离析,反之亦然.这种痛苦是因为IE和FF对一些默认样式的解析并不相同所导致. 网上有很多为何不一样的例子,下面链接是一个比较全的不同之处,大家可以进去看看。 http://hi.baidu.com/css%D6%AE%C3%C0/blog/item/f44628e6a506c229b83820ef.html 2.2如何实现跨浏览器 2.2.1实现原理 既然问题出在FF和IE对各种不同HTML元素的解析上所有偏差.更不用说一些其他小市场份额的浏览器上.我们只需要针对性的把页面里大多数HTML元素重置即可.这样在各种浏览器里面显示的效果会是相同的. 2.2.2实现方式 重置我们选择的名称和大多数框架一样,reset.css,用我们Develper的思想理解——--框架中所有元素的基类,就像.net里的Object对象一样。 下面我们来说说reset.css的构成. 1.首先定义最基本的body,因为所有其他元素都由此继承.我喜欢的框架遵循“尽量保持小”的原则,所以我只简单清除padding和margin,以及设置字体(设置成具体数值,因为在后面用’em’做单位的时候都要以这里做比较,页面风格需要整体变化时,重载这里.) 2.将大量浏览器预定义的块状元素清除magin和padding(块装元素即在未定义样式的情况下浏览器render出来的方式为display:block;的元素) 3.让列表前面的符号消失,图片边框消失,p的上下边距为一行字. 我喜欢reset.css尽量保持简洁.只要实现了基本的重置即可. PS:不过也不能过于简洁.记得曾经的框架喜欢对”*”这个CSS选择符重置.可是这个杀伤力太大,往往是杀敌1000自伤800,遇到input之类的表单元素时还得重置回来.最后据传说这样还有性能问题-.-!!不过难以考证… 下面是满足上面条件最基本的reset.css Code1.body { 2. padding: 0; 3. margin: 0; 4. font: 13px Arial, sans-serif; 5. } 6. body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset ,p,blockquote { 7. padding: 0; 8. margin: 0; 9. font-weight: normal; 10. font-style: normal; 11. line-height: 1em; 12. font-size: 100%; 13. } 14. table { 15. font-size: inherit; 16. font: 100%; 17. } 18. ul { 19. list-style: none; 20. } 21. img { 22. border: 0; 23. } 24. p { 25. margin: 1em 0;} 这个reset.css是目前我个人最喜欢,因为reset.css就像.net中的Framework中的Object类一样,应该尽量保持精简,这个精简了很多.只留下了必要的重置. 在这里值得一说的是:在body里将font的大小和字体设置了具体的值,在其他元素里通过继承的方式来重写这样的方式是我最喜欢的,这样可以很容易的保持页面整体风格的统一 2.3一些注意事项 Reset.css一经写好,除了BUG之外.永远不要去修改它.而是在其它页面中重载它(不知道用OO的方式理解CSS是否正确,即利用CSS的优先级特性覆盖.这个在下一章说到.) http://www.cnblogs.com/CareySon/archive/2009/07/07/1518543.html
View Details1.1为什么需要CSS框架 其实这个问题如果要罗列出来网上有一大堆.但是对我们这些”I’m a web developer more than web designer”的人来说,有时候看似简单的CSS却成了网站设计最让人心力憔悴的部分.所以我还是要罗列一下使用CSS框架的好处. PS:一位看客:我们有前台,还有美工,为什么我还要整个什么CSS框架?答曰:我等在小公司没有如此优厚的条件,一个人从前台JS,XHTML,CSS到后台C#,再到Database全是我们2-3个人..所以,请有条件不用兼web designer的看客不要拍砖-.-!! 1.1.1解放生产力 我们对在VS里建立一个新项目太熟悉了.但却往往不知道该怎么处理CSS问题,随着项目的进行,页面设计总是有所变化.这些变化往往会让没有使用CSS框架的你擦掉几乎所有的CSS然后重写.好吧.你赌气想,我开始不写CSS了,等项目后期再写..可是后来你发现外观丑已经让你心情低落了.而和JS交互的那部分CSS你还不得不写.这足以让你抓狂了.而CSS框架可以把你从这种痛苦里解救出来. 1.1.2代码结构清晰,避免混乱和冲突 通过对CSS的清晰有条理的定义.会让我们节省更多的时间专注在设计页面上, 而不是费劲的去查找自己所需要更改的样式. 1.1.3更好的团队合作 我深受混乱的CSS带来的痛苦.我和一位同事曾经一起通过VSS编写样式, 有一个定位的CSS无论我怎样修改,那个元素纹丝不动.找了半天原来.才发现我同事在更高级别的CSS上面进行了定义. 我当然无论怎样定义都不行了,使用CSS框架可以避免此类尴尬.. 1.1.4跨浏览器 这个当然是使用CSS框架的一个亮点,因为IE和FF以及其他市场小份额的浏览器对不同样式预定义的解析方式有所差异.导致用IE测试做出的页面在FF里完全崩溃.进而导致你也崩溃-.-!!反之在FF里测的页面在IE里又崩溃了.导致你也跟着再次崩溃-.-!! 1.1.5依托CSS框架有一个更好的工作流程 我想这个不难理解.大多Developer对CSS头痛的原因就是因为感觉无从下手,而CSS框架让你有路可寻. 1.1.6节省下载流量 CSS框架会让你大幅减少重复定义的次数,进而减少需要下载CSS文件的 流量. 1.1.7网站变换风格更加容易 在项目对整体颜色或者效果改版时.之需要略微改动下项目的CSS框架文件, 或是写个新的CSS文件对框架进行部分覆盖.即可达到效果. 1.2 为什么网上已有那么多CSS框架,我还要自己写 其实我也是从使用网上成型的CSS框架开始,不可否认,他们的CSS框架写的非常优秀,有很多地方可以借鉴.我曾经以为使用熟练一个框架已经足够,可是工作中使用别人的框架产生了一系列问题.下面我一一分解. 1.2.1 必须深入了解框架的每一行代码 因为如果你不仔细学习你所使用的框架的代码,你会发现工作中总会有一些“灵异现象”,你明明这么定义,页面却是那样. 还有就是仔细阅读框架的代码的学习成本足以让你自己写一个自己专用的框架。 1.2.2 别人的框架不一定适合你 因为别人的框架并不会完全适合你的项目,而网上的CSS框架往往过于臃肿,自己写框架当然会对项目更有针对性。 1.2.3 自己写CSS框架会让自己的CSS水平有质的提升并更加针对自己的项目 这也算是题外话了J不过自己写CSS框架以及学习CSS框架的写法是一种CSS学习.会让自己的CSS水平站在一个新的高度,这也是本系列文章所希望的. http://www.cnblogs.com/CareySon/archive/2009/07/06/1517912.html
View Details1. Stylish jQuery Accordion 一个完全可定制的卷帘插件,可用于在有限的区域显示很多的文本和图片数据 下载插件 (Free) 2. HorizontalNav 水平导航菜单自动扩展宽度到父一层元素的宽度,这是实现响应式优雅菜单的好方法。 下载插件 (Free) 3. jQuery Sidebar 在你的网页上显示可扩展的边栏 下载插件 (Free) 4. PageScroller 为你的网页添加平滑的滚动导航 下载插件 (Lite version free or $35) 5. Explr 轻量级和可定制的树状菜单 下载插件 ($6) 6. Sticky Mojo 可固定在网页某个位置的边栏,不跟随页面的滚动更改变位置 下载插件 (Free) 7. ddSlick 下拉菜单,带图片和描述 下载插件 (Free) 8. CSS Dock menu Mac 风格的菜单 下载插件 (Free) 9. Metro flexible navigation Metro 风格的菜单 下载插件 ($6) 10. Filtrify 外观超棒的标签过滤插件 下载插件 (Free) via designer-daily 转自:http://www.oschina.net/news/39290/10-jquery-plugins-for-better-website-navigation
View Details