很久很久以前,我刚接触到这一行的时候,用的是一款名叫webedit的WEB在线编辑器。当时并不了解什么WEB标准,后来才发现在非IE的浏览器下都用不了。其实抛开兼容性的话,这一款还算是蛮不错的在线编辑器了。
再后来,就用到了所谓大名鼎鼎的FCK。FCK功能的确是不错,但我实在没法称赞它好用,他真的很难用,或者说是不适合中国人的使用习惯吧。像我们一些开发人员自己用还没什么,如果给客户做的程序用的是FCK,那么一个上传图片的模式就会搞得人摸不着头脑。
然后我不停地在找,终于碰到了一款近乎完美的WEB在线编辑器——xheditor。没有说它完美,因为它还有一个前提条件,是用jquery框架开发的。不过就算项目用的不是jquery框架,加上一个50K的JS包,它的体积还是非常小的,调用相当方便不像以前的那些需要插入一个iframe而是一个textarea就可以了,而且非常适合国人的使用习惯。详细介绍我这里就不写了,大家可以去谷歌代码上去看,他们的开发团队一直都有更新版本。
http://code.google.com/p/xheditor/

其实在平时很少注意到CSS渲染效率的问题,不过在很多时候都是细节决定成败,这也是个不容忽视的问题。之前也拜读过网上流传的一篇有关CSS渲染效率的文章,传得太多,也不知原作是谁了。不过并不是太赞同其中的一些观点,所以就本人工作中的一些经验以及看法,说说这个问题,个人观点并非权威,欢迎拍砖。
在这里我们不只是单纯地研究渲染效率的快或慢,应该从一个项目的整体来看。页面渲染的这个过程,是在用户本地进行的,也就是说用户打开页面,载入了HTML代码以及样式表、JS等等相关的文件,浏览器再跟据这些文件把页面渲染出来。关于速度方面,我们更注重的是载入的速度。而渲染速度,的确某些样式的写法会存在渲染速度的差异,但对于当前随便每秒都能运算上亿次的个人电脑来说,把一张背景图平铺100次跟平铺10000次又有多大区别呢?当然,细节,细节决定成败,但细节不等于吹毛求疵,下面说说个人对此侧重点的一些看法。
可能会有影响,但可跟据具体情况忽略的部分
比如说颜色值,color:#F00;、color:#FF0000;、color:red; 这三者都是一样的,至少用人类的感观无法区分其对渲染速度的影响,用简写可能或多或少能减少那么几个字节的体积,不过标准写法是6位大写字符的写法。
display与visibility就不详说了,这本身就是两种不同的表现属性,该用谁就用谁。
注意某些样式的保留属性,比如说:
background:url(image.jpg);这样一句,那么在渲染的时候会默认输出background-color : transparent 、background-attachment : scroll 、background-repeat : repeat 等等属性。在完美主义者的眼里这是对资源的一种浪费,但同样,人类的感观体会不到此影响。其实个人还是认为简写形式有助于减少样式表的体积,而且这也似乎是行内默认的写法了。同样的,border、list-style等也有默认属性,也不用深究了。
背景平铺的问题
对于可平铺的背景来说,很多人喜欢用1px为单位来进行平铺,前面也说了,其实平铺多少次对于个人电脑来说几乎都是一样的,关键在于图片的大小了。对于可平铺的图片,一定范围内的像素值是一样的,所以增大尺寸对于积体的影响并不大,我这里对比了单色1*1跟10*10的图片在jpg跟gif格式下的大小,相差都几有几个字节

其实本人不太建议用1px的图,至少自己在修改的时候无法一眼看出那张图片是什么。而且现在用css sprites也会把可平铺的部分也做进去,这也是对渲染效率的提升了。
再说说会有明显影响的部分
@import 的使用
不建议在页面里使用,他会在页面加载完之后才被加载,有可能使页面闪动或是裸体。如果是样式表过多为了方面管理的话,放在CSS里就好。
某些选择符的使用
渲染的过程也就是对这些选择符的匹配,所以我们可以很容易地理解到,一些比较直接的选择符比如类选择符、ID选择符等的匹配效率高,而一些条件比较繁复点的选择符比如子选择符、属性选择符等的匹配效率相对来就低一些。当所匹配的量比较多的时候,可以明显地感觉到速度的差别。(关于各种选择符,具体可查看CSS手册了)
IE的滤镜
自从标准化的兴起以来,IE滤镜的日子就不好过了,除了不兼容以外,某些滤镜真的蛮耗资源的。现在还在用的可能就是为了处理IE6下图片透明的问题了,建议能不用就不用他吧。
expression的使用
也许这个不能归为渲染的部分,不过他的确相当占资源,如果加得多的话,会让你的页面其慢如牛。
说到lightbox,做这行的人应该都不陌生,想当年那牛逼哄哄的效果着实让我眼前一亮。不过原版的lightbox是用Prototype框架写的,但本民工只懂得少许的jquery,总不能同一个项目中用两个框架吧,还好牛人们已经做出了基于jquery的lightbox的插件了。其实wordpress里就有很多lightbox的插件,不过这东西可不是只用在博客里,还是整理一个能通用的吧。
jQuery lightBox 0.5,是当前最新的版本了,在这里本民工稍微修改了一下,去掉了点击时的虚线框,以及修改了有关中文的样式。
下载:jquery-lightbox-05.rar
不知有没有朋友碰到过这个问题,我也是前阵子做一个FLASH的时候才碰到这个问题。鼠标指向FLASH中的链接区域时,鼠标不是固定的手形,而是在手形跟指针之间不停地变换。这并不是点击区域的问题,因为单独打开FLASH是好的,在FF中也是好的,只是在IE中会出现此问题。
然后查阅资料,找到了解决方法,在FLASH的属性参数中加上以下两句中任意一句都可以解决
<param name="wmode" value="opaque">
<param name="wmode" value="transparent">
因为在DW里插入FLASH时默认是没有这两句的,另外现在很多都会用类似AC_FL_RunContent的JS加载FLASH,也要记得在相应位置加参数。
对于一个WEB前端工作者来说,Yslow绝对是一款必不可少的性能优化工具,可以方便地查出是哪些因素影响了你的网页性能。

新版本的Yslow共有22条指标,比原来的多了9条。还可以自定义规则,新版本Yslow有三个内置的规则:V2、V1、小型站和博客,V2的指标最多,包括所有22项指标,而V1则只包括上一个版本的13条指标。你可以完全设置自己的规则,这样就可以比较灵活,也更客观实际的分析自己的网站。另外,还增加了一些网站的优化工具,比如Smush.it、JS Minified、 JS Beautified等等。
在这里我只列举一下新增的那9条指标了,其它的可以看另一篇网站优化——Yslow评分标准。由于是本人自行翻译的,如有错漏还请达人指出。
Make AJAX cacheable
设置AJAX的缓存。当前AJAX的应用越来越广泛,AJAX的信息读取是异步的,这也表示用户不一定会等待这异步的响应,为避免重复的AJAX请求,设置缓存是优化性能的一个好方法。
Use GET for AJAX requests
用GET获取AJAX请求。又是一条有关AJAX的。AJAX的传值可用GET跟POST,在这里建议使用的是GET。
Reduce the number of DOM elements
减少页面DOM节点。也就是讲究页面代码的简洁,一个复杂的页面不仅增大页面的体积,也会对JavaScript访问DOM元素产生影响。
Avoid HTTP 404 (Not Found) error
避免404错误页面的出现。这个应该不用怎么解释了,不管从服务器资源还是用户体验上来说,都是不好的。
Reduce cookie size
减少cookie的大小。cookie一般用于身份验证等用途,一般说来cookie被限制在4K以内,尽量控制 Cookie 的大小,不要塞入一些无用的信息。
Use cookie-free domains
使用域名无关性的Cookie。这里是有关静态服务器的问题,主要是指一些静态文件比如说图片、CSS等等,比如说YAHOO,他的静态文件都在 yimg.com 上,客户端请求静态文件的时候,减少了 Cookie 的反复传输对主域名的影响。
Avoid AlphaImageLoader filter
避免AlphaImageLoader滤镜的使用。这个几乎都是用在IE6下解决PNG透明的问题上的。而为了实现此效果而牺牲的性能来说,是很不合算的。
Do not scale images in HTML
不要对图片进行缩放。也就是图片的实际大小大于他的显示必要,比如一个800*600的图片,而我们在页面上只显示的是400*300的大小,那么这便是一种服务器资源的浪费。
Make favicon small and cacheable
使图标尽可能小,并使用缓存。这里指的是favicon.ico了,设置favicon.ico缓存可以避免频繁的页面请求。
想来想去,还是稍微写点东西吧,一来是想把自己的一些制作的思路与大家分享,二来也想请高手们点评一下。在这里把一些重点的部分详细说明一下,相信有点基础的朋友都能很快理解,心急点的朋友呢就直接跳到最后去看源码吧,呵呵。观看演示。
大体思路:载入图片、把图片分割、随机排列图片、鼠标点击事件、序列的比较判断是否结束。在这里只把一些关键的代码帖出来了,但不影响理解。
首先是加载图片,我们这里用的是外部载入,当然你也可以扩展一下做成可以多张图片选择的:
1
2
3
4
5
| private function loadpic() {
_loader = new Loader();
_loader.load(new URLRequest("myphoto.jpg"));
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoad);
} |
接下来到了一个重点了,分割图片,这里应该会有很多种处理方法,我这里用的是Matrix控制背景图填充的方法来实现的。有更好的方法还望大家指出来。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| private function onImageLoad(event:Event):void {
var bitmap:BitmapData = new BitmapData(_loader.width, _loader.height);
var x_num:int=480/x_p;//每小块的宽
var y_num:int=360/y_p;//每小块的高
bitmap.draw(_loader);
pic_box=new box_bg();
pic_box.x=10;
pic_box.y=10;
addChild(pic_box);
d_arr=new Array();//初始数组
for (var i:int=0; i<x_p; i++) {
for (var j:int=0; j<y_p; j++) {
var matrix:Matrix = new Matrix();
matrix.translate(-x_num * i,-y_num * j);//背景定位
var block:Sprite = new Sprite();
block.x=x_num * i;
block.y=y_num * j;
var temp_obj:Object={obj:block,b_x:block.x,b_y:block.y};
d_arr.push(temp_obj);//存入初始数组,在这里把obj也存入,方便后面的比较。
block.buttonMode=true;
block.graphics.lineStyle();
block.graphics.beginBitmapFill(bitmap, matrix);
block.graphics.drawRect(0,0,x_num-1, y_num-1);//通过背景图填充的方式分割图片
block.graphics.endFill();
pic_box.addChild(block);
}
}
} |
图片分割好了,接下来就是要把它打散,也就是随机排列。我们刚才已经把正确的顺序存入了d_arr数组,那么现在要做的就是把这个数组复制一个出来,然后随机排列,用sort()加一个比较函数就可以实现。d_arr是初始的数组,c_arr是随机化了的数组,都包含了[obj,x,y],把d_arr中的obj取值c_arr中的x,y,那么就实现了图片的随机排列。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| private function block_pic(e:MouseEvent) {
var fooba:ByteArray=new ByteArray();//深度复制数组。
fooba.writeObject(d_arr);
fooba.position=0;
c_arr=fooba.readObject() as Array;
c_arr.sort(randomsort);//随机排列
for (var i=0; i<c_arr.length; i++) {
d_arr[i].obj.addEventListener(MouseEvent.CLICK,block_click)//在这里加上鼠标点击事件。
d_arr[i].obj.x=c_arr[i].b_x;
d_arr[i].obj.y=c_arr[i].b_y;
}
}
//随机排列比较函数
private function randomsort(obj_A:String,obg_B:String):int {
return Math.floor(Math.random() * 3 - 1);//这里只能产生-1、0、1三种值。
} |
接下来是鼠标点击事件,我们这里要的效果是点击两个不同的图片使之互换,这一步比较简单,给个变量来判断是第一次还是第二次点击,记录下坐标然后互换就可以了。当然还得记得把点击的对象深度置顶,不然移动的时候会被其它图片挡住的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| private function block_click(e:MouseEvent) {
//第一次点击
if (d_choose) {
click_x1=e.target.x;
click_y1=e.target.y;
var v_obj=e.target;
c_obj=v_obj;
pic_box.setChildIndex(v_obj,pic_box.numChildren-1);
c_obj.alpha=0.7;
d_choose=!d_choose;
} else {
//第二次点击
v_obj=e.target;
pic_box.setChildIndex(v_obj,pic_box.numChildren-1);
c_obj.alpha=1;
TweenLite.to(c_obj,0.3,{x:e.target.x,y:e.target.y,onComplete:check_end});
TweenLite.to(e.target,0.3,{x:click_x1,y:click_y1,onComplete:check_end});//两个都要写onComplete,要不然就让其中一个运动时间长一点。
d_choose=!d_choose;
step+=1;
move_num_mc.m_num.text=step;
}
} |
最后是判断是否拼成功,这里没有用到两个数组是否相等的比较,因为两个数组的顺序不一样。这里是通过判断obj在两个数组中的x,y是否相同来判定的。
1
2
3
4
5
6
7
8
9
10
| private function check_end() {
end_test=0;//位置正确的个数,正确个数为数组长度时,拼图成功。
for (var i=0; i<d_arr.length; i++) {
(Math.floor(d_arr[i].obj.x)==d_arr[i].b_x)&&(Math.floor(d_arr[i].obj.y)==d_arr[i].b_y) ? end_test=end_test+1 : 0;
}
isend();
}
private function isend() {
end_test==d_arr.length ? win() : 0;
} |
源文件:puzzles.rar