为FIT CSS做了一个本地Nginx的Mock

前面已经介绍了FIT CSS的的思想,具体请看 http://foreplayer.net/?p=234。如果你本地没有复杂的服务器端环境,如何做静态http访问的测试呢,Ngnix提供了对URI的Rewrite方法,可以在Rewrite之前检查你所使用的user agent。你只要修改你的Ngnix.conf即可。代码如下:

#根据你个人资源位置修改
location /2.0prototype/css/{

#你本地的资源防止路径
root   D:/Framework/wwf;

#下面的很简单,不解释,虽然不好看,够用就行。
if ($http_user_agent ~* Firefox){
rewrite ^(.*)\.css$ $1-firefox.css break;
}

if ($http_user_agent ~* Chrome){
rewrite ^(.*)\.css$ $1-chrome.css break;
}
if ($http_user_agent ~* Safari){
rewrite ^(.*)\.css$ $1-safari.css break;
}

if ($http_user_agent ~* Opera){
rewrite ^(.*)\.css$ $1-opera.css break;
}

if ($http_user_agent ~* “MSIE 7.0″){
rewrite ^(.*)\.css$ $1-ie7.css break;
}

if ($http_user_agent ~* “MSIE 8.0″){
rewrite ^(.*)\.css$ $1-ie8.css break;
}

if ($http_user_agent ~* “MSIE 9.0″){
rewrite ^(.*)\.css$ $1-ie9.css break;
}

if ($http_user_agent ~* “MSIE 10.0″){
rewrite ^(.*)\.css$ $1-ie10.css break;
}
}

—EOF—

Web socket 协议研究

Summary
Web socket 是基于HTTP协议的长连接通信方式, 隶属HTML 5规范的一部分。不同于以往的无状态HTTP请求,web socket在第一握手完成之后将长期保持连接,直到客户端或服务器端有一方将连接断开。

使用web socket的益处在于:

  • 每个客户端有限的长链接
  • 避免每次请求都要重新建立TCP/IP的消耗
  • 由于连接长期存在,服务器端主动push数据到客户端成为可能
  • 避免每次问答都需要附加的HTTP协议

Web socket 连接建立方式
web socket仍然是基于TCP/IP连接,由客户端发起

FIT CSS的LESS实现

什么是FIT CSS?这是dongdong同志给按照不同浏览器的需要下载不同样式表的实现所下的一个定义。 FIT CSS的目标就是用户只会拿到自己需要的样式,减少数据的加载量。概念来自: http://www.conditional-css.com/index。举个例子进行简单的解释:
.box_shadow {
-webkit-box-shadow: 0px 0px 4px 0px #ffffff; /* Saf3-4, iOS 4.0.2 – 4.2, Android 2.3+ */
-moz-box-shadow: 0px 0px 4px 0px #ffffff; /* FF3.5 – 3.6 */
box-shadow: 0px 0px 4px 0px #ffffff; /* Opera 10.5, IE9, FF4+, Chrome 6+, iOS 5 */
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=3, Direction=135, Color=’#ffffff); /* IE8- */
}

按照以前的实现,我们需要把以上所有样式都写上确保所有浏览器都能比较好的工作,FIT的思路是把把上面的CSS内容分拆到不同的文件,比如客户端如果是使用的IE8,他所拿到的css名称会是style-ie8.css, 内容如下

.box_shadow {
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=3, Direction=135, Color=’#ffffff); /* IE8- */
}

这样代码会轻便许多。如果使用FIT CSS的里面,计会减少下载体积20%-30%。

昨天根据这种思想,尝试了一下LESS中的实现,我们会根据一份LESS文件产生不同后缀的CSS文件,比如:Style.less会产生style.css(此文件会包含所有定义), style-ie7.css, style-ie8.css, style-firefox.css, style-safari.css等。我们写LESS的时候只要在同一行内加上约定格式的注释就可以了。比如说上面的例子,可以改写成:

.box_shadow {
-webkit-box-shadow: 0px 0px 4px 0px #ffffff; //#safari#
-moz-box-shadow: 0px 0px 4px 0px #ffffff; //#firefox#
box-shadow: 0px 0px 4px 0px #ffffff; //标准CSS3属性,此处没有添加判断浏览器的注释,所有浏览器都保留
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=3, Direction=135, Color=’#ffffff); //#ie7# #ie8#
}

我们在改写LESS的编译器后可以的到如下文件:

1. style-safari.css
.box_shadow {
-webkit-box-shadow: 0px 0px 4px 0px #ffffff;
box-shadow: 0px 0px 4px 0px #ffffff;
}

2. style-firefox.css
.box_shadow {
-moz-box-shadow: 0px 0px 4px 0px #ffffff; //#firefox#
box-shadow: 0px 0px 4px 0px #ffffff;
}

3. style-ie7.css
.box_shadow {
box-shadow: 0px 0px 4px 0px #ffffff;
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=3, Direction=135, Color=’#ffffff);
}

4. style-ie8.css
.box_shadow {
box-shadow: 0px 0px 4px 0px #ffffff;
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=3, Direction=135, Color=’#ffffff);
}

5…

通过此编译方法我们不同客户端得到的CSS文件体积会大大减小。

下面说一下如何修改编译器,以Winless为例,编译器的工作原理是读取LESS源文件,通过less.js解析,然后写入到指定文件夹中。我们修改写入过程就可以了。Winless的安装目录有lessc.wsf文件,基于Jscript,非常容易修改,具体修改办法就不赘述了,主要是添加一个对象browsers,按照browsers对象属性值生成以此属性值为结尾的CSS文件,要做到这点,在核心方法convert()中添加一个参数传入浏览器名称就可以了。

var browsers = {
ie7      :   ‘ie7′,
ie8      :   ‘ie8′,
ie9      :   ‘ie9′,
ie10     :   ‘ie10′,
chrome   :   ‘chrome’,
firefox  :   ‘firefox’,
opera    :   ‘opera’,
safari   :   ‘safari’
}

因为对于一款浏览器我们需要删除不需要的那些带注释的浏览器的CSS属性,我们必须添加一个条件,通过正则表达式删除那些行就可以了,由于本人不熟悉正则表达式,费了一番功夫,还好最终搞定了。

if(platform){ //add platform selection
output = output.substr(0, output.length – 4) + ‘-’ + platform + ‘.css’;
var regStr = ”;
for (x in browsers){
if (browsers[x] === platform){
continue;
}
regStr = regStr + ‘#’ + browsers[x] + ‘#|’;
}
regStr = regStr.substr(0, regStr.length – 1);

regStr = ‘/^((?=.*?(‘ + regStr + ‘))(?!.*?(#’ + platform + ‘#))).*$/mg’;

var regex = eval(regStr);
data=data.replace(regex, ”);
}

到此,不同浏览器的不同CSS已经搞定,并且我们只用维护一份LESS文件,何其简单,剩下的就交给后端去处理就OK啦。

 

 

Zen-Coding: 超Zan的代码编辑工具

书写HTML/CSS代码,相信对于每个前端攻城师们都是一个“梦魇”,复杂而枯燥的语法,重复而单调的代码结构,一点点的在消磨着开发同学们的热情和耐心。。。好在Zen Coding 的横空出世,总算终结了这种纠结,让我们得以以一种无比帅气的方式书写代码~

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en”>

<head>

<meta http-equiv=”Content-Type” content=”text/html;charset=UTF-8″ />

<title></title>

</head>

<body>

 

</body>

</html>

这段代码大家都很熟悉,如果光靠手动来写,一晃几分钟的时间就过去了,而真正的内容却还没开始动工。。。。有了Zen Coding,你只需输入:html:xt,然后Ctrl + E (NotePad++中),接下来就是见证奇迹的时刻。。。

再举个例子:

<div id="header">

    <div id="logo"></div>

    <ul class="nav">

        <li class="item-1"><a href=""></a></li>

        <li class="item-2"><a href=""></a></li>

        <li class="item-3"><a href=""></a></li>

        <li class="item-4"><a href=""></a></li>

        <li class="item-5"><a href=""></a></li>

    </ul>

</div>

以前的时候,大家能做的就是拷贝、粘贴,然后再修改,这样的工作真是苦不堪言。。。 有了Zen Coding, 你只需:div#header>div#logo+ul.nav>li.item-$*5>a,同样的,使用代码展开快捷键,你将会很欣喜的看到一段格式化完美无缺的代码出现了,这种感觉是不是很爽?

什么?你觉得Zen Coding的语法看着眼熟?是的,你没看错,Zen Coding使用类似CSS选择器的语法规则来生成HTML文档,而这对于前端开发来说应该也算是轻车熟路了,而且Zen Coding所有的语法规则非常的少,大家只需学上几分钟,我保证基本上大多数的HTML网页都不在话下,真的是异常的犀利~~~

目前很多文本编辑器包括IDE,都增加了对Zen Coding的支持,著名的有:NotePad++、Sublime Text 2、WebStorm、Aptana等等,有的需要你安装插件,有的则在新版中已默认集成了该项功能,但是需要注意的是,不同的编辑器/IDE有不同的快捷键方式,所以同时使用多个工具的同学,在这方面需要稍微注意下。

以下是学习Zen Coding的几个较好的参考文章:

http://rpsh.net/archives/zen-coding-npp/

http://www.bwtx.org/others/tips/zen-coding-in-notepad-in-use.html

欲了解更多Zen Coding的知识,请自行google之。

Java Applet 之截屏

最近在研究基于Web的桌面共享,初步想法是通过Java applet实现定时截屏然后发送给页面的JS控件,JS控件通过Canvas来将图片生成到网页。这里最关键的问题就是截屏。
虽然没有系统的学过java,网上关于java的文章还是比较多的,随便搜搜就搜到了。网上基本都是通过Robot类来实现抓图的:

package manna.sharing;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

import netscape.javascript.JSObject;

public class CaptureScreen extends JFrame implements ActionListener {
	private Dimension screenSize = java.awt.Toolkit.getDefaultToolkit()
			.getScreenSize(); // 屏幕大小
	Robot robot;
	BufferedImage saveImage;
	Rectangle rct = new Rectangle(0, 0, screenSize.width, screenSize.height);

	public CaptureScreen() {
		setVisible(false);
		try {
			robot = new Robot(); // 初始化机器人
		} catch (AWTException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
	}

	public String captureFullScreen() {
		saveImage = robot.createScreenCapture(rct);//截屏
		String imgString = "";
		try {
			imgString = Util.ImageToBase64(saveImage);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return imgString;
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub

	}
}

这段代码在调试的时候都没问题,但作为applet插入到网页中却报安全错误!
这是由于applet本身安全机制的限制。我们可以通过给applet生成签名来解决。具体步骤大家可以在网上搜一下,操作比较复杂每次编译测试都要生成。。

原文地址:http://blog.thinkjs.net/archives/174

Winless 编译假成功怎么办?试试 “Crunch“!

最近玩Winless ,发现一个问题,每次都提示编译成功,但是CSS文件没更新。情急之中,忽闪一念,是不是该升级了,发现官网已经1.5了,迅速升级1.3 到1.5.3

Version: 1.5.3

顺便说一句 winless 的升级一点提示都没有,对于不喜欢被骚扰的同学,真的不错。不会像一些国内软件,三天两头提示升级。但是当有功能缺陷还是很有必要提示下的。

言归正传,升级到最新版仍然未果,换了一台机子仍仍然未果。崩溃。
基本能断定是软件的问题。很可能是它编译报错机制不全面导致 提示成功编译但是Less文件却没有被编译。

 

果断换Less客户端,说实话什么 SimpleLess, LESS2CSS,Less.app ,N多在线编辑。不是难用就是没GUI,要不就是非全自动(半自动不适合我这种懒人,你懂的),还有就是需要特殊系统支持。比如 Less.app 就需要苹果系统。还有些是在linux下跑的。

最后发现了Crunch 基于 Adobe Air的 Less 开发工具。集合编辑器和编译器于一身。还跨操作系统。官网 http://crunchapp.net/  很喜欢他logo的风格。大工具钳。

 

不过编辑器还处于原始的阶段,而且还要先装Air。关键是每集编辑都要按头顶硕大的Crunch IT!太费事了。

换用Crunch后迅速定位问题,发现是有个地方分号重复了。修改后编译成功。

 

迅速切回Winless,发现他也ok了。现在winless可以稳定使用了。 爽。还是Winless 好用,文件修改后自动编译。

1.5里编译速度明显变快。编译器错误处理做的再强大些就更好了。推荐Winless.

Java Applet 初探

Applet就像是IE的ActiveX控件,可以嵌入到网页中。Applet的开发很简单,只要从java.applet.Applet 类继承就可以了。
我们先来看个简单的例子:

import java.applet.Applet;
import java.awt.Graphics;
public class Helper extends Applet {
	public void paint(Graphics g)
	 {
		 g.drawString("hello world",10,10);
	 }
}

将这个文件编译成Helper.class然后通过下面的代码在页面中引用

<html>
  <head>
      <title>demo
  </head>
  <body>
      <h1>demo

      <hr>
      <applet code="Helper.class" width=400 height=400>
	Your browser is completely ignoring the <APPLET> tag!
      </applet>
      <hr>
  </body>
</html>

如果你需要跟Javascript交互需要引入netscape的JSObject包。

import java.applet.Applet;
import netscape.javascript.JSObject;
public class Helper extends Applet {
	public void init(){
		JSObject win=JSObject.getWindow(this);
		System.out.print("run applet");
		win.eval("alert(1);");
		win = null;
	}
}

通过JSObject.getWindow(this) 可以拿到window对象。然后通过win.getMember(“document”) 获取子对象。

win=JSObject.getWindow(this); // 获取JavaScript窗口句柄,引用当前文档窗口
doc=(JSObject)win.getMember("document"); // 访问JavaScript document对象
form=(JSObject)doc.getMember("textForm"); //访问JavaScript form对象
textField=(JSObject)form.getMember("textField");访问JavaScript text对象
text=(String) textField.getMember("value"); //获取文本区的值   

// 调用JavaScript的alert()方法
win.eval("alert(\"This alert comes from Java!\")");   

// 调用JavaScript的myFunction(message)方法
win.call("myFunction", new Object[]{"Hello"});//参数用数组的形势表示。

在使用JSObject的时候applet标签必须加上MAYSCRIPT属性

<html>
  <head>
      <title>demo
  </head>
  <body>
      <h1>demo

      <hr>
      <applet code="Helper.class" MAYSCRIPT width=400 height=400>
	Your browser is completely ignoring the <APPLET> tag!
      </applet>
      <hr>
  </body>
</html>

Demo 下载

更多详细信息请查看Java官方文档

Sass, 让你的css更简单

Sass, 没错, 咱说的不是Saas. 一个css的编译工具而已, 但是能让你的css写起来更加简单. Sass提供了让你在CSS里面使用变量, 嵌套, 选择器集成等能力. 以下示例简单明了的告诉你Sass  都能干些啥.

在CSS中使用变量

 

 

在CSS使用嵌套

在CSS中使用引用

 

在CSS中使用选择器继承

 

使用Sass语法写完的CSS文件需要保存为.scss. 使用Mac OS X的用户, 可以使用 gem install sass 安装Sass提供的CSS生成工具. 安装之后,使用

sass –watch style.scss:style.css

即可将style.scss转换为style.css, 并且Sass进程会监视之后style.css的任何修改, 并自动更新style.css. 对于多个样式文件,也可以使用

sass –watch stylesheets/sass:stylesheets/compiled

去监视一个目录. 当然, Sass也有Win对应的工具

http://rubyinstaller.org/download.html

 

慎用闭包谨防跨页面内存泄露

写Js的时候很多童鞋喜欢用闭包,其实闭包是非常危险的。我们先来看一个例子

<div id="bb"><div id="aa">cc</div></div>
<script type="text/javascript">
function leakTest(){
    var a=[];//用来加大闭包资源占用
    for(var i=0;i<100000;i++){
     a.push('a');
    }
    var divA=document.getElementById('aa');
    divA.test=function(){};
    divA.parentNode.removeChild(divA);
}
leakTest();
</script>

在IE下这个页面每次刷新都会产生跨页面泄露,内存占用每次增大了7MB!
在这个例子中我们在leakTest()中创建了一个内部匿名函数并在dom元素aa的自定义属性test中保存了他的引用,这就产生了一个闭包。
divA.parentNode.removeChild(divA);
这句是产生泄露的主要原因,移除了aa只不过是在dom树上将这个节点移出了,在闭包中的divA这个局部变量不会被释放,而divA中保存着aa的引用,这就形成了一个循环引用,闭包保存了dom元素aa的引用,dom元素aa的自定义属性test又保存了闭包内部的匿名函数的引用,所以在页面刷新的时候IE无法释放掉这个aa和闭包的资源,在我这个例子中就比较吓人,刷一下涨几MB内存

那么如何解决这个问题呢?其实很简单只要我们打断divA 与aa的连接就可以了

<div id="bb"><div id="aa">cc</div></div>
<script type="text/javascript">
function leakTest(){
    var a=[];//用来加大闭包资源占用
    for(var i=0;i<100000;i++){
     a.push('a');
    }
    var divA=document.getElementById('aa');
    divA.test=function(){};
    divA.parentNode.removeChild(divA);
    divA = null// fix memory leak
}
leakTest();
</script>

建议大家不要随意使用getElementById 这些原生的方法,最好使用jQuery object去操作dom 或存储dom,这样能减少因个人疏忽引起的内存泄漏。
毕竟内存泄漏对产品来说是非常严重的问题。

不要怪 Iphone 其实他是好心 (解决 Iphone下safari 网页字体随机放大问题 ,适用960分辨率一下 ios 设备。)

iphone 下的网页会 自己判断 放大一些文字 以便用户阅读。其实是很好的辅助功能。 但是带来的副作用是,有些过大的文字又会影响整个站点的美观。 所以 我们为了我们网站更漂亮。 加上这个吧。

body {-webkit-text-size-adjust:100%;}

iOS设备如(iphone、itouch)的分辨率是480×320(4代机器是960×640) 其实问题就出现在 小分辨率的 设备上 所以 做好加个 @media only screen and (max-device-width:960px){…}