<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>AskTest</title>
	<atom:link href="http://www.asktest.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.asktest.com/blog</link>
	<description>问测网</description>
	<lastBuildDate>Wed, 30 Jun 2010 05:29:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>代理服务器</title>
		<link>http://www.asktest.com/blog/?p=317</link>
		<comments>http://www.asktest.com/blog/?p=317#comments</comments>
		<pubDate>Wed, 30 Jun 2010 05:29:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[知识]]></category>

		<guid isPermaLink="false">http://www.asktest.com/blog/?p=317</guid>
		<description><![CDATA[代理服务器（英文：Proxy），是一种重要的电脑安全功能，也是特殊的网络服务，允许客户端通过它与另一个网络服务进行非直接的连接，也称“网络代理”。代理服务器有利于保障网络安全，防止攻击。
提供代理服务的计算机或其它类型的网络节点称为代理服务器（英文：Proxy Server），代理服务器中实现网络代理的软件称为“代理软件”。具体过程为：客户端首先与代理服务器建立连接，接着发出一个对另外的目标服务器的文件或其它资源的连接请求，代理服务器通过与目标服务器连接或从缓存中取得请求的资源，并返回给客户端。通常在这个过程中，代理服务器可能改变客户端请求或服务器端响应的一些内容以满足各种代理需要。
http://zh.wikipedia.org/zh-cn/代理服务器
常常会听到别人说，你的浏览器要设代理服务器(Proxy Server)，这样你上网的速度会比较快。到底什么是代理服务器，它在Internet里扮演什么样的角色?
    当使用者要向服务器要求资料时，假设使用者输入www.yahoo.com向 Yahoo索取资料时，在正常的网路流程中，当使用者的浏览器看到www.yahoo.com这个域名(Domain Name)时，会向域名解析服务器(DNS)寻找www.yahoo.com所对应的IP地址，当DNS传回对应的IP地址后，浏览器会再对这个Yahoo服务器索取资料，这看起来是没有问题的，但如果网络阻塞、网站的机器配备不好、网站的专线不够快等不良的因素通通加在一起后，你要连接的网站就会变的很慢，所以这个时候有一个叫代理服务器的东西，会把大家常常看的网页资料暂存在一个位置，这个位置的机器设备通常会很好，线路带宽会很大，所以用户读取的速度就会很快。
    当用户设了代理服务器时，浏览器在读取资料时，资料应该是如何传递的呢?相同的，浏览器会先向DNS查询IP地址，然后找到IP地址后，会先向代理服务器查询是否有这个网站的资料，如果有的话，代理服务器就直接把内容传给了用户，如果代理服务器没有资料的话，才会直接向网站要资料。
    代理服务器的主要功能有:
(1)设置用户验证和记帐功能，可按用户进行记帐，没有登记的用户无权通过代理服务器访问Internet网。并对用户的访问时间、访问地点、信息流量进行统计。
(2)对用户进行分级管理，设置不同用户的访问权限，对外界或内部的Internet地址进行过滤，设置不同的访问权限。
(3)增加缓冲器(Cache)，提高访问速度，对经常访问的地址创建缓冲区，大大提高热门站点的访问效率。通常代理服务器都设置一个较大的硬盘缓冲区(可能高达几个GB或更大)，当有外界的信息通过时，同时也将其保存到缓冲区中，当其他用户再访问相同的信息时，则直接由缓冲区中取出信息，传给用户，以提高访问速度。
(4)连接Internet与Internet，充当防火墙(Firewall):因为所有内部网的用户通过代理服务器访问外界时，只映射为一个 IP地址，所以外界不能直接访问到内部网；同时可以设置IP地址过滤，限制内部网对外部的访问权限。
(5)节省IP开销:代理服务器允许使用大量的伪IP地址，节约网上资源，即用代理服务器可以减少对IP地址的需求，对于使用局域网方式接入 Internet ，如果为局域网(LAN)内的每一个用户都申请一个IP地址，其费用可想而知。但使用代理服务器后，只需代理服务器上有一个合法的IP地址，LAN内其他用户可以使用10.*.*.*这样的私有IP地址，这样可以节约大量的IP，降低网络的维护成本。
]]></description>
			<content:encoded><![CDATA[<p>代理服务器（英文：Proxy），是一种重要的电脑安全功能，也是特殊的网络服务，允许客户端通过它与另一个网络服务进行非直接的连接，也称“网络代理”。代理服务器有利于保障网络安全，防止攻击。</p>
<p>提供代理服务的计算机或其它类型的网络节点称为代理服务器（英文：Proxy Server），代理服务器中实现网络代理的软件称为“代理软件”。具体过程为：客户端首先与代理服务器建立连接，接着发出一个对另外的目标服务器的文件或其它资源的连接请求，代理服务器通过与目标服务器连接或从缓存中取得请求的资源，并返回给客户端。通常在这个过程中，代理服务器可能改变客户端请求或服务器端响应的一些内容以满足各种代理需要。<br />
<a href="http://zh.wikipedia.org/zh-cn/代理服务器">http://zh.wikipedia.org/zh-cn/代理服务器</a></p>
<p>常常会听到别人说，你的浏览器要设代理服务器(Proxy Server)，这样你上网的速度会比较快。到底什么是代理服务器，它在Internet里扮演什么样的角色?</p>
<p>    当使用者要向服务器要求资料时，假设使用者输入www.yahoo.com向 Yahoo索取资料时，在正常的网路流程中，当使用者的浏览器看到www.yahoo.com这个域名(Domain Name)时，会向域名解析服务器(DNS)寻找www.yahoo.com所对应的IP地址，当DNS传回对应的IP地址后，浏览器会再对这个Yahoo服务器索取资料，这看起来是没有问题的，但如果网络阻塞、网站的机器配备不好、网站的专线不够快等不良的因素通通加在一起后，你要连接的网站就会变的很慢，所以这个时候有一个叫代理服务器的东西，会把大家常常看的网页资料暂存在一个位置，这个位置的机器设备通常会很好，线路带宽会很大，所以用户读取的速度就会很快。</p>
<p>    当用户设了代理服务器时，浏览器在读取资料时，资料应该是如何传递的呢?相同的，浏览器会先向DNS查询IP地址，然后找到IP地址后，会先向代理服务器查询是否有这个网站的资料，如果有的话，代理服务器就直接把内容传给了用户，如果代理服务器没有资料的话，才会直接向网站要资料。</p>
<p>    代理服务器的主要功能有:</p>
<p>(1)设置用户验证和记帐功能，可按用户进行记帐，没有登记的用户无权通过代理服务器访问Internet网。并对用户的访问时间、访问地点、信息流量进行统计。</p>
<p>(2)对用户进行分级管理，设置不同用户的访问权限，对外界或内部的Internet地址进行过滤，设置不同的访问权限。</p>
<p>(3)增加缓冲器(Cache)，提高访问速度，对经常访问的地址创建缓冲区，大大提高热门站点的访问效率。通常代理服务器都设置一个较大的硬盘缓冲区(可能高达几个GB或更大)，当有外界的信息通过时，同时也将其保存到缓冲区中，当其他用户再访问相同的信息时，则直接由缓冲区中取出信息，传给用户，以提高访问速度。</p>
<p>(4)连接Internet与Internet，充当防火墙(Firewall):因为所有内部网的用户通过代理服务器访问外界时，只映射为一个 IP地址，所以外界不能直接访问到内部网；同时可以设置IP地址过滤，限制内部网对外部的访问权限。</p>
<p>(5)节省IP开销:代理服务器允许使用大量的伪IP地址，节约网上资源，即用代理服务器可以减少对IP地址的需求，对于使用局域网方式接入 Internet ，如果为局域网(LAN)内的每一个用户都申请一个IP地址，其费用可想而知。但使用代理服务器后，只需代理服务器上有一个合法的IP地址，LAN内其他用户可以使用10.*.*.*这样的私有IP地址，这样可以节约大量的IP，降低网络的维护成本。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.asktest.com/blog/?feed=rss2&amp;p=317</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>hosts 文件的作用</title>
		<link>http://www.asktest.com/blog/?p=315</link>
		<comments>http://www.asktest.com/blog/?p=315#comments</comments>
		<pubDate>Wed, 30 Jun 2010 04:58:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[知识]]></category>

		<guid isPermaLink="false">http://www.asktest.com/blog/?p=315</guid>
		<description><![CDATA[很多用户都知道在Window系统中有个Hosts文件（没有后缀名），在Windows98系统下该文件在Windows目录，在 Windows2000/XP系统中位于C:\Winnt\System32\Drivers\Etc 目录中。该文件其实是一个纯文本的文件，用普通的文本编辑软件如记事本等都能打开。
用记事本打开hosts文件，首先看见了微软对这个文件的说明。这个文件是根据TCP/IPforWindows的标准来工作的，它的作用是包含 IP地址和Host name(主机名)的映射关系，是一个映射IP地址和Hostname(主机名)的规定，规定要求每段只能包括一个映射关系，IP地址要放在每段的最前面，空格后再写上映射的Host name(主机名)。对于这段的映射说明用“#”分割后用文字说明。
现在让我们来看看Hosts在Windows中是怎么工作的。
    我们知道在网络上访问网站，要首先通过DNS服务器把网络域名（www.XXXX.com）解析成61.XXX.XXX.XXX的IP地址后，我们的计算机才能访问。要是对于每个域名请求我们都要等待域名服务器解析后返回IP信息，这样访问网络的效率就会降低，而Hosts文件就能提高解析效率。根据 Windows系统规定，在进行DNS请求以前，Windows系统会先检查自己的Hosts文件中是否有这个地址映射关系，如果有则调用这个IP地址映射，如果没有再向已知的DNS 服务器提出域名解析。也就是说Hosts的请求级别比DNS高。
    知道了Hosts文件的工作方式，那在具体使用中它有哪些作用呢?
    1、加快域名解析
    对于要经常访问的网站，我们可以通过在Hosts中配置域名和IP的映射关系，这样当我们输入域名计算机就能很快解析出IP，而不用请求网络上的DNS服务器。
    2、方便局域网用户
    在很多单位的局域网中，会有服务器提供给用户使用。但由于局域网中一般很少架设DNS服务器，访问这些服务要输入难记的IP地址，对不少人来说相当麻烦。现在可以分别给这些服务器取个容易记住的名字，然后在Hosts中建立IP映射，这样以后访问的时候我们输入这个服务器的名字就行了。
    3、屏蔽网站
    现在有很多网站不经过用户同意就将各种各样的插件安装到你的计算机中，有些说不定就是木马或病毒。对于这些网站我们可以利用Hosts把该网站的域名映射到错误的IP或自己计算机的IP，这样就不用访问了。我们在Hosts写上以下内容：
    127.0.0.1#屏蔽的网站
0.0.0.0#屏蔽的网站
    这样计算机解析域名就解析到本机或错误的IP，达到了屏蔽的目的。
    4、顺利连接系统
    [...]]]></description>
			<content:encoded><![CDATA[<p>很多用户都知道在Window系统中有个Hosts文件（没有后缀名），在Windows98系统下该文件在Windows目录，在 Windows2000/XP系统中位于C:\Winnt\System32\Drivers\Etc 目录中。该文件其实是一个纯文本的文件，用普通的文本编辑软件如记事本等都能打开。</p>
<p>用记事本打开hosts文件，首先看见了微软对这个文件的说明。这个文件是根据TCP/IPforWindows的标准来工作的，它的作用是包含 IP地址和Host name(主机名)的映射关系，是一个映射IP地址和Hostname(主机名)的规定，规定要求每段只能包括一个映射关系，IP地址要放在每段的最前面，空格后再写上映射的Host name(主机名)。对于这段的映射说明用“#”分割后用文字说明。</p>
<p>现在让我们来看看Hosts在Windows中是怎么工作的。</p>
<p>    我们知道在网络上访问网站，要首先通过DNS服务器把网络域名（www.XXXX.com）解析成61.XXX.XXX.XXX的IP地址后，我们的计算机才能访问。要是对于每个域名请求我们都要等待域名服务器解析后返回IP信息，这样访问网络的效率就会降低，而Hosts文件就能提高解析效率。根据 Windows系统规定，在进行DNS请求以前，Windows系统会先检查自己的Hosts文件中是否有这个地址映射关系，如果有则调用这个IP地址映射，如果没有再向已知的DNS 服务器提出域名解析。也就是说Hosts的请求级别比DNS高。</p>
<p>    知道了Hosts文件的工作方式，那在具体使用中它有哪些作用呢?</p>
<p>    1、加快域名解析</p>
<p>    对于要经常访问的网站，我们可以通过在Hosts中配置域名和IP的映射关系，这样当我们输入域名计算机就能很快解析出IP，而不用请求网络上的DNS服务器。</p>
<p>    2、方便局域网用户</p>
<p>    在很多单位的局域网中，会有服务器提供给用户使用。但由于局域网中一般很少架设DNS服务器，访问这些服务要输入难记的IP地址，对不少人来说相当麻烦。现在可以分别给这些服务器取个容易记住的名字，然后在Hosts中建立IP映射，这样以后访问的时候我们输入这个服务器的名字就行了。</p>
<p>    3、屏蔽网站</p>
<p>    现在有很多网站不经过用户同意就将各种各样的插件安装到你的计算机中，有些说不定就是木马或病毒。对于这些网站我们可以利用Hosts把该网站的域名映射到错误的IP或自己计算机的IP，这样就不用访问了。我们在Hosts写上以下内容：</p>
<p>    127.0.0.1#屏蔽的网站<br />
0.0.0.0#屏蔽的网站</p>
<p>    这样计算机解析域名就解析到本机或错误的IP，达到了屏蔽的目的。</p>
<p>    4、顺利连接系统</p>
<p>    对于Lotus的服务器和一些数据库服务器，在访问时如果直接输入IP地址那是不能访问的，只能输入服务器名才能访问。那么我们配置好Hosts文件，这样输入服务器名就能顺利连接了。</p>
<p>    最后要指出的是，Hosts文件配置的映射是静态的，如果网络上的计算机更改了请及时更新IP地址，否则将不能访问。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.asktest.com/blog/?feed=rss2&amp;p=315</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>招聘：Flex工程师/UI设计/J2EE软件开发工程师(猎头职位)</title>
		<link>http://www.asktest.com/blog/?p=309</link>
		<comments>http://www.asktest.com/blog/?p=309#comments</comments>
		<pubDate>Mon, 24 May 2010 06:41:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[招聘]]></category>

		<guid isPermaLink="false">http://www.asktest.com/blog/?p=309</guid>
		<description><![CDATA[岗位名称：J2EE软件开发工程师
角色介绍：本岗位招聘J2EE软件开发工程师，应聘人主要从事基于J2EE架构的软件开发工作
岗位职责：
1、分析软件的架构，理解软件的设计思路
2、完成软件功能的详细设计
3、实现项目任务的编码
4、编写单元测试用例
5、处理相关bug
6、对实施现场发生的问题及时定位并处理
需要的技能和素质：
1、大学本科及以上学历，计算机,通信相关专业优先;
2、具有3年以上的j2ee应用开发经验；具有2年以上ejb应用的设计经验,熟悉TCP/IP相关协议;
3、熟练掌握Java语言，熟练掌握面向对象的开发方法;
4、精通j2ee架构，精通jboss/weblogic/websphere至少一种，精通Hibernate;
5、熟练掌握SQL Server、Oracle、DB2、Mysql、Postgresql至少其中一种数据库，能独立书写相关的DDL和DML，以及存储过程;
6、计算机网络基础知识扎实，熟悉Snmp协议;
7、具有较强的学习、分析问题解决问题的能力;
8、具有良好的团队合作精神和与人沟通的能力;
9、具有良好的英语读写能力。
工作地点：北京
岗位名称：Flex工程师
角色介绍：
本岗位招聘Flex工程师，应聘人主要从事Flex前台界面实现、进行Flex与后台的数据交互编程
岗位职责：
1、依据需求设计操作界面
2、根据界面原型完成相关的前台编码
3、分析软件的架构，理解软件的设计思路
4、编写单元测试用例
5、处理相关bug
6、优化软件界面，改进用户体验
7、负责撰写相关技术文档
需要的技能和素质：
1、大学本科及以上学历，计算机,通信相关专业优先;
2、精通Flex,AS3,对UI设计有较深的认识;
3、熟练掌握Java语言，熟练掌握面向对象的开发方法;
4、具有较强的学习、分析问题解决问题的能力；
5、具有良好的团队合作精神和与人沟通的能力；
6、具有良好的英语读写能力；
7、熟悉IP网络相关知识/设计模式
工作地点：北京
岗位名称：UI设计专家
角色介绍：
本岗位招聘UI设计总监。应聘人主要从事软件产品的交互设计，同时兼顾界面风格设计，图标设计，Flex页面布局设计，flash动画的实现等。
职责：
1.负责软件产品的用户界面设计，交互设计，图标设计，界面风格的控制
2.设计效果图切片，软件的访问控制率控制；
3.Flex页面的实现，编写css控制页面布局与风格；
4.flash动画效果制作；
5.软件产品界面操作主线文档的写作；
6.配合优化现有产品的用户体验
需要的技能和素质：
1、精通设计相关软件：如Photoshop、Dreamweaver等
2、熟悉flash、Illustrator、Flex等技术
2、具有创意思维，注重用户体验，有很强的创造力。
3、美术或艺术设计相关专业.
4、两年年以上从事应用软件界面设计的工作经验.
5、有较强的学习能力，工作积极主动，有较强的责任心及良好的团队合作精神；
发简历时请附带作品。
工作地点：北京
简历投递邮箱：emma18study#gmail.com
]]></description>
			<content:encoded><![CDATA[<p>岗位名称：J2EE软件开发工程师<br />
角色介绍：本岗位招聘J2EE软件开发工程师，应聘人主要从事基于J2EE架构的软件开发工作</p>
<p>岗位职责：<br />
1、分析软件的架构，理解软件的设计思路<br />
2、完成软件功能的详细设计<br />
3、实现项目任务的编码<br />
4、编写单元测试用例<br />
5、处理相关bug<br />
6、对实施现场发生的问题及时定位并处理</p>
<p>需要的技能和素质：<br />
1、大学本科及以上学历，计算机,通信相关专业优先;<br />
2、具有3年以上的j2ee应用开发经验；具有2年以上ejb应用的设计经验,熟悉TCP/IP相关协议;<br />
3、熟练掌握Java语言，熟练掌握面向对象的开发方法;<br />
4、精通j2ee架构，精通jboss/weblogic/websphere至少一种，精通Hibernate;<br />
5、熟练掌握SQL Server、Oracle、DB2、Mysql、Postgresql至少其中一种数据库，能独立书写相关的DDL和DML，以及存储过程;<br />
6、计算机网络基础知识扎实，熟悉Snmp协议;<br />
7、具有较强的学习、分析问题解决问题的能力;<br />
8、具有良好的团队合作精神和与人沟通的能力;<br />
9、具有良好的英语读写能力。</p>
<p>工作地点：北京</p>
<p>岗位名称：Flex工程师<br />
角色介绍：<br />
本岗位招聘Flex工程师，应聘人主要从事Flex前台界面实现、进行Flex与后台的数据交互编程</p>
<p>岗位职责：<br />
1、依据需求设计操作界面<br />
2、根据界面原型完成相关的前台编码<br />
3、分析软件的架构，理解软件的设计思路<br />
4、编写单元测试用例<br />
5、处理相关bug<br />
6、优化软件界面，改进用户体验<br />
7、负责撰写相关技术文档</p>
<p>需要的技能和素质：<br />
1、大学本科及以上学历，计算机,通信相关专业优先;<br />
2、精通Flex,AS3,对UI设计有较深的认识;<br />
3、熟练掌握Java语言，熟练掌握面向对象的开发方法;<br />
4、具有较强的学习、分析问题解决问题的能力；<br />
5、具有良好的团队合作精神和与人沟通的能力；<br />
6、具有良好的英语读写能力；<br />
7、熟悉IP网络相关知识/设计模式</p>
<p>工作地点：北京</p>
<p>岗位名称：UI设计专家<br />
角色介绍：<br />
本岗位招聘UI设计总监。应聘人主要从事软件产品的交互设计，同时兼顾界面风格设计，图标设计，Flex页面布局设计，flash动画的实现等。</p>
<p>职责：<br />
1.负责软件产品的用户界面设计，交互设计，图标设计，界面风格的控制<br />
2.设计效果图切片，软件的访问控制率控制；<br />
3.Flex页面的实现，编写css控制页面布局与风格；<br />
4.flash动画效果制作；<br />
5.软件产品界面操作主线文档的写作；<br />
6.配合优化现有产品的用户体验</p>
<p>需要的技能和素质：<br />
1、精通设计相关软件：如Photoshop、Dreamweaver等<br />
2、熟悉flash、Illustrator、Flex等技术<br />
2、具有创意思维，注重用户体验，有很强的创造力。<br />
3、美术或艺术设计相关专业.<br />
4、两年年以上从事应用软件界面设计的工作经验.<br />
5、有较强的学习能力，工作积极主动，有较强的责任心及良好的团队合作精神；</p>
<p>发简历时请附带作品。</p>
<p>工作地点：北京</p>
<p>简历投递邮箱：emma18study#gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.asktest.com/blog/?feed=rss2&amp;p=309</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript 7 个全局函数</title>
		<link>http://www.asktest.com/blog/?p=307</link>
		<comments>http://www.asktest.com/blog/?p=307#comments</comments>
		<pubDate>Mon, 17 May 2010 02:40:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.asktest.com/blog/?p=307</guid>
		<description><![CDATA[ JavaScript 中包含以下 7 个全局函数，用于完成一些常用的功能（以后的章节中可能会用到）：escape( )、eval( )、isFinite( )、isNaN( )、parseFloat( )、parseInt( )、unescape( )。
1.　escape( )
escape( ) 函数以一个 string 对象或表达式为参数并返回一个 string 对象。参数指定的字符串中的所有非字母字符被转换成以 XX% 表示的等价数字，XX 是一个表示非字母字符的十六进制数。
以下示例显示了 escape( ) 函数的作用。

&#60;script type=&#34;text/javascript&#34;&#62;
window.onload = function(){
var escapeString=escape(&#34;Ask &#38; Test com&#34;);
document.write(escapeString);
}&#60;/script&#62;

  提示：你可以先修改部分代码再运行。

说明：在以上示例中，空格被 %20 代替，&#038; 被 %26 代替。
2.　eval( )
eval( ) 函数将通过参数传入的一个包含 JavaScript 语句的字符串作为一个 JavaScript 源代码执行。eval ( ) 返回执行 JavaScript 语句的返回值。
例如，在编写跨浏览器代码时，可以使用以下代码段：

&#60;script type=&#34;text/javascript&#34;&#62;
window.onload = function(){
eval(&#34;for(var i [...]]]></description>
			<content:encoded><![CDATA[<p> JavaScript 中包含以下 7 个全局函数，用于完成一些常用的功能（以后的章节中可能会用到）：escape( )、eval( )、isFinite( )、isNaN( )、parseFloat( )、parseInt( )、unescape( )。</p>
<p>1.　escape( )</p>
<p>escape( ) 函数以一个 string 对象或表达式为参数并返回一个 string 对象。参数指定的字符串中的所有非字母字符被转换成以 XX% 表示的等价数字，XX 是一个表示非字母字符的十六进制数。</p>
<p>以下示例显示了 escape( ) 函数的作用。</p>
<div class="runcode">
<p><textarea name="runcode" class="runcode_text" id="runcode_qyis_l">&lt;script type=&quot;text/javascript&quot;&gt;
window.onload = function(){
var escapeString=escape(&quot;Ask &amp; Test com&quot;);
document.write(escapeString);
}&lt;/script&gt;
</textarea></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode_open_new('runcode_qyis_l');"/> <input type="button" value="复制" class="runcode_button" onclick="runcode_copy('runcode_qyis_l');"/> 提示：你可以先修改部分代码再运行。</p>
</div>
<p>说明：在以上示例中，空格被 %20 代替，&#038; 被 %26 代替。</p>
<p>2.　eval( )</p>
<p>eval( ) 函数将通过参数传入的一个包含 JavaScript 语句的字符串作为一个 JavaScript 源代码执行。eval ( ) 返回执行 JavaScript 语句的返回值。</p>
<p>例如，在编写跨浏览器代码时，可以使用以下代码段：</p>
<div class="runcode">
<p><textarea name="runcode" class="runcode_text" id="runcode_RnHqTw">&lt;script type=&quot;text/javascript&quot;&gt;
window.onload = function(){
eval(&quot;for(var i in window){document.write(window[i]+'&lt;br/&gt;')}&quot;);
}&lt;/script&gt;
</textarea></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode_open_new('runcode_RnHqTw');"/> <input type="button" value="复制" class="runcode_button" onclick="runcode_copy('runcode_RnHqTw');"/> 提示：你可以先修改部分代码再运行。</p>
</div>
<p>3.　isFinite( )</p>
<p>isFinite ( ) 函数用于确定一个变量是否有界，如果有界则返回 true，否则返回 false。所谓有界是指表达式的值界于 MAX_VALUE 和 MIN_VALUE 之间。</p>
<p>以下示例显示了 isFinite( ) 函数的作用。</p>
<div class="runcode">
<p><textarea name="runcode" class="runcode_text" id="runcode_BwyfwZ">&lt;script type=&quot;text/javascript&quot;&gt;
window.onload = function(){
document.write(&quot;isFinite(12)=&quot;+isFinite(12)+&quot;&lt;BR&gt;&quot;);
document.write(&quot;isFinite(1.2)=&quot;+isFinite(1.2)+&quot;&lt;BR&gt;&quot;);
document.write(&quot;isFinite('a')=&quot;+isFinite('a')+&quot;&lt;BR&gt;&quot;)
document.write(&quot;isFinite(true)=&quot;+isFinite(true)+&quot;&lt;BR&gt;&quot;)
document.write(&quot;isFinite(null)=&quot;+isFinite(null))
}&lt;/script&gt;
</textarea></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode_open_new('runcode_BwyfwZ');"/> <input type="button" value="复制" class="runcode_button" onclick="runcode_copy('runcode_BwyfwZ');"/> 提示：你可以先修改部分代码再运行。</p>
</div>
<p>4.　isNaN( )</p>
<p>isNaN( ) 函数用于确定一个变量是否是 NaN，如果是，则返回 true，否则返回 false。NaN 代表 Not a Number，表示非数，即不是任何数。</p>
<p>例如，isNaN(12) 返回 false，isNaN(&#8217;a') 返回 true，isNaN(true) 返回 false（因为此时 true 被当作数字 1）。</p>
<p>5.　parseFloat( )</p>
<p>parseFloat( ) 函数用于将字符串开头的整数或浮点数分解出来，若字符串不是以数字开头，则返回 NaN。</p>
<p>以下示例显示了 parseFloat( ) 函数的用法。</p>
<p>6.　parseInt( )</p>
<p>parseInt( ) 函数与 parseFloat( ) 函数类似，用于将字符串开头的整数分解出来，若字符串不是以数字开头，则返回 NaN。</p>
<p>例如，如果将刚才的 parseFloat( ) 函数示例中的所有 parseFloat 都用 parseInt 代替。</p>
<p>7.　unescape( )</p>
<p>unescape( ) 函数将参数传递来的字符串中的十六进制码转换成 ASCII 码并返回，它完成 escape( ) 函数的逆操作。例如，unescape(&#8221;Tom%20%26%20and%20Jerry%20show&#8221;) 的返回值为 &#8220;Tom &#038; Jerry show&#8221;。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.asktest.com/blog/?feed=rss2&amp;p=307</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>javascript动态加载css,js</title>
		<link>http://www.asktest.com/blog/?p=299</link>
		<comments>http://www.asktest.com/blog/?p=299#comments</comments>
		<pubDate>Fri, 14 May 2010 09:15:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[dynamicLoad]]></category>

		<guid isPermaLink="false">http://www.asktest.com/blog/?p=299</guid>
		<description><![CDATA[javascript动态加载css,js
正常情况下，文件会被写到head区域，不管本页面用得到用不到就要加载，这种方式会造成一次性请求数过多加大block的时间，也容易造成文件字节过大。延迟加载的方案是通过js在dom需要的位置load文件，比如一些需要用户触发才展示的组件，日历选择，弹出框等。


&#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Transitional//EN&#34; &#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#34;&#62;
&#60;html xmlns=&#34;http://www.w3.org/1999/xhtml&#34;&#62;
&#60;head&#62;
&#60;meta content=&#34;text/html; charset=utf-8&#34; http-equiv=&#34;Content-Type&#34; /&#62;
&#60;title&#62;javascript动态加载css,js&#60;/title&#62;
&#60;style type=&#34;text/css&#34;&#62;*{margin:0;padding:0;}&#60;/style&#62;
&#60;script type=&#34;text/javascript&#34;&#62;
function extend(destination,source){for(var property in source){destination[property]=source[property]};return destination};var Class={create:function(){return function(){this.initialize.apply(this,arguments)}}};var loadFile=new Class.create();loadFile.prototype={initialize:function(options){this.SetOptions(options);this.Load()},SetOptions:function(options){this.options={src:'',type:'',hasLoad:0,callBack:function(){},cache:{}};extend(this.options,options&#124;&#124;{})},Load:function(){var type=this.getType(),dynamicObj,self=this;if(type=='js'){if(this.hasLoad())return;dynamicObj=document.createElement(&#34;script&#34;);dynamicObj.src=this.options.src;dynamicObj.type=&#34;text/javascript&#34;;document.getElementsByTagName(&#34;head&#34;)[0].appendChild(dynamicObj);if(-[1,]){dynamicObj.onload=function(){self.options.hasLoad=1;self.options.callBack()}}else{dynamicObj.onreadystatechange=function(){if(dynamicObj.readyState=='loaded'&#124;&#124;dynamicObj.readyState=='complete'){self.options.hasLoad=1}}}}else if(type=='css'){if(this.options.cache[encodeURIComponent(this.options.src)])return;this.cssMark();dynamicObj=document.createElement(&#34;link&#34;);dynamicObj.rel=&#34;stylesheet&#34;;dynamicObj.type=&#34;text/css&#34;;dynamicObj.href=this.options.src;document.getElementsByTagName(&#34;head&#34;)[0].appendChild(dynamicObj)}},hasLoad:function(){return this.options.hasLoad},getType:function(){var lastIndex=this.options.src.lastIndexOf(&#34;.&#34;);if(lastIndex!=-1){this.options.type=this.options.src.substr(lastIndex+1)};return this.options.type},cssMark:function(){var obj={};obj.file=this.options.src;obj.isLoaded=true;this.options.cache[encodeURIComponent(this.options.src)]=obj}};
window.onload = function(){
	document.getElementById('bb').onclick = function(){
	var sss = new loadFile({src:'http://www.asktest.com/blog/wp-content/themes/WPINK/js/jquery.js',callBack:function(){$('#bb').fadeOut(&#34;slow&#34;);}});
	var sss2 = new loadFile({src:'http://www.asktest.com/reset.css'});
	var sss2 = new loadFile({src:'http://www.asktest.com/tjubao.css'});
	}
}
&#60;/script&#62;
 &#60;/head&#62;
 &#60;body&#62;
&#60;!--[if IE]&#62;
&#60;script&#62;
var html5Tags=['header' ,'footer','article','nav' ,'section','aside']
for(var i=0;i&#60;html5Tags.length;i++){
   [...]]]></description>
			<content:encoded><![CDATA[<p><strong>javascript动态加载css,js</strong><br />
正常情况下，文件会被写到head区域，不管本页面用得到用不到就要加载，这种方式会造成一次性请求数过多加大block的时间，也容易造成文件字节过大。延迟加载的方案是通过js在dom需要的位置load文件，比如一些需要用户触发才展示的组件，日历选择，弹出框等。</p>
<div class="runcode">
<p><textarea name="runcode" class="runcode_text" id="runcode_inIXV7">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta content=&quot;text/html; charset=utf-8&quot; http-equiv=&quot;Content-Type&quot; /&gt;
&lt;title&gt;javascript动态加载css,js&lt;/title&gt;
&lt;style type=&quot;text/css&quot;&gt;*{margin:0;padding:0;}&lt;/style&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function extend(destination,source){for(var property in source){destination[property]=source[property]};return destination};var Class={create:function(){return function(){this.initialize.apply(this,arguments)}}};var loadFile=new Class.create();loadFile.prototype={initialize:function(options){this.SetOptions(options);this.Load()},SetOptions:function(options){this.options={src:'',type:'',hasLoad:0,callBack:function(){},cache:{}};extend(this.options,options||{})},Load:function(){var type=this.getType(),dynamicObj,self=this;if(type=='js'){if(this.hasLoad())return;dynamicObj=document.createElement(&quot;script&quot;);dynamicObj.src=this.options.src;dynamicObj.type=&quot;text/javascript&quot;;document.getElementsByTagName(&quot;head&quot;)[0].appendChild(dynamicObj);if(-[1,]){dynamicObj.onload=function(){self.options.hasLoad=1;self.options.callBack()}}else{dynamicObj.onreadystatechange=function(){if(dynamicObj.readyState=='loaded'||dynamicObj.readyState=='complete'){self.options.hasLoad=1}}}}else if(type=='css'){if(this.options.cache[encodeURIComponent(this.options.src)])return;this.cssMark();dynamicObj=document.createElement(&quot;link&quot;);dynamicObj.rel=&quot;stylesheet&quot;;dynamicObj.type=&quot;text/css&quot;;dynamicObj.href=this.options.src;document.getElementsByTagName(&quot;head&quot;)[0].appendChild(dynamicObj)}},hasLoad:function(){return this.options.hasLoad},getType:function(){var lastIndex=this.options.src.lastIndexOf(&quot;.&quot;);if(lastIndex!=-1){this.options.type=this.options.src.substr(lastIndex+1)};return this.options.type},cssMark:function(){var obj={};obj.file=this.options.src;obj.isLoaded=true;this.options.cache[encodeURIComponent(this.options.src)]=obj}};
window.onload = function(){
	document.getElementById('bb').onclick = function(){
	var sss = new loadFile({src:'http://www.asktest.com/blog/wp-content/themes/WPINK/js/jquery.js',callBack:function(){$('#bb').fadeOut(&quot;slow&quot;);}});
	var sss2 = new loadFile({src:'http://www.asktest.com/reset.css'});
	var sss2 = new loadFile({src:'http://www.asktest.com/tjubao.css'});
	}
}
&lt;/script&gt;
 &lt;/head&gt;
 &lt;body&gt;
&lt;!--[if IE]&gt;
&lt;script&gt;
var html5Tags=['header' ,'footer','article','nav' ,'section','aside']
for(var i=0;i&lt;html5Tags.length;i++){
    document.createElement(html5Tags[i]);
}
&lt;/script&gt;
&lt;![endif]--&gt;
&lt;div style=&quot;text-align:center;&quot;&gt;
&lt;button id=&quot;bb&quot; title=&quot;点击动态加载&quot;&gt;动态加载&lt;/button&gt;
&lt;/div&gt;
&lt;header&gt;&lt;h1&gt;个人简历&lt;/h1&gt;&lt;/header&gt;
&lt;section id=&quot;wrapper&quot;&gt;
&lt;section&gt;
&lt;h3&gt;个人简介:&lt;/h3&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;姓名:&lt;/span&gt;田聚宝 &lt;/li&gt;
&lt;li&gt;&lt;span&gt;教育经历:&lt;/span&gt;南阳理工学院-----计算机图形图象制作技术 | 大专 &lt;/li&gt;
&lt;li&gt;&lt;span&gt;出生日期:&lt;/span&gt;1984年7月 &lt;/li&gt;
&lt;li&gt;&lt;span&gt;联系方式:&lt;/span&gt;13488881765 &lt;/li&gt;
&lt;li&gt;&lt;span&gt;个人网站:&lt;/span&gt;&lt;a href=&quot;http://www.asktest.com/blog/&quot; target=&quot;_blank&quot;&gt;http://www.asktest.com/blog/&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href=&quot;http://www.asktest.com/focus.html&quot;&gt;平时关注的&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;职业技能:&lt;/span&gt;
&lt;ol&gt;
&lt;li&gt;1.精通css,xhtml;&lt;/li&gt;
&lt;li&gt;2.熟悉各种主流浏览器的CSS兼容性问题的解决方法;&lt;/li&gt;
&lt;li&gt;3.对Web标准和标签语义化有深入理解，理解表现(css)、结构(html)、行为(behavior)分离;&lt;/li&gt;
&lt;li style=&quot;display:none;&quot;&gt;5. 掌握JavaScript语言核心技术如DOM、BOM、Ajax、JSON等，对JavaScript框架如mootools、JQuery等有一定的应用经验；&lt;/li&gt;
&lt;li&gt;4.熟练掌握javascript,熟悉js框架（mootools,jquery,prototype);&lt;/li&gt;
&lt;li&gt;5. 对CSS/JavaScript性能操作有一定了解;&lt;/li&gt;
&lt;li&gt;6.熟悉php和mysql以及smarty模板&lt;/li&gt;
&lt;li&gt;7.对可用性、可访问性等相关知识有实际的了解和实践经验;&lt;/li&gt;
&lt;li&gt;8.熟悉前端代码对seo的影响。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;自我评价:&lt;/span&gt;成功属于一直坚持的人，因为对理想的执着所以我会做的更好！ &lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
 &lt;/body&gt;
&lt;/html&gt;
</textarea></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode_open_new('runcode_inIXV7');"/> <input type="button" value="复制" class="runcode_button" onclick="runcode_copy('runcode_inIXV7');"/> 提示：你可以先修改部分代码再运行。</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.asktest.com/blog/?feed=rss2&amp;p=299</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Template JST模板引擎</title>
		<link>http://www.asktest.com/blog/?p=295</link>
		<comments>http://www.asktest.com/blog/?p=295#comments</comments>
		<pubDate>Fri, 14 May 2010 08:24:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.asktest.com/blog/?p=295</guid>
		<description><![CDATA[Trimpath JavaScript 是个轻量级的，基于JavaScript的，跨浏览器，采用APL/GPL开放源代码协议的，可以让你轻松进行基于模板编程方式的纯JS引擎。
它有如下的特点：
1、采用标准的JavaScript编写，支持跨浏览器
2、模板语法类似于：FreeMarker，Velocity,Smarty
3、采用简易的语言来描述大段的字串以及Dom/DHTML操作
4、可以很方便的解析XML文件格式的数据到指定模板。
采 用该引擎，可以让它来完全处理View方面的事情，服务端Module直接输出Data就可以。让你的 MVC模式连成一体，而且由于View由浏览器来处 理，大大减少了服务器的负担，用来构建Ajax技术的网络信息系统应用是一个非常好的选择。下面将通过翻译该站的文章来给大家介绍这个JST引擎的使用。


&#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Strict//EN&#34; &#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&#34;&#62;
&#60;html xmlns=&#34;http://www.w3.org/1999/xhtml&#34;&#62;
&#60;head&#62;
&#60;title&#62;JS template for google calendar&#60;/title&#62;
&#60;meta http-equiv=&#34;Content-Type&#34; content=&#34;text/html; charset=utf-8&#34; /&#62;
&#60;style type=&#34;text/css&#34;&#62;
&#60;!--
table {margin:10px; }
table,td,th {
	border:1px solid #000;
	border-collapse:collapse;
}
td {padding:5px; }
textarea {color:green; font-size:12px; padding:5px;  }
#taotao {width:220px; }
#taotao * {margin:0;padding:0;list-style:none; }
#taotao li {margin:0 0 3px; padding:5px; background:#666; border:1px solid #333; color:#ddd; font-size:12px;}
#taotao li p.time {color:#888;text-align:right; margin:0 [...]]]></description>
			<content:encoded><![CDATA[<p>Trimpath JavaScript 是个轻量级的，基于JavaScript的，跨浏览器，采用APL/GPL开放源代码协议的，可以让你轻松进行基于模板编程方式的纯JS引擎。</p>
<p>它有如下的特点：<br />
1、采用标准的JavaScript编写，支持跨浏览器<br />
2、模板语法类似于：FreeMarker，Velocity,Smarty<br />
3、采用简易的语言来描述大段的字串以及Dom/DHTML操作<br />
4、可以很方便的解析XML文件格式的数据到指定模板。</p>
<p>采 用该引擎，可以让它来完全处理View方面的事情，服务端Module直接输出Data就可以。让你的 MVC模式连成一体，而且由于View由浏览器来处 理，大大减少了服务器的负担，用来构建Ajax技术的网络信息系统应用是一个非常好的选择。下面将通过翻译该站的文章来给大家介绍这个JST引擎的使用。</p>
<div class="runcode">
<p><textarea name="runcode" class="runcode_text" id="runcode_LDbq43">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;title&gt;JS template for google calendar&lt;/title&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;style type=&quot;text/css&quot;&gt;
&lt;!--
table {margin:10px; }
table,td,th {
	border:1px solid #000;
	border-collapse:collapse;
}
td {padding:5px; }
textarea {color:green; font-size:12px; padding:5px;  }
#taotao {width:220px; }
#taotao * {margin:0;padding:0;list-style:none; }
#taotao li {margin:0 0 3px; padding:5px; background:#666; border:1px solid #333; color:#ddd; font-size:12px;}
#taotao li p.time {color:#888;text-align:right; margin:0 0 5px 0;   }
#taotao li p.time span {font-size:11px;}
--&gt;
&lt;/style&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
/**
 * TrimPath Template. Release 1.0.39.
 * Copyright (C) 2004, 2005 Metaha.
 *
 * TrimPath Template is licensed under the GNU General Public License
 * and the Apache License, Version 2.0, as follows:
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var TrimPath;
// TODO: Debugging mode vs stop-on-error mode - runtime flag.
// TODO: Handle || (or) characters and backslashes.
// TODO: Add more modifiers.
(function() {               // Using a closure to keep global namespace clean.
    if (TrimPath == null)
        TrimPath = new Object();
    if (TrimPath.evalEx == null)
        TrimPath.evalEx = function(src) { return eval(src); };
    var UNDEFINED;
    if (Array.prototype.pop == null)  // IE 5.x fix from Igor Poteryaev.
        Array.prototype.pop = function() {
            if (this.length === 0) {return UNDEFINED;}
            return this[--this.length];
        };
    if (Array.prototype.push == null) // IE 5.x fix from Igor Poteryaev.
        Array.prototype.push = function() {
            for (var i = 0; i &lt; arguments.length; ++i) {this[this.length] = arguments[i];}
            return this.length;
        };
    TrimPath.parseTemplate = function(tmplContent, optTmplName, optEtc) {
        if (optEtc == null)
            optEtc = TrimPath.parseTemplate_etc;
        var funcSrc = parse(tmplContent, optTmplName, optEtc);
        var func = TrimPath.evalEx(funcSrc, optTmplName, 1);
        if (func != null)
            return new optEtc.Template(optTmplName, tmplContent, funcSrc, func, optEtc);
        return null;
    }
    try {
        String.prototype.process = function(context, optFlags) {
            var template = TrimPath.parseTemplate(this, null);
            if (template != null)
                return template.process(context, optFlags);
            return this;
        }
    } catch (e) { // Swallow exception, such as when String.prototype is sealed.
    }
    TrimPath.parseTemplate_etc = {};            // Exposed for extensibility.
    TrimPath.parseTemplate_etc.statementTag = &quot;forelse|for|if|elseif|else|var|macro&quot;;
    TrimPath.parseTemplate_etc.statementDef = { // Lookup table for statement tags.
        &quot;if&quot;     : { delta:  1, prefix: &quot;if (&quot;, suffix: &quot;) {&quot;, paramMin: 1 },
        &quot;else&quot;   : { delta:  0, prefix: &quot;} else {&quot; },
        &quot;elseif&quot; : { delta:  0, prefix: &quot;} else if (&quot;, suffix: &quot;) {&quot;, paramDefault: &quot;true&quot; },
        &quot;/if&quot;    : { delta: -1, prefix: &quot;}&quot; },
        &quot;for&quot;    : { delta:  1, paramMin: 3,
                     prefixFunc : function(stmtParts, state, tmplName, etc) {
                        if (stmtParts[2] != &quot;in&quot;)
                            throw new etc.ParseError(tmplName, state.line, &quot;bad for loop statement: &quot; + stmtParts.join(' '));
                        var iterVar = stmtParts[1];
                        var listVar = &quot;__LIST__&quot; + iterVar;
                        return [ &quot;var &quot;, listVar, &quot; = &quot;, stmtParts[3], &quot;;&quot;,
                             // Fix from Ross Shaull for hash looping, make sure that we have an array of loop lengths to treat like a stack.
                             &quot;var __LENGTH_STACK__;&quot;,
                             &quot;if (typeof(__LENGTH_STACK__) == 'undefined' || !__LENGTH_STACK__.length) __LENGTH_STACK__ = new Array();&quot;,
                             &quot;__LENGTH_STACK__[__LENGTH_STACK__.length] = 0;&quot;, // Push a new for-loop onto the stack of loop lengths.
                             &quot;if ((&quot;, listVar, &quot;) != null) { &quot;,
                             &quot;var &quot;, iterVar, &quot;_ct = 0;&quot;,       // iterVar_ct variable, added by B. Bittman
                             &quot;for (var &quot;, iterVar, &quot;_index in &quot;, listVar, &quot;) { &quot;,
                             iterVar, &quot;_ct++;&quot;,
                             &quot;if (typeof(&quot;, listVar, &quot;[&quot;, iterVar, &quot;_index]) == 'function') {continue;}&quot;, // IE 5.x fix from Igor Poteryaev.
                             &quot;__LENGTH_STACK__[__LENGTH_STACK__.length - 1]++;&quot;,
                             &quot;var &quot;, iterVar, &quot; = &quot;, listVar, &quot;[&quot;, iterVar, &quot;_index];&quot; ].join(&quot;&quot;);
                     } },
        &quot;forelse&quot; : { delta:  0, prefix: &quot;} } if (__LENGTH_STACK__[__LENGTH_STACK__.length - 1] == 0) { if (&quot;, suffix: &quot;) {&quot;, paramDefault: &quot;true&quot; },
        &quot;/for&quot;    : { delta: -1, prefix: &quot;} }; delete __LENGTH_STACK__[__LENGTH_STACK__.length - 1];&quot; }, // Remove the just-finished for-loop from the stack of loop lengths.
        &quot;var&quot;     : { delta:  0, prefix: &quot;var &quot;, suffix: &quot;;&quot; },
        &quot;macro&quot;   : { delta:  1,
                      prefixFunc : function(stmtParts, state, tmplName, etc) {
                          var macroName = stmtParts[1].split('(')[0];
                          return [ &quot;var &quot;, macroName, &quot; = function&quot;,
                                   stmtParts.slice(1).join(' ').substring(macroName.length),
                                   &quot;{ var _OUT_arr = []; var _OUT = { write: function(m) { if (m) _OUT_arr.push(m); } }; &quot; ].join('');
                     } },
        &quot;/macro&quot;  : { delta: -1, prefix: &quot; return _OUT_arr.join(''); };&quot; }
    }
    TrimPath.parseTemplate_etc.modifierDef = {
        &quot;eat&quot;        : function(v)    { return &quot;&quot;; },
        &quot;escape&quot;     : function(s)    { return String(s).replace(/&amp;/g, &quot;&amp;amp;&quot;).replace(/&lt;/g, &quot;&amp;lt;&quot;).replace(/&gt;/g, &quot;&amp;gt;&quot;); },
        &quot;capitalize&quot; : function(s)    { return String(s).toUpperCase(); },
        &quot;default&quot;    : function(s, d) { return s != null ? s : d; }
    }
    TrimPath.parseTemplate_etc.modifierDef.h = TrimPath.parseTemplate_etc.modifierDef.escape;
    TrimPath.parseTemplate_etc.Template = function(tmplName, tmplContent, funcSrc, func, etc) {
        this.process = function(context, flags) {
            if (context == null)
                context = {};
            if (context._MODIFIERS == null)
                context._MODIFIERS = {};
            if (context.defined == null)
                context.defined = function(str) { return (context[str] != undefined); };
            for (var k in etc.modifierDef) {
                if (context._MODIFIERS[k] == null)
                    context._MODIFIERS[k] = etc.modifierDef[k];
            }
            if (flags == null)
                flags = {};
            var resultArr = [];
            var resultOut = { write: function(m) { resultArr.push(m); } };
            try {
                func(resultOut, context, flags);
            } catch (e) {
                if (flags.throwExceptions == true)
                    throw e;
                var result = new String(resultArr.join(&quot;&quot;) + &quot;[ERROR: &quot; + e.toString() + (e.message ? '; ' + e.message : '') + &quot;]&quot;);
                result[&quot;exception&quot;] = e;
                return result;
            }
            return resultArr.join(&quot;&quot;);
        }
        this.name       = tmplName;
        this.source     = tmplContent;
        this.sourceFunc = funcSrc;
        this.toString   = function() { return &quot;TrimPath.Template [&quot; + tmplName + &quot;]&quot;; }
    }
    TrimPath.parseTemplate_etc.ParseError = function(name, line, message) {
        this.name    = name;
        this.line    = line;
        this.message = message;
    }
    TrimPath.parseTemplate_etc.ParseError.prototype.toString = function() {
        return (&quot;TrimPath template ParseError in &quot; + this.name + &quot;: line &quot; + this.line + &quot;, &quot; + this.message);
    }
    var parse = function(body, tmplName, etc) {
        body = cleanWhiteSpace(body);
        var funcText = [ &quot;var TrimPath_Template_TEMP = function(_OUT, _CONTEXT, _FLAGS) { with (_CONTEXT) {&quot; ];
        var state    = { stack: [], line: 1 };                              // TODO: Fix line number counting.
        var endStmtPrev = -1;
        while (endStmtPrev + 1 &lt; body.length) {
            var begStmt = endStmtPrev;
            // Scan until we find some statement markup.
            begStmt = body.indexOf(&quot;{&quot;, begStmt + 1);
            while (begStmt &gt;= 0) {
                var endStmt = body.indexOf('}', begStmt + 1);
                var stmt = body.substring(begStmt, endStmt);
                var blockrx = stmt.match(/^\{(cdata|minify|eval)/); // From B. Bittman, minify/eval/cdata implementation.
                if (blockrx) {
                    var blockType = blockrx[1];
                    var blockMarkerBeg = begStmt + blockType.length + 1;
                    var blockMarkerEnd = body.indexOf('}', blockMarkerBeg);
                    if (blockMarkerEnd &gt;= 0) {
                        var blockMarker;
                        if( blockMarkerEnd - blockMarkerBeg &lt;= 0 ) {
                            blockMarker = &quot;{/&quot; + blockType + &quot;}&quot;;
                        } else {
                            blockMarker = body.substring(blockMarkerBeg + 1, blockMarkerEnd);
                        }
                        var blockEnd = body.indexOf(blockMarker, blockMarkerEnd + 1);
                        if (blockEnd &gt;= 0) {
                            emitSectionText(body.substring(endStmtPrev + 1, begStmt), funcText);
                            var blockText = body.substring(blockMarkerEnd + 1, blockEnd);
                            if (blockType == 'cdata') {
                                emitText(blockText, funcText);
                            } else if (blockType == 'minify') {
                                emitText(scrubWhiteSpace(blockText), funcText);
                            } else if (blockType == 'eval') {
                                if (blockText != null &amp;&amp; blockText.length &gt; 0) // From B. Bittman, eval should not execute until process().
                                    funcText.push('_OUT.write( (function() { ' + blockText + ' })() );');
                            }
                            begStmt = endStmtPrev = blockEnd + blockMarker.length - 1;
                        }
                    }
                } else if (body.charAt(begStmt - 1) != '$' &amp;&amp;               // Not an expression or backslashed,
                           body.charAt(begStmt - 1) != '\\') {              // so check if it is a statement tag.
                    var offset = (body.charAt(begStmt + 1) == '/' ? 2 : 1); // Close tags offset of 2 skips '/'.
                                                                            // 10 is larger than maximum statement tag length.
                    if (body.substring(begStmt + offset, begStmt + 10 + offset).search(TrimPath.parseTemplate_etc.statementTag) == 0)
                        break;                                              // Found a match.
                }
                begStmt = body.indexOf(&quot;{&quot;, begStmt + 1);
            }
            if (begStmt &lt; 0)                              // In &quot;a{for}c&quot;, begStmt will be 1.
                break;
            var endStmt = body.indexOf(&quot;}&quot;, begStmt + 1); // In &quot;a{for}c&quot;, endStmt will be 5.
            if (endStmt &lt; 0)
                break;
            emitSectionText(body.substring(endStmtPrev + 1, begStmt), funcText);
            emitStatement(body.substring(begStmt, endStmt + 1), state, funcText, tmplName, etc);
            endStmtPrev = endStmt;
        }
        emitSectionText(body.substring(endStmtPrev + 1), funcText);
        if (state.stack.length != 0)
            throw new etc.ParseError(tmplName, state.line, &quot;unclosed, unmatched statement(s): &quot; + state.stack.join(&quot;,&quot;));
        funcText.push(&quot;}}; TrimPath_Template_TEMP&quot;);
        return funcText.join(&quot;&quot;);
    }
    var emitStatement = function(stmtStr, state, funcText, tmplName, etc) {
        var parts = stmtStr.slice(1, -1).split(' ');
        var stmt = etc.statementDef[parts[0]]; // Here, parts[0] == for/if/else/...
        if (stmt == null) {                    // Not a real statement.
            emitSectionText(stmtStr, funcText);
            return;
        }
        if (stmt.delta &lt; 0) {
            if (state.stack.length &lt;= 0)
                throw new etc.ParseError(tmplName, state.line, &quot;close tag does not match any previous statement: &quot; + stmtStr);
            state.stack.pop();
        }
        if (stmt.delta &gt; 0)
            state.stack.push(stmtStr);
        if (stmt.paramMin != null &amp;&amp;
            stmt.paramMin &gt;= parts.length)
            throw new etc.ParseError(tmplName, state.line, &quot;statement needs more parameters: &quot; + stmtStr);
        if (stmt.prefixFunc != null)
            funcText.push(stmt.prefixFunc(parts, state, tmplName, etc));
        else
            funcText.push(stmt.prefix);
        if (stmt.suffix != null) {
            if (parts.length &lt;= 1) {
                if (stmt.paramDefault != null)
                    funcText.push(stmt.paramDefault);
            } else {
                for (var i = 1; i &lt; parts.length; i++) {
                    if (i &gt; 1)
                        funcText.push(' ');
                    funcText.push(parts[i]);
                }
            }
            funcText.push(stmt.suffix);
        }
    }
    var emitSectionText = function(text, funcText) {
        if (text.length &lt;= 0)
            return;
        var nlPrefix = 0;               // Index to first non-newline in prefix.
        var nlSuffix = text.length - 1; // Index to first non-space/tab in suffix.
        while (nlPrefix &lt; text.length &amp;&amp; (text.charAt(nlPrefix) == '\n'))
            nlPrefix++;
        while (nlSuffix &gt;= 0 &amp;&amp; (text.charAt(nlSuffix) == ' ' || text.charAt(nlSuffix) == '\t'))
            nlSuffix--;
        if (nlSuffix &lt; nlPrefix)
            nlSuffix = nlPrefix;
        if (nlPrefix &gt; 0) {
            funcText.push('if (_FLAGS.keepWhitespace == true) _OUT.write(&quot;');
            var s = text.substring(0, nlPrefix).replace('\n', '\\n'); // A macro IE fix from BJessen.
            if (s.charAt(s.length - 1) == '\n')
            	s = s.substring(0, s.length - 1);
            funcText.push(s);
            funcText.push('&quot;);');
        }
        var lines = text.substring(nlPrefix, nlSuffix + 1).split('\n');
        for (var i = 0; i &lt; lines.length; i++) {
            emitSectionTextLine(lines[i], funcText);
            if (i &lt; lines.length - 1)
                funcText.push('_OUT.write(&quot;\\n&quot;);\n');
        }
        if (nlSuffix + 1 &lt; text.length) {
            funcText.push('if (_FLAGS.keepWhitespace == true) _OUT.write(&quot;');
            var s = text.substring(nlSuffix + 1).replace('\n', '\\n');
            if (s.charAt(s.length - 1) == '\n')
            	s = s.substring(0, s.length - 1);
            funcText.push(s);
            funcText.push('&quot;);');
        }
    }
    var emitSectionTextLine = function(line, funcText) {
        var endMarkPrev = '}';
        var endExprPrev = -1;
        while (endExprPrev + endMarkPrev.length &lt; line.length) {
            var begMark = &quot;${&quot;, endMark = &quot;}&quot;;
            var begExpr = line.indexOf(begMark, endExprPrev + endMarkPrev.length); // In &quot;a${b}c&quot;, begExpr == 1
            if (begExpr &lt; 0)
                break;
            if (line.charAt(begExpr + 2) == '%') {
                begMark = &quot;${%&quot;;
                endMark = &quot;%}&quot;;
            }
            var endExpr = line.indexOf(endMark, begExpr + begMark.length);         // In &quot;a${b}c&quot;, endExpr == 4;
            if (endExpr &lt; 0)
                break;
            emitText(line.substring(endExprPrev + endMarkPrev.length, begExpr), funcText);
            // Example: exprs == 'firstName|default:&quot;John Doe&quot;|capitalize'.split('|')
            var exprArr = line.substring(begExpr + begMark.length, endExpr).replace(/\|\|/g, &quot;#@@#&quot;).split('|');
            for (var k in exprArr) {
                if (exprArr[k].replace) // IE 5.x fix from Igor Poteryaev.
                    exprArr[k] = exprArr[k].replace(/#@@#/g, '||');
            }
            funcText.push('_OUT.write(');
            emitExpression(exprArr, exprArr.length - 1, funcText);
            funcText.push(');');
            endExprPrev = endExpr;
            endMarkPrev = endMark;
        }
        emitText(line.substring(endExprPrev + endMarkPrev.length), funcText);
    }
    var emitText = function(text, funcText) {
        if (text == null ||
            text.length &lt;= 0)
            return;
        text = text.replace(/\\/g, '\\\\');
        text = text.replace(/\n/g, '\\n');
        text = text.replace(/&quot;/g,  '\\&quot;');
        funcText.push('_OUT.write(&quot;');
        funcText.push(text);
        funcText.push('&quot;);');
    }
    var emitExpression = function(exprArr, index, funcText) {
        // Ex: foo|a:x|b:y1,y2|c:z1,z2 is emitted as c(b(a(foo,x),y1,y2),z1,z2)
        var expr = exprArr[index]; // Ex: exprArr == [firstName,capitalize,default:&quot;John Doe&quot;]
        if (index &lt;= 0) {          // Ex: expr    == 'default:&quot;John Doe&quot;'
            funcText.push(expr);
            return;
        }
        var parts = expr.split(':');
        funcText.push('_MODIFIERS[&quot;');
        funcText.push(parts[0]); // The parts[0] is a modifier function name, like capitalize.
        funcText.push('&quot;](');
        emitExpression(exprArr, index - 1, funcText);
        if (parts.length &gt; 1) {
            funcText.push(',');
            funcText.push(parts[1]);
        }
        funcText.push(')');
    }
    var cleanWhiteSpace = function(result) {
        result = result.replace(/\t/g,   &quot;    &quot;);
        result = result.replace(/\r\n/g, &quot;\n&quot;);
        result = result.replace(/\r/g,   &quot;\n&quot;);
        result = result.replace(/^(\s*\S*(\s+\S+)*)\s*$/, '$1'); // Right trim by Igor Poteryaev.
        return result;
    }
    var scrubWhiteSpace = function(result) {
        result = result.replace(/^\s+/g,   &quot;&quot;);
        result = result.replace(/\s+$/g,   &quot;&quot;);
        result = result.replace(/\s+/g,   &quot; &quot;);
        result = result.replace(/^(\s*\S*(\s+\S+)*)\s*$/, '$1'); // Right trim by Igor Poteryaev.
        return result;
    }
    // The DOM helper functions depend on DOM/DHTML, so they only work in a browser.
    // However, these are not considered core to the engine.
    //
    TrimPath.parseDOMTemplate = function(elementId, optDocument, optEtc) {
        if (optDocument == null)
            optDocument = document;
        var element = optDocument.getElementById(elementId);
        var content = element.value;     // Like textarea.value.
        if (content == null)
            content = element.innerHTML; // Like textarea.innerHTML.
        content = content.replace(/&amp;lt;/g, &quot;&lt;&quot;).replace(/&amp;gt;/g, &quot;&gt;&quot;);
        return TrimPath.parseTemplate(content, elementId, optEtc);
    }
    TrimPath.processDOMTemplate = function(elementId, context, optFlags, optDocument, optEtc) {
        return TrimPath.parseDOMTemplate(elementId, optDocument, optEtc).process(context, optFlags);
    }
}) ();
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a href=&quot;http://code.google.com/p/trimpath/&quot;&gt;JavaScript Template JST模板引擎&lt;/a&gt;
&lt;table&gt;
 &lt;tr&gt;
  &lt;td&gt;
&lt;textarea name=&quot;taotao_jst&quot; id=&quot;taotao_jst&quot; cols=&quot;70&quot; rows=&quot;12&quot;&gt;
&lt;ul&gt;
 {for p in posts}
 &lt;li&gt;&lt;p class=&quot;time&quot;&gt;飞翔唠叨于 &lt;span&gt;${p.time}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;${p.cn} &lt;/p&gt;&lt;/li&gt;
 {/for}
&lt;/ul&gt;
&lt;/textarea&gt;
  &lt;/td&gt;
  &lt;td&gt;
&lt;div id=&quot;taotao&quot;&gt;
	loading...
&lt;/div&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
&lt;!--
function doApi(root){
	outputEl=document.getElementById('taotao');
	eval(root);
	outputEl.innerHTML = TrimPath.processDOMTemplate(&quot;taotao_jst&quot;, root);
}
//--&gt;
&lt;/script&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
&lt;/table&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://www.taotao.com/cgi-bin/msgj?qq=38672654&amp;num=5&amp;t=0&quot;&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode_open_new('runcode_LDbq43');"/> <input type="button" value="复制" class="runcode_button" onclick="runcode_copy('runcode_LDbq43');"/> 提示：你可以先修改部分代码再运行。</p>
</div>
<p>JST十分钟简介</p>
<p>JST API<br />
JST Markup Syntax<br />
JST Standard Modifiers<br />
JST Downloads<br />
JST Community Wiki<br />
JST Browser Compatibility<br />
JST Online Demo</p>
<p>1、API<br />
首先到下载页面下载 template.js<br />
然后在你的JSP/ASP/PHP等文件中引用</p>
<p>   1. <script language="javascript" src="trimpath/template.js"></script></p>
<p>复制代码</p>
<p>当你引用了template.js文件之后，脚本将创建一个名叫“trimpath&#8221;的物件给你使用。</p>
<p>TrimPath Object<br />
这个物件是一个全局的单一变量，也是所有trimpath组件的访问入口，除了它自身，我们尝试建立一个清晰的命名空间给您使用。</p>
<p>下面是 Trimpath 定义的方法：</p>
<p>   1. TrimPath.parseDOMTemplate ( elementId, optionalDocument )</p>
<p>复制代码</p>
<p>得到页面中ID为elementId的Dom组件的InnerHTML，并将其解析成一个模板，这个方法返回一个templateObject对象（下面将详细描述），解析出错时将抛出一个异常，下面是这个方法的参数：<br />
  elementId               DOM组件，其innerhtml将用来做模板<br />
  optionalDocument     一个可选参数，在使用iframe，frameset或者默认多文档时会有用<br />
通常用来做模板的DOM元素是一个隐藏的<textarea>，如下面的例子</p>
<p>   1. <textarea id="elementId" style="display:none;"> template body </textarea></p>
<p>复制代码</p>
<p>TrimPath.processDOMTemplate ( elementId, contextObject, optionalFlags, optionalDocument )<br />
一 个辅助函数，里面调用了TrimPath.parseDOMTemplate() 和 then the process() 方法以获得templateObject。输出的是templateObject.process() 中返回的对象。解析出错时将抛出一个错误。下面是这个方法的参数：</p>
<p>elementId         包含模板内容的DOM元素ID<br />
contextObject     参考templateObject.process()<br />
optionalFlags       参考templateObject.process()<br />
optionalDocument 参考TrimPath.parseDOMTemplate</p>
<p>TrimPath.parseTemplate ( templateContentStr, optionalTemplateName )<br />
解析模板方法，将一个字符串做为模板解析并返回一个templateObject<br />
参数表：</p>
<p>templateContentStr   符合JST语法的字符串，例如: &#8220;Hello ${firstName} ${lastName}&#8221;<br />
optionalTemplateName 一个可选的字符串用来指定模板名称，辅助查错。</p>
<p>The templateObject<br />
TrimPath.parseTemplate() 和 TrimPath.parseDOMTemplate()的成功运行将产生一个 templateObject 它只有一个主方法</p>
<p>templateObject.process ( contextObject, optionalFlags )</p>
<p>这个方法将模板和数据结合在一起，可以重复调用，如果没有重新解析，templateObjects的缓存和重用将获得最好的系统性能。这个函数的返回值是一个经过“渲染”过的模板的字符串。</p>
<p>参数contextObject 必须是一个对象，并将成为模板的一个访问域，比如一个模板是：${a}，那么contextObject.a必须是可以访问到的。同样${a.b.c}, contextObject.a.b.c也是可以访问到的。<br />
注 意：contextObject 可以是javascript中的任意对象，包含字符串, 数字, 日期, 对象和函数。所以${groupCalender(new Date())} 可以这样来调用contextObject.groupCalender(new Date())。当然，你必须自己编程实现groupCalender() 这个函数。</p>
<p>参数optionalFlags 可以是空值，也可以是一个下面列表描述的对象：<br />
throwExceptions 默认是false,当true的时候，process() 方法将重新抛出异常，当false的时候，任何异常将停止解析模板，并在方法返回值包含一个出错信息。<br />
keepWhitespace 默认是falsel，当值为true时，模板的空白将保留。当为false时，空白（换行、空格、TAB）将被截取。</p>
<p>String.prototype.process() 方法</p>
<p>String.prototype.process ( contextObject, optionalFlags )<br />
做为一个便捷的方式为string对象加入一个process（）的方法，让它来执行解析模板的动作。参数跟process()一样。</p>
<p>   1.   var result = &#8220;hello ${firstName}&#8221;.process(data)<br />
   2.   // &#8230;is equivalent to&#8230;<br />
   3.   var result = TrimPath.parseTemplate(&#8221;hello ${firstName}&#8221;).process(data);</p>
<p>复制代码</p>
<p>添加自定义标识符</p>
<p>如果要采用自定义标识符，你必须把他们放在_MODIFERS 这个对象中，这些标识符集将被添加到contextObject 对象中，然后最终传给process()解析。每一个自定义标识符必须是一个函数并且至少有一个字符串参数输入和一个字符串输出。<br />
例子：</p>
<p>   1.   var myModifiers = {<br />
   2.   hello : function(str, greeting) {<br />
   3.     if (greeting == null)<br />
   4.       greeting = &#8220;Hello&#8221;;<br />
   5.     return greeting + &#8220;, &#8221; + str;<br />
   6.   },<br />
   7.   zeroSuffix : function(str, totalLength) {<br />
   8.     return (str + &#8220;000000000000000&#8243;).substring(0, totalLength);<br />
   9.   }<br />
  10. };<br />
  11. var myData = {<br />
  12.   firstName : &#8220;John&#8221;,<br />
  13.   getCurrentPoints : function() { /* Do something here&#8230; */ return 12; }<br />
  14. }<br />
  15.</p>
<p>  16. myData._MODIFIERS = myModifiers;<br />
  17.</p>
<p>  18. &#8220;${firstName}&#8221;.process(myData) == &#8220;John&#8221;<br />
  19. &#8220;${firstName|hello}&#8221;.process(myData) == &#8220;Hello, John&#8221;<br />
  20. &#8220;${firstName|hello:&#8221;Buenos Dias&#8221;}&#8221;.process(myData) == &#8220;Buenos Dias, John&#8221;<br />
  21. &#8220;${firstName|hello:&#8221;Buenos Dias&#8221;|capitalize}&#8221;.process(myData) == &#8220;BUENOS DIAS, JOHN&#8221;<br />
  22.</p>
<p>  23. &#8220;${getCurrentPoints()}&#8221;.process(myData) == &#8220;12&#8243;<br />
  24. &#8220;${getCurrentPoints()|zeroSuffix:4}&#8221;.process(myData) == &#8220;1200&#8243;</p>
<p>复制代码</p>
<p>JST 的语法和语句</p>
<p>语法</p>
<p>   1. ${expr}<br />
   2. ${expr|modifier}<br />
   3. ${expr|modifier1|modifier2|&#8230;|modifierN}<br />
   4. ${expr|modifier1:argExpr1_1}<br />
   5. ${expr|modifier1:argExpr1_1,argExpr1_2,&#8230;,argExpr1_N}<br />
   6. ${expr|modifier1:argExpr1_1,argExpr1_2|&#8230;|modifierN:argExprN_1,argExprN_2,&#8230;,argExprN_M}</p>
<p>复制代码</p>
<p>表达式可以是除了“}”之外的任何合法的javascript字符串<br />
标识符看起来像这种结构：modifierName[:argExpr1[,argExpr2[,argExprN]]]</p>
<p>一个带参数的表达式例子</p>
<p>   1. ${customer.firstName}<br />
   2. ${customer.firstName|capitalize}<br />
   3. ${customer.firstName|default:&#8221;no name&#8221;|capitalize}<br />
   4. ${article.getCreationDate()|default:new Date()|toCalenderControl:&#8221;YYYY.MM.DD&#8221;,true,&#8221;Creation Date&#8221;}<br />
   5. ${(lastQuarter.calcRevenue() &#8211; fixedCosts) / 1000000}</p>
<p>复制代码</p>
<p>一个表达式也可以像下面一样通过添加“％”字符来标识，这个可以避免在你的表达式中出现“}”时出错的情况。</p>
<p>比如：</p>
<p>   1. Visit our ${% emitLink(&#8217;Solutions and Products&#8217;,<br />
   2.                 { color: &#8216;red&#8217;, blink: false }) %} page.<br />
   3.</p>
<p>   4. The extra spaces are actually not necessary, like&#8230;<br />
   5. ${%customer.firstName%}<br />
   6. ${%customer.firstName|capitalize%}</p>
<p>复制代码</p>
<p>语句<br />
JST语句就像是javascript语句一样，也有if/else/for/function这些句子</p>
<p>分支控制语句</p>
<p>   1. {if testExpr}<br />
   2.   {elseif testExpr}<br />
   3.   {else}<br />
   4. {/if}</p>
<p>复制代码</p>
<p>上述testExpr 是一个合法的javascript判定式</p>
<p>例子</p>
<p>   1. {if customer != null &#038;&#038; customer.balance > 1000}<br />
   2.   We love you!<br />
   3. {/if}<br />
   4.</p>
<p>   5. {if user.karma > 100}<br />
   6.     Welcome to the Black Sun.<br />
   7. {elseif user.isHero}<br />
   8.     Sir, yes sir! Welcome!<br />
   9.     {if user.lastName == &#8220;Yen&#8221;}<br />
  10.       Fancy some apple pie, sir?<br />
  11.     {/if}<br />
  12. {/if}<br />
  13.</p>
<p>  14. <a href="/login{if returnURL != null &#038;&#038; returnURL != 'main'}?goto=${returnURL}{/if}">Login</a></p>
<p>复制代码</p>
<p>*JST引擎还包含一个辅助函数defined(str)，这个可以测试一个变量是否已经被定义。</p>
<p>比如这段代码判断管理员发送了消息给你</p>
<p>   1. {if defined(&#8217;adminMessage&#8217;)}<br />
   2.   System Administrator Important NOTICE: ${adminMessage}<br />
   3. {/if}</p>
<p>复制代码</p>
<p>循环语句</p>
<p>   1. {for varName in listExpr}<br />
   2. {/for}<br />
   3.</p>
<p>   4. {for varName in listExpr}<br />
   5.   &#8230;main body of the loop&#8230;<br />
   6. {forelse}<br />
   7.   &#8230;body when listExpr is null or listExpr.length is 0&#8230;<br />
   8.</p>
<p>   9. {/for}</p>
<p>复制代码</p>
<p>*varName 必须是一个javascript的合法变量名<br />
*listExpr 可以是一个数组，对象或者为空，而且只能被赋值一次<br />
例子</p>
<p>   1. Two variables are bound in the main body of the loop:<br />
   2.   __LIST__varName &#8211; holds the result of evaluating listExpr.<br />
   3.   varName_index   &#8211; this is the key or counter used during iteration.<br />
   4.</p>
<p>   5. Examples:<br />
   6. {for x in customer.getRecentOrders()}<br />
   7.   ${x_index} : ${x.orderNumber} <br/><br />
   8. {forelse}<br />
   9.   You have no recent orders.<br />
  10. {/for}<br />
  11.</p>
<p>  12. Converted pseudo-code for the above&#8230;<br />
  13. var __LIST__x = customer.getRecentOrders();<br />
  14. if (__LIST__x != null &#038;&#038; __LIST__x.length > 0) {<br />
  15.   for (var x_index in __LIST__x) {<br />
  16.     var x = __LIST__x[x_index];<br />
  17.     ${x_index} : {$x.orderNumber} <br/><br />
  18.   }<br />
  19. } else {<br />
  20.   You have no recent orders.<br />
  21. }</p>
<p>复制代码</p>
<p>定义变量</p>
<p>{var varName}<br />
{var varName = varInitExpr}<br />
*varName必须是一个合法的javascript变量名<br />
*varInitExpr必须是一个没有包含&#8221;}&#8221;的字符串</p>
<p>例子：</p>
<p>   1. {var temp = crypto.generateRandomPrime(4096)}<br />
   2. Your prime is ${temp}.</p>
<p>复制代码</p>
<p>宏定义<br />
  {macro macroName(arg1, arg2, &#8230;argN)}<br />
  &#8230;body of the macro&#8230;<br />
{/macro}</p>
<p>*宏类似于一个javascript函数，不同点在于宏的主体是另外一个包含了诸如控制语句、循环语句的JST模板</p>
<p>*宏的名称必须是一个合法javascript变量名<br />
*宏的返回值是一个字符创<br />
*使用宏可以采用这种语法 ：${macroName()}<br />
一个使用宏的例子</p>
<p>   1. {macro htmlList(list, optionalListType)}<br />
   2.   {var listType = optionalListType != null ? optionalListType : &#8220;ul&#8221;}<br />
   3.   <${listType}><br />
   4.     {for item in list}<br />
   5.
<li>${item}</li>
<p>   6.     {/for}<br />
   7.   </${listType}><br />
   8. {/macro}<br />
   9.</p>
<p>  10. Using the macro&#8230;<br />
  11. ${htmlList([ 1, 2, 3])}<br />
  12. ${htmlList([ "Purple State", "Blue State", "Red State" ], &#8220;ol&#8221;)}<br />
  13. {var saved = htmlList([ 100, 200, 300 ])}<br />
  14. ${saved} and ${saved}</p>
<p>复制代码</p>
<p>运行上述语句将出现</p>
<p>QUOTE:<br />
*1<br />
*2<br />
*3</p>
<p>这样的列表。只需将数据列表赋值给htmlList这个宏，就会帮你把数据通过
<li>方式列出来，聪明的你很快就会把它改成<option>
<td>等应用了。</p>
<p>从宏的访问域来说，默认情况下它是每个模板私有的，但是如果你想定义<br />
一个宏库的话，那么也许你需要在process()之前先定义可以导出宏：contextObject['exported'] ={};<br />
下面是例子：</p>
<p>   1.   {macro userName(user)}<br />
   2.   {if user.aliasName != null &#038;&#038; user.aliasName.length > 0}<br />
   3.     ${user.aliasName}<br />
   4.   {else}<br />
   5.     ${user.login}<br />
   6.   {/if}<br />
   7. {/macro}<br />
   8. ${exported.userName = userName |eat}</p>
<p>复制代码</p>
<p>另外，你也可以设置 contextObject['exported'] = contextObject;它也可以正常的工作。</p>
<p>CDATA 文本区段</p>
<pre class="brush: plain;">[/code]</pre>
<p>{cdata}<br />
  ...text emitted without JST processing...<br />
{/cdata}</p>
<p>{cdata EOF}<br />
  ...text emitted without JST processing...</p>
]]></content:encoded>
			<wfw:commentRss>http://www.asktest.com/blog/?feed=rss2&amp;p=295</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>浏览器侦测  AT.browser</title>
		<link>http://www.asktest.com/blog/?p=287</link>
		<comments>http://www.asktest.com/blog/?p=287#comments</comments>
		<pubDate>Wed, 12 May 2010 09:42:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.asktest.com/blog/?p=287</guid>
		<description><![CDATA[
 &#60;script type=&#34;text/javascript&#34;&#62;
(function(){
	AT.browser = {
		/**
		 * @property IE
		 * @type {Boolean}
		 */
		IE : !!( window.attachEvent &#38;&#38; !window.opera ),
		/**
		 * @property IE6
		 * @type {Boolean}
		 */
		IE6 : navigator.userAgent.indexOf( 'MSIE 6.0' ) &#62; -1,
		/**
		 * @property IE7
		 * @type {Boolean}
		 */
		IE7 : navigator.userAgent.indexOf( 'MSIE 7.0' ) &#62; -1,
        /**
  [...]]]></description>
			<content:encoded><![CDATA[<div class="runcode">
<p><textarea name="runcode" class="runcode_text" id="runcode_riwWvN"> &lt;script type=&quot;text/javascript&quot;&gt;
(function(){
	AT.browser = {
		/**
		 * @property IE
		 * @type {Boolean}
		 */
		IE : !!( window.attachEvent &amp;&amp; !window.opera ),
		/**
		 * @property IE6
		 * @type {Boolean}
		 */
		IE6 : navigator.userAgent.indexOf( 'MSIE 6.0' ) &gt; -1,
		/**
		 * @property IE7
		 * @type {Boolean}
		 */
		IE7 : navigator.userAgent.indexOf( 'MSIE 7.0' ) &gt; -1,
        /**
        * @property IE8
        * @type {Boolean}
        */
	    IE8 : navigator.userAgent.indexOf( 'MSIE 8.0' ) &gt; -1,
		/**
		 * @property Opera
		 * @type {Boolean}
		 */
		Opera : !!window.opera,
		/**
		 * @property WebKit
		 * @type {Boolean}
		 */
		WebKit : navigator.userAgent.indexOf( 'AppleWebKit/' ) &gt; -1,
		/**
		 * @property Gecko
		 * @type {Boolean}
		 */
		Gecko : navigator.userAgent.indexOf( 'Gecko' ) &gt; -1 &amp;&amp; navigator.userAgent.indexOf( 'KHTML' ) == -1
}
})();
 &lt;/script&gt;
</textarea></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode_open_new('runcode_riwWvN');"/> <input type="button" value="复制" class="runcode_button" onclick="runcode_copy('runcode_riwWvN');"/> 提示：你可以先修改部分代码再运行。</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.asktest.com/blog/?feed=rss2&amp;p=287</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>为自己的代码增加DEBUG_MODE</title>
		<link>http://www.asktest.com/blog/?p=282</link>
		<comments>http://www.asktest.com/blog/?p=282#comments</comments>
		<pubDate>Wed, 12 May 2010 09:29:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[debug]]></category>

		<guid isPermaLink="false">http://www.asktest.com/blog/?p=282</guid>
		<description><![CDATA[为自己的代码增加DEBUG_MODE
查看方法：点击运行框在firebug控制台面板查看对象AT的信息。（记得刷新一下）


 &#60;script type=&#34;text/javascript&#34;&#62;
var AT = {};
AT.DEBUG_MODE = false;
AT.debug = {
	log: function(){},
	on : function(){
		AT.DEBUG_MODE = true;
		if(window.console &#38;&#38; console.log){
			this.log = function(s){
				console.log(s);
			}
		}
	},
	off: function(){
		this.log = function(){};
	}
}
AT.log = function(s){
	AT.debug.log(s);
};
if(navigator.userAgent.indexOf( 'Gecko' ) &#62; -1 &#38;&#38; navigator.userAgent.indexOf( 'KHTML' ) == -1){
AT.debug.on();
}
AT.log(AT);
 &#60;/script&#62;

  提示：你可以先修改部分代码再运行。

]]></description>
			<content:encoded><![CDATA[<p><strong>为自己的代码增加DEBUG_MODE</strong><br />
查看方法：点击运行框在firebug控制台面板查看对象AT的信息。（记得刷新一下）</p>
<div class="runcode">
<p><textarea name="runcode" class="runcode_text" id="runcode_ySpbgd">
 &lt;script type=&quot;text/javascript&quot;&gt;
var AT = {};
AT.DEBUG_MODE = false;
AT.debug = {
	log: function(){},
	on : function(){
		AT.DEBUG_MODE = true;
		if(window.console &amp;&amp; console.log){
			this.log = function(s){
				console.log(s);
			}
		}
	},
	off: function(){
		this.log = function(){};
	}
}
AT.log = function(s){
	AT.debug.log(s);
};
if(navigator.userAgent.indexOf( 'Gecko' ) &gt; -1 &amp;&amp; navigator.userAgent.indexOf( 'KHTML' ) == -1){
AT.debug.on();
}
AT.log(AT);
 &lt;/script&gt;
</textarea></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode_open_new('runcode_ySpbgd');"/> <input type="button" value="复制" class="runcode_button" onclick="runcode_copy('runcode_ySpbgd');"/> 提示：你可以先修改部分代码再运行。</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.asktest.com/blog/?feed=rss2&amp;p=282</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FireBug Console API</title>
		<link>http://www.asktest.com/blog/?p=279</link>
		<comments>http://www.asktest.com/blog/?p=279#comments</comments>
		<pubDate>Wed, 12 May 2010 01:19:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.asktest.com/blog/?p=279</guid>
		<description><![CDATA[console.log(object[, object, ...])
在控制台输出一条消息。如果有多个参数，输出时会用空格隔开这些参数。
第一个参数可以是一个包含格式化占位符输出的字符串，例如：
console.log(&#8221;The %s jumped over %d tall buildings&#8221;, animal, count);
上面的例子可以用下面的无格式化占位符输出的代码替换：
console.log(&#8221;The&#8221;, animal, &#8220;jumped over&#8221;, count, &#8220;tall buildings&#8221;);
并且，这两种方式是可以组合使用的。如果使用了格式化占位符，而提供的参数的个数多于占位符的个数，那么，多余的参数会以空格分隔的方式附加在字符串后面，就像：
console.log(&#8221;I am %s and I have:&#8221;, myName, thing1, thing2, thing3);
如果参数是一个Javascript对象，那么在控制台输出的就不是静态文字，而是一个可交互的超链接，点击超链接可以查看该对象的HTML, CSS, Script, DOM窗口，可用格式化字符串%o代替Javascript对象。
console.log(&#8221;Body tag is %o&#8221;, document.body);
格式化字符串列表：
格式化字符串 类型
%s 字符串
%d, %i 整型（暂不支持数字型）
%f 浮点型 （暂不支持数字型）
%o 链接对象
console.debug(object[, object, ...])
在控制台输出一条消息，包含一个指向代码调用位置的超链接。假如是直接在控制台输入该命令，就不会出现超链接（和console.log()一样）。
console.info(object[, object, ...])
在控制台输出一条带有“信息”图标的消息和一个指向代码调用位置的超链接。
console.warn(object[, object, ...])
在控制台输出一条带有“警告”图标的消息和一个指向代码调用位置的超链接。
console.error(object[, object, ...])
在控制台输出一条带有“错误”图标的消息和一个指向代码调用位置的超链接。
console.assert(expression[, object, ...])
测试表达式expression是否为真。如果不是真，会在控制台写一条消息并抛出异常
console.dir(object)
以列表形式输出一个对象的所有属性，有点和你查看DOM窗口相类似。
console.dirxml(node)
输出一个HTML或者XML元素的XML源代码。和你在HTML窗口看到的相似。
console.trace()
Prints an interactive stack trace of [...]]]></description>
			<content:encoded><![CDATA[<p>console.log(object[, object, ...])<br />
在控制台输出一条消息。如果有多个参数，输出时会用空格隔开这些参数。</p>
<p>第一个参数可以是一个包含格式化占位符输出的字符串，例如：<br />
console.log(&#8221;The %s jumped over %d tall buildings&#8221;, animal, count);</p>
<p>上面的例子可以用下面的无格式化占位符输出的代码替换：<br />
console.log(&#8221;The&#8221;, animal, &#8220;jumped over&#8221;, count, &#8220;tall buildings&#8221;);</p>
<p>并且，这两种方式是可以组合使用的。如果使用了格式化占位符，而提供的参数的个数多于占位符的个数，那么，多余的参数会以空格分隔的方式附加在字符串后面，就像：<br />
console.log(&#8221;I am %s and I have:&#8221;, myName, thing1, thing2, thing3);</p>
<p>如果参数是一个Javascript对象，那么在控制台输出的就不是静态文字，而是一个可交互的超链接，点击超链接可以查看该对象的HTML, CSS, Script, DOM窗口，可用格式化字符串%o代替Javascript对象。<br />
console.log(&#8221;Body tag is %o&#8221;, document.body);</p>
<p>格式化字符串列表：<br />
格式化字符串 类型<br />
%s 字符串<br />
%d, %i 整型（暂不支持数字型）<br />
%f 浮点型 （暂不支持数字型）<br />
%o 链接对象</p>
<p>console.debug(object[, object, ...])<br />
在控制台输出一条消息，包含一个指向代码调用位置的超链接。假如是直接在控制台输入该命令，就不会出现超链接（和console.log()一样）。</p>
<p>console.info(object[, object, ...])<br />
在控制台输出一条带有“信息”图标的消息和一个指向代码调用位置的超链接。</p>
<p>console.warn(object[, object, ...])<br />
在控制台输出一条带有“警告”图标的消息和一个指向代码调用位置的超链接。</p>
<p>console.error(object[, object, ...])<br />
在控制台输出一条带有“错误”图标的消息和一个指向代码调用位置的超链接。</p>
<p>console.assert(expression[, object, ...])<br />
测试表达式expression是否为真。如果不是真，会在控制台写一条消息并抛出异常</p>
<p>console.dir(object)<br />
以列表形式输出一个对象的所有属性，有点和你查看DOM窗口相类似。</p>
<p>console.dirxml(node)<br />
输出一个HTML或者XML元素的XML源代码。和你在HTML窗口看到的相似。</p>
<p>console.trace()<br />
Prints an interactive stack trace of JavaScript execution at the point where it is called.</p>
<p>The stack trace details the functions on the stack, as well as the values that were passed as arguments to each function. You can click each function to take you to its source in the Script tab, and click each argument value to inspect it in the DOM or HTML tabs.</p>
<p>console.group(object[, object, ...])<br />
输出一条消息，并打开一个嵌套块，块中的内容都会缩进。调用console.groupEnd() 关闭块。该命令可以嵌套使用。</p>
<p>console.groupEnd()<br />
关闭最近一个由console.group打开的块。</p>
<p>console.time(name)<br />
创建一个名字为name的计时器，调用console.timeEnd(name) 停止计时器并输出所耗时间（毫秒）。</p>
<p>console.timeEnd(name)<br />
停止同名的计时器并输出所耗时间（毫秒）。</p>
<p>console.profile([title])<br />
打开Javascript性能测试开关。可选参数title会在打印性能测试报告时在报告的开头输出。</p>
<p>console.profileEnd()<br />
关闭Javascript性能测试开关并输出报告。</p>
<p>console.count([title])<br />
Writes the number of times that the line of code where count was called was executed. The optional argument title will print a message in addition to the number of the count. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.asktest.com/blog/?feed=rss2&amp;p=279</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox下margin-top</title>
		<link>http://www.asktest.com/blog/?p=275</link>
		<comments>http://www.asktest.com/blog/?p=275#comments</comments>
		<pubDate>Tue, 11 May 2010 09:07:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[css/xhtml]]></category>
		<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://www.asktest.com/blog/?p=275</guid>
		<description><![CDATA[（一）margin-top失效
   先看下面代码：

float:left
clear:both; margin-top:20px;

两个层box1和box2，box1具有浮动属性，box2没有，这时候设置box2的上边距 margin-top没有效果。


&#60;!DOCTYPE &#60;a href=&#34;http://www.blue1000.com/bkhtml/c22/&#34; target=&#34;_blank&#34; title=&#34;HTML/JavaScript教程&#34;&#62;
&#60;html&#62;
&#60;head&#62;
&#60;meta http-equiv=&#34;Content-Type&#34; content=&#34;text/html; charset=utf-8&#34; /&#62;
&#60;title&#62;Firefox下margin-top问题&#60;/title&#62;
&#60;style type=&#34;text/css&#34;&#62;
&#60;!--
* {
margin:0;
padding:0;
}
.box1{
float:left;
width:500px;
height:100px;
background:#999;
}
.box2{
margin-top:20px;
width:500px;
height:50px;
background:#000;
color:#fff;
clear:both;
}
--&#62;
&#60;/style&#62;
&#60;/head&#62;
&#60;body&#62;
&#60;div&#62;
&#60;div class=&#34;box1&#34; &#62;float:left&#60;/div&#62;
&#60;div class=&#34;box2&#34;&#62;clear:both; margin-top:20px;&#60;/div&#62;
&#60;/div&#62;
&#60;/body&#62;
&#60;/html&#62;

  提示：你可以先修改部分代码再运行。

网上能找到的两种比较靠谱的解释：1：“在css2.1中，水平的margin不会被折叠；垂直margin可能在一些盒模型中被折叠…”2：当第一个层浮动，而第二个没浮动层的margin会被压缩，详见&#8211;浮动元素后非浮动元素的margin的处理（ 地址 ）。
得到解决问题思路：要浮动一起浮动，要就一起不浮动。
解决办法：
1.box2增加float属性
2.box1与box2之间增加一层&#8221;

&#8221;
（二）子元素设置margin-top作用于父容器
当给box2设置margin-top时，在FF下仅作用于父容器。


&#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Transitional//EN&#34; &#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#34;&#62;
&#60;html xmlns=&#34;http://www.w3.org/1999/xhtml&#34;&#62;
&#60;head&#62;
&#60;meta http-equiv=&#34;Content-Type&#34; content=&#34;text/html; charset=utf-8&#34; /&#62;
&#60;title&#62;Firefox下margin-top问题&#60;/title&#62;
&#60;style type=&#34;text/css&#34;&#62;
&#60;!--
* {
margin:0;
padding:0;
}
.box2{
margin-top:20px;
width:500px;
height:50px;
background:#000;
color:#fff;
}
--&#62;
&#60;/style&#62;
&#60;/head&#62;
&#60;body&#62;
&#60;div class=&#34;box&#34; style=&#34;height:100px;background:red;&#34;&#62;
&#60;div class=&#34;box2&#34;&#62;clear:both; margin-top:20px;height:50px;width:500px;background:#000;&#60;/div&#62;
&#60;/div&#62;
&#60;/body&#62;
&#60;/html&#62;

  提示：你可以先修改部分代码再运行。

解决办法：
1.给父容器box加overflow:hidden;属性
2.父容器box加border除none以外的属性
3.用父容器 box的padding-top代替margin-top
自己工作中遇到的总结，可能会有不严谨的地方，如有发现希望指出！
]]></description>
			<content:encoded><![CDATA[<p>（一）margin-top失效<br />
   先看下面代码：</p>
<div>
<div class="box1" >float:left</div>
<div class="box2">clear:both; margin-top:20px;</div>
</div>
<p>两个层box1和box2，box1具有浮动属性，box2没有，这时候设置box2的上边距 margin-top没有效果。</p>
<div class="runcode">
<p><textarea name="runcode" class="runcode_text" id="runcode_QdJnae">
&lt;!DOCTYPE &lt;a href=&quot;http://www.blue1000.com/bkhtml/c22/&quot; target=&quot;_blank&quot; title=&quot;HTML/JavaScript教程&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;title&gt;Firefox下margin-top问题&lt;/title&gt;
&lt;style type=&quot;text/css&quot;&gt;
&lt;!--
* {
margin:0;
padding:0;
}
.box1{
float:left;
width:500px;
height:100px;
background:#999;
}
.box2{
margin-top:20px;
width:500px;
height:50px;
background:#000;
color:#fff;
clear:both;
}
--&gt;
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div&gt;
&lt;div class=&quot;box1&quot; &gt;float:left&lt;/div&gt;
&lt;div class=&quot;box2&quot;&gt;clear:both; margin-top:20px;&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode_open_new('runcode_QdJnae');"/> <input type="button" value="复制" class="runcode_button" onclick="runcode_copy('runcode_QdJnae');"/> 提示：你可以先修改部分代码再运行。</p>
</div>
<p>网上能找到的两种比较靠谱的解释：1：“在css2.1中，水平的margin不会被折叠；垂直margin可能在一些盒模型中被折叠…”2：当第一个层浮动，而第二个没浮动层的margin会被压缩，详见&#8211;浮动元素后非浮动元素的margin的处理（ 地址 ）。</p>
<p>得到解决问题思路：要浮动一起浮动，要就一起不浮动。</p>
<p>解决办法：</p>
<p>1.box2增加float属性<br />
2.box1与box2之间增加一层&#8221;
<div style="clear:both;"></div>
<p>&#8221;</p>
<p>（二）子元素设置margin-top作用于父容器</p>
<p>当给box2设置margin-top时，在FF下仅作用于父容器。</p>
<div class="runcode">
<p><textarea name="runcode" class="runcode_text" id="runcode_9T1ikL">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;title&gt;Firefox下margin-top问题&lt;/title&gt;
&lt;style type=&quot;text/css&quot;&gt;
&lt;!--
* {
margin:0;
padding:0;
}
.box2{
margin-top:20px;
width:500px;
height:50px;
background:#000;
color:#fff;
}
--&gt;
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;box&quot; style=&quot;height:100px;background:red;&quot;&gt;
&lt;div class=&quot;box2&quot;&gt;clear:both; margin-top:20px;height:50px;width:500px;background:#000;&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></p>
<p><input type="button" value="运行" class="runcode_button" onclick="runcode_open_new('runcode_9T1ikL');"/> <input type="button" value="复制" class="runcode_button" onclick="runcode_copy('runcode_9T1ikL');"/> 提示：你可以先修改部分代码再运行。</p>
</div>
<p>解决办法：</p>
<p>1.给父容器box加overflow:hidden;属性<br />
2.父容器box加border除none以外的属性<br />
3.用父容器 box的padding-top代替margin-top</p>
<p>自己工作中遇到的总结，可能会有不严谨的地方，如有发现希望指出！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.asktest.com/blog/?feed=rss2&amp;p=275</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

