SASS 需要运行在 Ruby 下,进入这个页面,下载最新版本的 rubyinstaller,一路 Next 完成安装。
在开始菜单中找到 “Ruby 1.9.3-p0 -> Start Command Prompt with Ruby”并运行。
输入以下命令
gem install compass该命令会自动下载和安装 COMPASS 及其依赖模块(包括 SASS)。

在命令行中切换到你需要创建项目的目录,运行:
compass create <projectname>
这个命令会创建一个包含一系列文件的目录,其中最重要的是配置文件 config.rb,其他文件如果你不需要都可以删除。
在 config.rb 中你可以修改 SASS 和 CSS 的目录及其它一些基础设置。
在命令行下切换到项目目录,运行:
compass watchCOMPASS 将会实时监控 SASS 目录的文件变化,只要你一保存文件,立即将相应文件编译为 CSS 文件。
既然现在用 SASS 来开发,我们就需要浏览器开发工具中显示样式对应的 SASS 行号而不是 CSS 行号了。
如果你使用 Firebug 可以安装 FireSass 来解决这个问题。
首先修改 SASS 的配置文件让其在 CSS 文件中输出调试信息,打开项目目录下的 config.rb,添加一行并保存
sass_options = {:debug_info => true}如果你在 watch,结束掉重新运行配置的修改才会生效。
然后下载安装 FireSass 后就能看到 Sass 行号了。

顺带一提,源码下载地址为:https://github.com/jquery/jquery/downloads。
今天先分析最外层的闭包,最外层的闭包代码在 intro.js 和 outro.js 这两个文件内,一个头一个尾。代码如下:
(function( window, undefined ) {
//jQuery 代码....
})( window );
可以看到 window 对象被作为参数传入,这种方式可以减少解析变量 window 时查询作用域链的深度,有助于提升性能。很多 jQuery 插件也是以这种方式把 jQuery 对象传入闭包内部的。
还有一个声明后未被传值的参数 undefined。由于 undefined 被设计成一个全局变量而不是关键字,所以 undefined 是可以被赋值的,为避免使用被污染的全局变量 undefined 而导致 bug,所以在闭包作用域里产生一个名为 undefined 的未被赋值的参数(未被赋值的变量其值为 undefined 的默认值)正好不过。
下一篇内容为 data 模块。
]]><style>
button:hover, button.hover {
}
table tr:hover, table tr.hover {
}
</style>
<script>
$(document).ready(function($) {
$('button').fixie6Hover();
$('table').fixie6Hover('tr'); //事件代理
});
</script>源代码:
( function($) {
if(!($.browser.msie && $.browser.version < 7)) {
$.fn.fixie6Hover = function() {
return this;
};
return;
}
var onMouseenter = function() {
$(this).addClass('hover');
};
var onMouseleave = function() {
$(this).removeClass('hover');
};
$.fn.fixie6Hover = function(selector) {
if(selector) {
this.bind('mouseover', function(event){;
if($(event.target).is(selector)) {
onMouseenter.call(event.target);
}
})
.bind('mouseout', function(event){;
if($(event.target).is(selector)) {
onMouseleave.call(event.target);
}
});
} else {
this.bind('mouseenter', onMouseenter)
.bind('mouseleave', onMouseleave);
}
return this;
};
}(jQuery));
下面是一个更短小的仅 jQuery1.7+ 可用的版本:
( function($) {
if(!($.browser.msie && $.browser.version < 7)) {
$.fn.fixie6Hover = function() {
return this;
};
return;
}
var events = {
mouseenter : function() {
$(this).addClass('hover');
},
mouseleave : function() {
$(this).removeClass('hover');
}
};
$.fn.fixie6Hover = function(selector) {
if(selector) {
this.on(events, selector);
} else {
this.on(events);
}
return this;
};
}(jQuery));
]]><link rel="stylesheet" href="css/style.css" />
<!--[if IE]><link rel="stylesheet" href="css/ie.css" /><![endif]-->
<!--[if IE 6]><link rel="stylesheet" href="css/ie6.css" /><![endif]-->以上代码大家应该都了解,对蛋疼的 IE 使用额外的样式表解决蛋疼的 IE 兼容性问题。
这种方案有2个缺点:
所以大型网站都不会使用这个方案,要么一个通用样式表搞定,要么注释不会产生请求的内嵌样式表。
那么还有更好的方法么?以下这种写法是我在 W3C HTML5 Loge 上发现的:
<!--[if lt IE 7 ]> <html lang="zh-cn" class="ie6 ielt8"> <![endif]-->
<!--[if IE 7 ]> <html lang="zh-cn" class="ie7 ielt8"> <![endif]-->
<!--[if IE 8 ]> <html lang="zh-cn" class="ie8"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> <html lang="zh-cn"> <!--<![endif]-->这样我们就可以 easy 的在 CSS 里写:.ie6 body { /* Go to Hell! */ }。
然后 jQuery 里可以这么写:if ($('.ie6').length) { /* Go to Hell! */ }。
很好很强大是吧?
]]><ul id="movieList"></ul>
<script id="movieTemplate" type="text/x-jquery-tmpl">
<li><b>${Name}</b> (${ReleaseYear})</li>
</script>
<script type="text/javascript">
var movies = [
{ Name: "The Red Violin", ReleaseYear: "1998" },
{ Name: "Eyes Wide Shut", ReleaseYear: "1999" },
{ Name: "The Inheritance", ReleaseYear: "1976" }
];
// Render the template with the movies data and insert
// the rendered HTML under the "movieList" element
$( "#movieTemplate" ).tmpl( movies )
.appendTo( "#movieList" );
</script>发现端倪没?有个 script 的 type 居然是 text/x-jquery-tmpl,恩,这就是模板了。
这不是一篇关于 jQuery Templates 介绍文章,更多基础内容可以看官方 API 和黑暗執行緒 blog 的相关文章。
本文想探讨的是对于一个比较复杂的站点,应该如何管理 jQuery 模板。
jQuery 模板有3种储存方式:
其中3是下下之选,因为保存在字符串中很多字符需要转义、不能换行、难以阅读和修改,有违模板简化 data to html 的初衷,而且如果需要多处代码使用一个模板,会不够灵活。
2会将无意义的模板写入 DOM 中,可能会被搜索引擎抓取,而且还要多一步解除隐藏的操作,不如直接用1。
1也有自身的问题,模板是和特定 js 操作关联在一起的,如果分离两者,后台得判断页面需要输出哪些模板,这多少会增加后台复杂度。当然也可以不做判断直接输出所有模板,这会无谓的增加文件大小,如果模板很多,这样也不可取。
其实可以把模板单独放到一个文件中,需要时才用 ajax 获取然后插入 dom。如果模板很多也可以拆分成多个文件按需加载。这样有2个好处,1是模板不占用 html 的字节,2是像 css 和 js 一样,浏览器可以缓存起来。
然后我们可以写一个简单的插件来管理模板获取。
//jQuery.getTmpl.js by Frully
(function ($) {
var _tmpls = {}; //保存已获取模板的信息 url: deferred
$.getTmpl = function (url) {
var tmpls = _tmpls,
tmpl = tmpls[url];
if (!tmpl) { //如果模板不存在,获取并插入 DOM
tmpls[url] = tmpl = $.get(url).done(function (data) {
$(data).appendTo('body');
});
}
return tmpl; //返回 deferred 对象
};
}(jQuery));调用方法:
$.getTmpl('temp1.tpl').done(function () { //载入成功时调用
//do something
}).fail(function () { //载入失败时调用
//do something
}).always(function () { //无论成功失败与否都调用(jQuery1.6 新增)
//do something
});
$.when($.getTmpl('temp2.tpl'), $.getTmpl('temp3.tpl')).done(function () {
//当两个模板均载入成功时调用
//do something
});有几个方法看起来有些奇怪?这是 jQuery 1.5 的新特性 Deferred(其中 .always() 是1.6 新增)。网上有不少相关资料,欲知详细请自行搜索。使用 Deferred 能书写出很优雅的代码,如果你无法使用 jQuery 1.5+,只能修改插件以参数传入回调函数了。
]]>原本我以为:
我错了,HTML5 确实是一个伟大的规范,她的伟大之处在于她的设计基于一个理念:求真务实。她着力于解决实际问题而不是构建理想的乌托邦。
<a href="/path/to/resource">
<h2>Headline text</h2>
<p>Paragraph text.</p>
</a>只用一个 <a> 套住所有要链接的元素,这段代码简单又优雅,浏览器也能正常解析;但是却不符合 XHTML 规范,只因为一个理由:理论上行内元素不应该包含块级元素。所以我们为了理论的完满必须忍受实行的麻烦。
好了,HTML 5 告诉你,你完全可以这么写,因为你是代码作者,作者比理论的完满重要。
读读《HTML5 设计原理》吧,里面有很多这样可爱的代码,相信读过后你们也会爱上 HTML5 的。
另外,IE 9 以下的 IE 浏览器无法渲染新的 HTML5 元素,可以通过 html5shiv 来支持。看看我爱水煮鱼的介绍。
]]>a {
display: block;
width: 100px;
height: 40px;
background: url(home.png);
text-indent: -999em;
overflow: hidden;
}负缩进是最常用的 CSS 图片替换文字技术,这个方法的缺点是如果图片加载失败,元素就会变成空白的,原有文字也无法显示。
所以后来又发展出另一种技术,在要替换图片的元素里加入一个空元素,给这个空元素添加背景,然后再用绝对定位覆盖到原有文字上。
<div>HTML<span></span></div>a,
a span {
display: block;
width: 100px;
height: 40px;
}
a {
position: relative;
}
a span {
background: url(home.png);
position: absolute;
top: 0;
left: 0;
}这个方法解决了第一个方法的缺点,但缺点是需要在 html 中添加冗余代码。
受 after 清除浮动技术的启发,我使用 :after 替换第二种方法中的空元素,这样就不需要在 html 中添加冗余元素了。
a,
a:after{
display: block;
width: 100px;
height: 40px;
}
a {
position: relative;
}
a:after {
content: '';
background: url(home.png);
position: absolute;
top: 0;
left: 0;
}这种方法很好的解决了前两种方法的缺点,可惜不支持 IE6 和 IE7(IE6 和 IE7 不支持 after 选择器)。本着平稳退化的原则,可以让 IE6 和 IE7 继续使用第一种方法。
<!--[if lt IE 8]>
<style type="text/css">
a {
text-indent: -999em;
background: url(home.png);
}
</style>
<![endif]--> ]]>一开始我用覆写 Views 模板的方法来清除垃圾代码,但是对快速开发的企业站,这个方法比较费时费力。
后来我找到了 Semantic Views 模块,这个模块提供对 Views 输出的更简单更精细的控制。这个模块很容易使用,安装好后,在 Views 的设置里将样式改为 Semantic Views、行样式改为 Semantic Views : Fields,再按照自己需求设置一下就OK了。
另外还有 Semantic CCK 模块,可以用来清除 CCK 输出的垃圾代码。
]]>