<?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>影の域 &#187; Web</title>
	<atom:link href="http://www.zfkun.com/index.php/category/code/web/feed" rel="self" type="application/rss+xml" />
	<link>http://www.zfkun.com</link>
	<description>关注web前端,追逐html5脚步,体会code人生</description>
	<lastBuildDate>Mon, 23 Apr 2012 15:09:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>KISSY DataLazyLoad组件之事件BUG</title>
		<link>http://www.zfkun.com/461.html</link>
		<comments>http://www.zfkun.com/461.html#comments</comments>
		<pubDate>Fri, 24 Feb 2012 10:58:48 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[dataLazyload]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[kissy]]></category>
		<category><![CDATA[resize]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/?p=461</guid>
		<description><![CDATA[正在随手弄一Photo App， 为了性能和效率，不得不使用LazyLoad，至此，为此BUG的浮现做好了铺垫。
为图快速制作出原型，暂且使用KISSY辅助开发，App自身只有一个重要需求： 弹性、自适应。
所以，很自然的对 windows 对象做了 Resize Event 的监听处理。 %*……（*&#038;*%%*……*（，(此处省略1000字)，coding-complete &#038;& unit-test-ok !
然后，准备添加 LazyLoad支持以提高体验和性能，降低成本。（殊不知，杯具就此发生） <a href="http://www.zfkun.com/461.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>正在随手弄一Photo App， 为了性能和效率，不得不使用LazyLoad，至此，为此BUG的浮现做好了铺垫。</p>
<p>为图快速制作出原型，暂且使用KISSY辅助开发，App自身只有一个重要需求： 弹性、自适应。</p>
<p>所以，很自然的对 windows 对象做了 Resize Event 的监听处理。<span style="color: #33cccc;"> %*……（*&amp;*%%*……*（，(此处省略<span style="color: #ff0000;">1000</span>字)</span>，coding-complete &amp;&amp; unit-test-ok !</p>
<p>然后，准备添加 LazyLoad支持以提高体验和性能，降低成本。（殊不知，杯具就此发生）</p>
<p><span style="color: #33cccc;">）*）*（）……&amp;（……&amp;*%&amp;**（此处省略<span style="color: #ff0000;">1000</span>字）</span>，coding-complete &amp;&amp; unit-test-ok !</p>
<p>准备 save &amp;&amp; comit, 随着不经意的窗口Scroll 到底部 &amp; Resize ，我hold住了。。。。。</p>
<p>自适应能力貌似费了，<span style="color: #33cccc;"> &amp;（*（）*——（——*）…………*（*（此处省略<span style="color: #ff0000;">1W</span>字）</span></p>
<p>好吧，我知道，一般都是我的问题，遂，加入以下调试代码块辅助检查：</p>
<pre name="code" class="js">window.addEventListener('resize', function(){ console.info('Native Resize Event fire !!') }, false);</pre>
<p>。。。结果出乎意料，冇反应。</p>
<p>直觉告诉，应该是KISSY在跟我开玩笑。</p>
<p>可是，想不通，为什么窗口在冇完全Scroll到底之前（或者说最后一个图片未被LazyLoad加载之前），一切都那么和谐有序呢？</p>
<p>看来，Source 我不得不再一次的偷窥你了。 &#8211; -！</p>
<p>（&amp;（*（）（——）（——…………*（*&amp;（此处省略1W字）</p>
<p>经过排查，问题不在 KISSY.js 核心文件，so, 问题就极有可能存在与 DataLazyLoad 组件本身鸟。  - -!</p>
<p>终于，我找到了让我撕心裂肺的你，你藏的如此诡异，以至于无心者很难察觉你的存在：</p>
<pre name="code" class="js">var self = this, resizeHandler,
    // 加载延迟项
    loadItems = function () {
        self._loadItems();
        if (self._getItemsLength() === 0) {
            Event.remove(win, SCROLL, loader);
            Event.remove(win, RESIZE, resizeHandler);
        }
    },
    // 加载函数
    loader = S.buffer(loadItems, DURATION, this);

// scroll 和 resize 时，加载图片
Event.on(win, SCROLL, loader);
Event.on(win, RESIZE, function () { self.threshold = self._getThreshold(); loader(); });</pre>
<p>从以上代码块，可以看出悲催的 resizeHandler 变量忘记赋值鸟！！！造成 Event.remove(win, RESIZE, resizeHandler) 的影响扩大到了全局，说白了，就是所有的resize 监听器都被瞬间释放鸟，世界清静了。。。。</p>
<p>既然，code里寻你千百行，我也不能让你就在那变量定义处。</p>
<p>fix 就很明了了：</p>
<pre name="code" class="js">Event.on(win, RESIZE, resizeHandler = function () { self.threshold = self._getThreshold(); loader(); });</pre>
<p>为了直观，提供2个简易DEMO来对比。</p>
<p><a title="原始带bug" href="http://www.zfkun.com//demo/kissy/KISSY_DataLazyLoad_bug.html" target="_blank">原始BUG</a>     <a title="修正后无BUG" href="http://www.zfkun.com//demo/kissy/KISSY_DataLazyLoad_bug_fixed.html" target="_blank">修正后</a></p>

	标签：<a href="http://www.zfkun.com/tag/bug" title="bug" rel="tag">bug</a>, <a href="http://www.zfkun.com/tag/datalazyload" title="dataLazyload" rel="tag">dataLazyload</a>, <a href="http://www.zfkun.com/tag/event" title="event" rel="tag">event</a>, <a href="http://www.zfkun.com/tag/kissy" title="kissy" rel="tag">kissy</a>, <a href="http://www.zfkun.com/tag/resize" title="resize" rel="tag">resize</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/159.html" title="如何在事件代理中正确使用 focus 和 blur 事件 (2011 年 01 月 13 日)" data-comment="0">如何在事件代理中正确使用 focus 和 blur 事件</a></li>
	<li><a href="http://www.zfkun.com/275.html" title="[转]IE6、IE7、IE8 CSS Bug兼容解决记录 (2011 年 06 月 14 日)" data-comment="1">[转]IE6、IE7、IE8 CSS Bug兼容解决记录</a></li>
	<li><a href="http://www.zfkun.com/344.html" title="WordPress 中文Tag 显示404错误的BUG修正 (2011 年 07 月 07 日)" data-comment="0">WordPress 中文Tag 显示404错误的BUG修正</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/461.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Path UI by CSS3</title>
		<link>http://www.zfkun.com/454.html</link>
		<comments>http://www.zfkun.com/454.html#comments</comments>
		<pubDate>Tue, 06 Dec 2011 06:44:20 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/?p=454</guid>
		<description><![CDATA[Path的UI惊起哇声一片，最大的亮点无疑是左下角的菜单展开效果。于是有各个版本的仿Path菜单出现，比如我们之前报道过的国内某牛人的作品，这里还有若干个关于Path菜单的讨论。但最引人注意的还是来自法国小伙Victor的作品：用纯CSS3制作的Path菜单效果。

他说他喜欢Path的新界面，尤其是添加菜单，作为一个前端设计师的他打算在浏览器里实现同样的效果。 <a href="http://www.zfkun.com/454.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Path的UI惊起哇声一片，最大的亮点无疑是左下角的菜单展开效果。于是有各个版本的仿Path菜单出现，比如我们之前报道过的<a title="新版Path的漂亮菜单UI已被开源" href="http://www.36kr.com/p/64382.html">国内某牛人的作品</a>，这里还有若干个<a href="http://www.v2ex.com/t/22743" rel="external nofollow" target="_blank">关于Path菜单的讨论</a>。但最引人注意的还是来自法国小伙<a href="https://twitter.com/#!/_victa" rel="external nofollow" target="_blank">Victor</a>的作品：用纯CSS3制作的Path菜单效果。</p>
<p>他说他喜欢Path的新界面，尤其是添加菜单，作为一个前端设计师的他打算在浏览器里实现同样的效果。以下是他制作的一段视频：</p>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XMzI5MjI5OTky/v.swf" /><param name="quality" value="high" /><param name="allowscriptaccess" value="sameDomain" /><param name="allowfullscreen" value="true" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XMzI5MjI5OTky/v.swf" quality="high" allowscriptaccess="sameDomain" allowfullscreen="true" /></object></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>整个作品通过html/css3完成，没有使用任何图片，没有任何javascript。因此仅支持Webkit浏览器。Victor通过Sass+Compass计算每个图标的坐标，并生成了动画效果。你不用重写代码就可以添加或删除项目。</p>
<p>实际效果请移步至<a href="http://lab.victorcoulon.fr/css/path-menu/" rel="external nofollow" target="_blank">这里</a>，你可以在github上找到<a href="https://github.com/victa/path-menu" rel="external nofollow" target="_blank">这段源代码</a>。</p>
<p>&nbsp;</p>
<p>本文转载来自<a title="用纯CSS3做成的Path菜单效果" href="http://www.36kr.com/p/65100.html" rel="bookmark">36氪</a></p>

	标签：<a href="http://www.zfkun.com/tag/android" title="android" rel="tag">android</a>, <a href="http://www.zfkun.com/tag/css3" title="css3" rel="tag">css3</a>, <a href="http://www.zfkun.com/tag/iphone" title="iphone" rel="tag">iphone</a>, <a href="http://www.zfkun.com/tag/path" title="path" rel="tag">path</a>, <a href="http://www.zfkun.com/tag/ui" title="ui" rel="tag">ui</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/445.html" title="移动 Web 开发平台 Rexsee 开源 (2011 年 10 月 28 日)" data-comment="0">移动 Web 开发平台 Rexsee 开源</a></li>
	<li><a href="http://www.zfkun.com/366.html" title="Market Enabler &#8211; Android越狱改区利器 (2011 年 07 月 10 日)" data-comment="2">Market Enabler &#8211; Android越狱改区利器</a></li>
	<li><a href="http://www.zfkun.com/html5" title="HTML5 (2011 年 06 月 03 日)" data-comment="0">HTML5</a></li>
	<li><a href="http://www.zfkun.com/377.html" title="Google+ for Android 安装 (2011 年 07 月 10 日)" data-comment="0">Google+ for Android 安装</a></li>
	<li><a href="http://www.zfkun.com/372.html" title="apk文件的MIME类型 (2011 年 07 月 10 日)" data-comment="0">apk文件的MIME类型</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/454.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>移动 Web 开发平台 Rexsee 开源</title>
		<link>http://www.zfkun.com/445.html</link>
		<comments>http://www.zfkun.com/445.html#comments</comments>
		<pubDate>Fri, 28 Oct 2011 09:30:04 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[open]]></category>
		<category><![CDATA[Rexsee]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/?p=445</guid>
		<description><![CDATA[国内移动Web开发平台Rexsee正式开源，其开发者社区也于本周上线。访问社区可以查看详细开发手册、API说明与示例以及全部源码，并可在线编译免费生成移动应用客户端。 <a href="http://www.zfkun.com/445.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>国内移动Web开发平台Rexsee正式开源，其开发者社区也于本周上线。访问社区可以查看详细开发手册、API说明与示例以及全部源码，并可在线编译免费生成移动应用客户端。</em></p>
<p>伴随着HTML5的发展以及Web App的广受认可，基于Web的移动应用开发已经受到了技术厂商与开发者的普遍关注。大量的Web框架纷纷转投移动应用领域，近期反响最大的无疑是由 ExtJS、jQTouch 以及 Raphael合并而成的Sencha，以及被Adobe收购的PhoneGap。Mozilla也于上月宣布计划构建 WebAPI，用于在浏览器中调用移动设备功能。</p>
<p>基于类似的技术理念，国内的Rexsee团队已提供了整体的移动应用“开发平台”，并于今年5月开始面向企业级应用市场推广。</p>
<p>Rexsee产品以Webkit为内核，全面支持HTML5。通过扩展超过1500个API，以Javascript实现对移动终端的功能调用，强化HTML5在浏览器之外的移动终端功能实现。开发者可以使用HTML、CSS和Javascript快速实现移动应用，并通过原生化应用转换功能，直接生成应用程序。</p>
<p>不同于国际范围的其他移动Web开发框架，Rexsee并不过度追求跨平台特性。在深度支持Android原生功能的前提下，采用全部同步的开发方式，并在执行效率上有显著提升。</p>
<p>Rexsee的开源策略旨在让更多的开发人员可以迅速的进入到移动互联网领域，基于标准化的Web开发方式快速实现移动应用。结合之前所积累的大量应用，Rexsee开发者社区在上线第一天，就已有246个应用得以审核推出，并且还在持续增加。</p>
<p>作为国内唯一开源的移动Web开发平台，Rexsee定位于服务移动应用开发者的技术平台提供方，力图为移动应用创新发展打造更加广泛坚实的开发者基础。</p>
<p>&nbsp;</p>
<p>原文： <a href="http://www.oschina.net/news/22624/raxsee-opensource">http://www.oschina.net/news/22624/raxsee-opensource</a></p>

	标签：<a href="http://www.zfkun.com/tag/android" title="android" rel="tag">android</a>, <a href="http://www.zfkun.com/tag/ios" title="ios" rel="tag">ios</a>, <a href="http://www.zfkun.com/tag/open" title="open" rel="tag">open</a>, <a href="http://www.zfkun.com/tag/rexsee" title="Rexsee" rel="tag">Rexsee</a>, <a href="http://www.zfkun.com/tag/source" title="source" rel="tag">source</a>, <a href="http://www.zfkun.com/tag/web-2" title="web" rel="tag">web</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/388.html" title="window.open() 之句柄保持和重连 (2011 年 07 月 14 日)" data-comment="0">window.open() 之句柄保持和重连</a></li>
	<li><a href="http://www.zfkun.com/454.html" title="Path UI by CSS3 (2011 年 12 月 06 日)" data-comment="0">Path UI by CSS3</a></li>
	<li><a href="http://www.zfkun.com/366.html" title="Market Enabler &#8211; Android越狱改区利器 (2011 年 07 月 10 日)" data-comment="2">Market Enabler &#8211; Android越狱改区利器</a></li>
	<li><a href="http://www.zfkun.com/377.html" title="Google+ for Android 安装 (2011 年 07 月 10 日)" data-comment="0">Google+ for Android 安装</a></li>
	<li><a href="http://www.zfkun.com/372.html" title="apk文件的MIME类型 (2011 年 07 月 10 日)" data-comment="0">apk文件的MIME类型</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/445.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress Rewrite SEO 之404方式折腾笔记</title>
		<link>http://www.zfkun.com/417.html</link>
		<comments>http://www.zfkun.com/417.html#comments</comments>
		<pubDate>Sun, 17 Jul 2011 10:10:57 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[杂七杂八]]></category>
		<category><![CDATA[404]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[rewrite]]></category>
		<category><![CDATA[seo]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/?p=417</guid>
		<description><![CDATA[    WordPress 是多么强大的Blog（甚至可以说CMS）系统就不用多说了。说到底我把WP只看做一个开发起步的框架而已，更多的性能及功能的挖掘和利用还是需要自己去完成。
    最近折腾 HTML5探索 的SEO时，想起来我的博客依旧还没做过SEO，遂就开始了下面记录中的折腾回忆录。
    空间是虚拟主机（还是WIN + IIS）、无Rewrite、无子域名等等，在诸多的不利因素下，对于强大的WordPress来说，依旧能找到较好的优化方式: 404 Rewrite。SO, 就开始大面积的调整程序 + hack, 终于算完成了现在的Rewrite，真是累死我也。（做了一大堆复杂的兼容工作，历史原因害死人呀！） <a href="http://www.zfkun.com/417.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>WordPress 是多么强大的Blog（甚至可以说CMS）系统就不用多说了。说到底我把WP只看做一个开发起步的框架而已，更多的性能及功能的挖掘和利用还是需要自己去完成。<br />
最近折腾 <a title="HTML5探索" href="http://html5.so" target="_blank">HTML5探索</a> 的SEO时，想起来我的博客依旧还没做过SEO，遂就开始了下面记录中的折腾回忆录。<br />
空间是虚拟主机（还是WIN + IIS）、无Rewrite、无子域名等等，在诸多的不利因素下，对于强大的WordPress来说，依旧能找到较好的优化方式: 404 Rewrite<br />
so, 就开始大面积的调整程序 + hack 终于算完成了现在的Rewrite，真是累死我也。（做了一大堆复杂的兼容工作，历史原因害死人呀！）<br />
经过亲身体验，需要提醒下使用 404 Rewrite 前要明确站点是否为新建站点，若是，一切很easy，若不是，就有了我下面的那么多兼容工作要做，悲催！！<br />
正常的对于新建站点（404支持设置为php页面前提），因为站点较新搜索引擎还未开始收录，对外分享也几乎为0。所以需要做的就相对很少，编写好404.php的处理代码，后台做好配置即可。<br />
而有时候（其实就是我现在啦- -）, 站点运行很长时间（几年了），期间经历过无数的配置调整（还有数据丢失，我擦！），对于各种URL已经产生了很多种版本，所以需要做的工作就非常多了。<br />
由于已经过了2天了，具体顺序都不清楚了，这里仅做下回忆录式笔记，以防以后不备之需（身在天朝，谁知哪天又天灾人祸呀！）：</p>
<h3>涉及文件修改列表：</h3>
<blockquote><p>/404.php     /index.php     /blog/index.php</p></blockquote>
<h3>修改回忆录：</h3>
<p>1. /blog/index.php -&gt; /blog/index.php.bak 说白了就是备份<br />
2. 新建 /blog/index.php, 编写一些兼容处理代码:</p>
<pre name="code" class="php">&lt;?php
// zfkun.com to www.zfkun.com
if ( $_SERVER["HTTP_HOST"] === "zfkun.com") {
doRedirect("http://www.");
} else {

// 对所有原有效URL规则做301永久重定向，从而兼容原旧历史路径
$_qu = str_replace('/blog/index.php', '', $_SERVER['REQUEST_URI']);
$_SERVER["REQUEST_URI"] = (empty($_qu) || $_qu == "") ? '/' : $_qu;
doRedirect();
}

function doRedirect($prefix = "http://") {
header( "HTTP/1.1 301 Moved Permanently" );
header("Location: " . $prefix . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] );
}
?&gt;</pre>
<p>3. cp /blog/index.php.bak /index.php, 然后增加兼容处理:</p>
<pre name="code" class="php">&lt;?php
    // zfkun.com to www.zfkun.com
    if ( $_SERVER["HTTP_HOST"] === "zfkun.com" ) {
    header( "HTTP/1.1 301 Moved Permanently" );
    header("Location: " . "http://www." . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] );
    exit;
} else {

	/**
	 * 对 /index.php/archives/* 形式URL做下过滤(历史原因)
	 *    增加对一些特殊路径的兼容纠错,如：
	 *        http://www.zfkun.com/index.php/archives/category/code/javascript
	 *        http://www.zfkun.com/index.php/archives/tag/javascript
	 *        http://www.zfkun.com/index.php/archives/205.html
	 */
	if (strpos($_SERVER['REQUEST_URI'], '/index.php') === 0) {
		$_qu = str_replace( '/archives', '', str_replace('/index.php', '', $_SERVER['REQUEST_URI']) );
		if (!empty($_qu)) {
                    // 修正对 /index.php/archives/239 此类地址解析时忘记补充 .html 造成的BUG
		    if (strpos($_qu, '.html') === false) {
		        // '/205' =&gt; '/205.html'
		         $_qu = preg_replace('/^\/(\d+)/', '$0.html', $_qu);
		    }
		    $_SERVER['PATH_INFO'] = $_SERVER["REQUEST_URI"] = $_qu;
		}
	}
}

// 解决 WordPress的中文路径在WIN + IIS 下的解析错误问题
$_SERVER['PATH_INFO'] = mb_convert_encoding($_SERVER['PATH_INFO'],"UTF-8","GBK");
$_SERVER['REQUEST_URI'] = mb_convert_encoding($_SERVER['REQUEST_URI'], "UTF-8", "GBK");
.....
?&gt;</pre>
<p>4. 新建 /404.php 并设置虚拟主机404错误跳转至它，代码摘要：</p>
<pre name="code" class="php">&lt;?php
/**
 * 重置 $_SERVER['REQUEST_URI'] 为期望访问的值
 * 如：
 *    当前访问  http://www.zfkun.com/date/2010/01 ,
 *    则 404 跳转来的 $_SERVER['QUERY_STRING'] === '404;http://www.zfkun.com:80/date/2010/01'
 */
$_SERVER['REQUEST_URI'] = substr($_SERVER['QUERY_STRING'], strpos($_SERVER['QUERY_STRING'], ':80') + 3);

// blog rule 标志位
$isBlogRule = false;

if (strpos($_SERVER['REQUEST_URI'], '/blog') === 0) {
    $_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'], 5);
    $isBlogRule = true;
}

if ($isBlogRule) {
    $_SERVER['REQUEST_URI'] = str_replace('/index.php', '', $_SERVER['REQUEST_URI']);

   /**
    *    /blog/archives/205
    *    /blog/archives/tag/php
    *    /blog/tag/php
    *    /blog/archives/category/code/php
    *    /blog/category/code/php
    */
   if (strpos($_SERVER['REQUEST_URI'], '/archives/') === 0) {
       $_SERVER['REQUEST_URI'] = str_replace('/archives/', '/', $_SERVER['REQUEST_URI']);
   }

    /**
     *  对非静态化后缀的形式进行过滤检测:
     *     可能为: '/blog/205'
     */
    if (strpos($_SERVER['REQUEST_URI'], '.html') === false) {
        // '/205' =&gt; '/205.html'
        $_SERVER['REQUEST_URI'] = preg_replace('/^\/(\d+)/', '$0.html', $_SERVER['REQUEST_URI']);
    }

   /**
    * 检测 queryString 和 hash， 非空需特殊处理
    */
    if (strpos($_SERVER['REQUEST_URI'], '?') === 0 || strpos($_SERVER['REQUEST_URI'], '#') === 0) {
        $_SERVER['REQUEST_URI'] = '/index.php' . $_SERVER['REQUEST_URI'];
        $_SERVER['PATH_INFO'] = '';
    } else {
        $_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];
    }

    /**
     * 修正因 404 带来的 wordpress内置分页算法的链接错误问题
     * 比如:
     *   访问 http://www.zfkun.com/date/2010/01 时，上一页本来期望是http://www.zfkun.com/date/2010/01/page/2
     *   而实际，因为使用的404 rewrite技术，上一页链接却成了http://www.zfkun.com:80;/date/2010/01/page/3
     *   这是因为wp内置的分页算法直接使用了 $_SERVER['QUERY_STRING'] 和 $_SERVER["SCRIPT_NAME"] 来生成链接地址，
     *   当前因为是404状态下，所以 $_SERVER['QUERY_STRING'] = '404;http://www.zfkun.com:80/date/2010/01';
     * 注意:
     *   仅修改 $_SERVER['QUERY_STRING'] = '' 的话，并解决不了问题，因为当前执行脚本文件为/404.php 从而会导致
     *   生成的链接到  http://www.zfkun.com/404.php/date/2010/01 上去
     *   所以，必须还要重置 $_SERVER['SCRIPT_NAME'] = '/index.php' 从而让WP内置处理逻辑运行正常
     */
    $_SERVER['QUERY_STRING'] = '';
    $_SERVER["SCRIPT_NAME"] = '/index.php';

    // 启动博客主程序
...
} else {
// 真正的 404 处理
...
}
?&gt;</pre>
<p>5. 必须地，后台-&gt;固定链接-&gt;自定义结构 更新值为 /%post_id%.html<br />
这里又发现一个让我很郁闷的问题，若自定义结构使用的形如 /archives/%post_id%.html 或之前的 /index.php/archives/%post_id%<br />
则， 分类 和 标签的 路由默认也会增加这个前缀 /archives/tag/* /archives/category/* 擦，之前历史遗留的2种兼容结构，就是因为这个问题导致的，无奈。</p>
<p>6. 其余的乱七八糟的兼容，模糊了，回头想起来补记下</p>
<p>其实，做的工作远比现在记录的要多，只是让我印象深刻（那是好听的，其实我想说恶心的）的是这些。回头有时间继续更新好了。今天就先到这。</p>

	标签：<a href="http://www.zfkun.com/tag/404" title="404" rel="tag">404</a>, <a href="http://www.zfkun.com/tag/hack" title="hack" rel="tag">hack</a>, <a href="http://www.zfkun.com/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.zfkun.com/tag/rewrite" title="rewrite" rel="tag">rewrite</a>, <a href="http://www.zfkun.com/tag/seo" title="seo" rel="tag">seo</a>, <a href="http://www.zfkun.com/tag/wordpress" title="wordpress" rel="tag">wordpress</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/344.html" title="WordPress 中文Tag 显示404错误的BUG修正 (2011 年 07 月 07 日)" data-comment="0">WordPress 中文Tag 显示404错误的BUG修正</a></li>
	<li><a href="http://www.zfkun.com/135.html" title="挑战 hax.tor.hu 申请带ssh的免费php+mysql空间 (2010 年 03 月 19 日)" data-comment="0">挑战 hax.tor.hu 申请带ssh的免费php+mysql空间</a></li>
	<li><a href="http://www.zfkun.com/39.html" title="基于OpenCV的PHP图像人脸识别技术 (2010 年 01 月 16 日)" data-comment="0">基于OpenCV的PHP图像人脸识别技术</a></li>
	<li><a href="http://www.zfkun.com/223.html" title="动态生成windows快捷方式文件 (2011 年 04 月 02 日)" data-comment="0">动态生成windows快捷方式文件</a></li>
	<li><a href="http://www.zfkun.com/74.html" title="wp_list_categories()参数说明 (2010 年 01 月 18 日)" data-comment="0">wp_list_categories()参数说明</a></li>
	<li><a href="http://www.zfkun.com/179.html" title="WordPress 3.1升级后无法访问 (2011 年 03 月 20 日)" data-comment="0">WordPress 3.1升级后无法访问</a></li>
	<li><a href="http://www.zfkun.com/102.html" title="Windows 下 Nginx + PHP5 的安装与配置 (2010 年 01 月 28 日)" data-comment="0">Windows 下 Nginx + PHP5 的安装与配置</a></li>
	<li><a href="http://www.zfkun.com/35.html" title="PHP CURL函数库 (2010 年 01 月 16 日)" data-comment="0">PHP CURL函数库</a></li>
	<li><a href="http://www.zfkun.com/95.html" title="Nginx 0.8.x + PHP 5.2.10（FastCGI）搭建胜过Apache十倍的Web服务器（第5版） (2010 年 01 月 28 日)" data-comment="0">Nginx 0.8.x + PHP 5.2.10（FastCGI）搭建胜过Apache十倍的Web服务器（第5版）</a></li>
	<li><a href="http://www.zfkun.com/366.html" title="Market Enabler &#8211; Android越狱改区利器 (2011 年 07 月 10 日)" data-comment="2">Market Enabler &#8211; Android越狱改区利器</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/417.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[转]利用跨域资源共享（CORS）实现ajax跨域调用</title>
		<link>http://www.zfkun.com/394.html</link>
		<comments>http://www.zfkun.com/394.html#comments</comments>
		<pubDate>Fri, 15 Jul 2011 05:14:06 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[cors]]></category>
		<category><![CDATA[credentialed]]></category>
		<category><![CDATA[crossdomain]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[orign]]></category>
		<category><![CDATA[preflighted]]></category>
		<category><![CDATA[XDomainRequest]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=394</guid>
		<description><![CDATA[几年前，网站开发者都因为ajax的同源策略而撞了南墙。当我们惊叹于XMLHttpRequest对象跨浏览器支持所带来的巨大进步时，我们很快发现没有一个方法可以使我们用JavaScript实现请求跨域访问，对此我们哀叹不已。每个人在他们自己的网站上建立代理来摆脱这种限制。虽然开发者利用服务器代理和其它技巧避开了这种限制，而在社区的抗议者允许ajax在本地跨域调用。许多人还没意识到当前几乎所有的浏览器（Internet Explorer 8+， Firefox 3.5+， Safari 4+和 Chrome）都可通过名为Cross-Origin Resource Sharing的协议支持ajax跨域调用。 <a href="http://www.zfkun.com/394.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>几年前，网站开发者都因为ajax的<a title="Same origin policy for Javascript" href="https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript" target="_blank">同源策略</a>而撞了南墙。当我们惊叹于XMLHttpRequest对象跨浏览器支持所带来的巨大进步时，我们很快发现没有一个方法可以使我们用<strong>JavaScript实现请求跨域</strong>访问，对此我们哀叹不已。每个人在他们自己的网站上建立代理（which was the onset of a new host of open redirect problems）来摆脱这种限制。虽然开发者利用服务器代理和其它技巧避开了这种限制，而在社区的抗议者允许ajax在本地跨域调用。许多人还没意识到当前几乎所有的浏览器（Internet Explorer 8+， Firefox 3.5+， Safari 4+和 Chrome）都可通过名为<strong>Cross-Origin Resource Sharing</strong>的协议支持ajax跨域调用。</p>
<h3>跨域资源共享（CORS）</h3>
<p><a title="" href="http://www.w3.org/TR/access-control/" target="_blank">Cross-Origin Resource Sharing</a> (<strong>CORS</strong>)是W3c工作草案，它定义了在跨域访问资源时浏览器和服务器之间如何通信。CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方，从而决定请求或响应成功与否。</p>
<p>对一个简单的请求，没有自定义头部，要么使用GET，要么使用POST，它的主体是text/plain,请求用一个名叫Orgin的额外的头部发送。Origin头部包含请求页面的头部（协议，域名，端口），这样服务器可以很容易的决定它是否应该提供响应。</p>
<blockquote><p>Origin: http://www.nczonline.net</p></blockquote>
<p>如果服务器确定请求被通过，它将发送一个Access-Control-Allow-Origin头部响应发送请求的同一个源，如果是一个公共资源，则返回“*”。如：</p>
<blockquote><p>Access-Control-Allow-Origin: http://www.nczonline.net</p></blockquote>
<p>如果头部丢失，或者源不匹配，那么浏览器将拒绝请求。如果一切顺利，浏览器将处理请求。注意，请求和响应都不包括cookie信息。</p>
<p>先前提到的所有浏览器都支持这些简单的请求。FF3.5 +，Safari 4和chrome通过使用XMLHttpRequest对象支持其使用。当尝试在不同域打开一个资源时，不需任何代码，这个行为会自动触发。如：</p>
<pre name="code" class="js">var xhr = new XMLHttpRequest();
xhr.open("get", "http://www.nczonline.net/some_resource/", true);
xhr.onload = function(){  //instead of onreadystatechange
    //do something
};
xhr.send(null);</pre>
<p>在IE8中也是一样，用同样的方式你需要使用<a title="XDomainRequest Object" href="http://msdn.microsoft.com/en-us/library/cc288060%28VS.85%29.aspx" target="_blank">XDomainRequest object</a>。</p>
<pre name="code" class="js">var xdr = new XDomainRequest();
xdr.open("get", "http://www.nczonline.net/some_resource/");
xdr.onload = function(){
    //do something
};
xdr.send();</pre>
<p>Mozilla小组在他们关于<a title="" href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/" target="_blank">CORS的留言</a>中建议应该检查withCredentials属性的存在性，从而决定浏览器是否通过XHR支持CORS。你可以合并<strong>XDomainRequest </strong>对象的存在性来支持所有的浏览器：</p>
<pre name="code" class="js">function createCORSRequest(method, url){
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr){
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined"){
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}

var request = createCORSRequest("get", "http://www.nczonline.net/");
if (request){
    request.onload = function(){
        //do something with request.responseText
    };
    request.send();
}</pre>
<p>Firefox, Safari, 和Chrome的XMLHttpRequest对象与IE的XDomainRequest对象有着相似的充分的接口，这些模式运行的很好。常见的接口属性/方法:</p>
<ul>
<li>abort()——用来终止已在进程中请求。</li>
<li>onerror()——替代onreadystatechange方法来探测错误。</li>
<li>onload()——替代onreadystatechange方法来探测成功。</li>
<li>responseText——用来取得响应地文本。</li>
<li>send()——用来发送请求。</li>
</ul>
<h3>Preflighted请求</h3>
<p>除了GET或POST，通过一种称之为<strong>preflighted</strong>请求的服务器透明验证机制，CORS允许使用自定义的头部和方法，以及不同主体内容类型。当你尝试使用高级选项中的一个来试着建立一个请求时，这时就建立了一个preflighted请求。该请求使用可选的方法，并发送如下头部：</p>
<ul>
<li>Origin——与简单请求相同。</li>
<li>Access-Control-Request-Method——请求将要使用的方法。</li>
<li>Access-Control-Request-Headers——（可选）一个逗号分开的正被使用的自定义头部列表。</li>
</ul>
<p>例子假定一个头部自定义为NCZ的POST请求：</p>
<blockquote><p>Origin: http://www.nczonline.net<br />
Access-Control-Request-Method: POST<br />
Access-Control-Request-Headers: NCZ</p></blockquote>
<p>在请求期间，服务器能决定是否允许这类请求。服务器通过在响应中发送以下头部来与浏览器通信。</p>
<ul>
<li>Access-Control-Allow-Origin——与简单请求相同。</li>
<li>Access-Control-Allow-Methods——用逗号分开的可接受的方法列表。</li>
<li>Access-Control-Allow-Headers——用逗号分开的服务器可接受的头部列表。</li>
<li>Access-Control-Max-Age——preflighted 请求应该被缓存的时间。</li>
</ul>
<p>如：</p>
<blockquote><p>Access-Control-Allow-Origin: http://www.nczonline.net<br />
Access-Control-Allow-Methods: POST, GET<br />
Access-Control-Allow-Headers: NCZ<br />
Access-Control-Max-Age: 1728000</p></blockquote>
<p>preflighted 请求一旦作出，结果将按响应中规定的时间缓存下来；第一次做出这样的请求，你将引发一次额外的HTTP请求。</p>
<p>Firefox 3.5+, Safari 4+和Chrome都支持preflighted 请求，IE8则不支持。</p>
<h3>Credentialed请求</h3>
<p>默认状态下，跨域请求不提供证书（cookie、HTTP身份验证、客户端SSL证书）。你可以规定一个请求应该通过设置withCredentials属性为true来发送证书。如果服务器允许credentialed请求，那么它将用下面的头部作出响应：</p>
<p>如果一个<strong>credentialed</strong>请求被发送，这个头部不会作为响应地一部分被发送。浏览器不会将响应传递给JavaScript(responseText是一个空字符串，状态为0，onerror()被调用)。注意，服务器也能发送这个HTTP头部作为preflight响应的一部分，以此来表明该源允许发送credentialed请求。</p>
<blockquote><p>Access-Control-Allow-Credentials: true</p></blockquote>
<p>IE8不支持withCredentials属性，Firefox 3.5+, Safari 4+和Chrome都支持它。</p>
<h3>结论</h3>
<p>在现代web浏览器中对跨域AJAX调用有许多可靠地支持，然而，大多数开发者仍没意识这些强大的功能力。只需在JavaScript和服务器端做一点额外的工作以保证正确的头部被发送即可使用它。在允许高级请求和credentialed请求方面，IE8的执行有些滞后，但希望它对CORS的支持将会继续改进。如果你想了解更多，我强烈建议你检查<a title="" href="http://arunranga.com/examples/access-control/" target="_blank">Arun Ranganathan的示例页</a>。</p>
<h3>相关阅读</h3>
<ul>
<li><a title="Cross-domain XHR removed from Firefox 3" href="http://www.nczonline.net/blog/2008/04/27/cross-domain-xhr-removed-from-firefox-3/" target="_blank">Cross-domain XHR removed from Firefox 3</a></li>
<li><a title="Firefox 3.5/Firebug XMLHttpRequest and readystatechange bug" href="http://www.nczonline.net/blog/2009/07/09/firefox-35firebug-xmlhttprequest-and-readystatechange-bug/" target="_blank">Firefox 3.5/Firebug XMLHttpRequest and readystatechange bug</a></li>
<li><a title="Mentioned in Microsoft whitepaper" href="http://www.nczonline.net/blog/2008/07/05/mentioned-in-microsoft-whitepaper/" target="_blank">Mentioned in Microsoft whitepaper</a></li>
<li><a title="XMLHttp Requests For Ajax" href="http://www.nczonline.net/blog/2006/03/14/xmlhttp-requests-for-ajax/" target="_blank">XMLHttp Requests For Ajax</a></li>
<li><a title="Firebug" href="http://www.nczonline.net/blog/2006/03/05/firebug/" target="_blank">Firebug</a></li>
<li><a title="Web definitions: DOM, Ajax, and more" href="http://www.nczonline.net/blog/2009/09/29/web-definitions-dom-ajax-and-more/" target="_blank">Web definitions: DOM, Ajax, and more</a></li>
</ul>
<p><strong>原文地址：</strong><a title="cross domain ajax with cross origin resource sharing" href="http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/" target="_blank">http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/</a></p>

	标签：<a href="http://www.zfkun.com/tag/ajax" title="ajax" rel="tag">ajax</a>, <a href="http://www.zfkun.com/tag/cors" title="cors" rel="tag">cors</a>, <a href="http://www.zfkun.com/tag/credentialed" title="credentialed" rel="tag">credentialed</a>, <a href="http://www.zfkun.com/tag/crossdomain" title="crossdomain" rel="tag">crossdomain</a>, <a href="http://www.zfkun.com/tag/javascript" title="JavaScript" rel="tag">JavaScript</a>, <a href="http://www.zfkun.com/tag/js" title="js" rel="tag">js</a>, <a href="http://www.zfkun.com/tag/orign" title="orign" rel="tag">orign</a>, <a href="http://www.zfkun.com/tag/preflighted" title="preflighted" rel="tag">preflighted</a>, <a href="http://www.zfkun.com/tag/xdomainrequest" title="XDomainRequest" rel="tag">XDomainRequest</a>, <a href="http://www.zfkun.com/tag/xmlhttprequest" title="XMLHttpRequest" rel="tag">XMLHttpRequest</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/147.html" title="前端资源文件缓存清除一法 (2010 年 11 月 25 日)" data-comment="0">前端资源文件缓存清除一法</a></li>
	<li><a href="http://www.zfkun.com/80.html" title="[转]Google Closure: 糟糕的JavaScript (2010 年 01 月 19 日)" data-comment="0">[转]Google Closure: 糟糕的JavaScript</a></li>
	<li><a href="http://www.zfkun.com/388.html" title="window.open() 之句柄保持和重连 (2011 年 07 月 14 日)" data-comment="0">window.open() 之句柄保持和重连</a></li>
	<li><a href="http://www.zfkun.com/115.html" title="Comet—“服务器推”技术 (2010 年 03 月 03 日)" data-comment="0">Comet—“服务器推”技术</a></li>
	<li><a href="http://www.zfkun.com/154.html" title="随机颜色 (2011 年 01 月 12 日)" data-comment="0">随机颜色</a></li>
	<li><a href="http://www.zfkun.com/59.html" title="腾讯TT、遨游浏览器检测 (2010 年 01 月 16 日)" data-comment="0">腾讯TT、遨游浏览器检测</a></li>
	<li><a href="http://www.zfkun.com/55.html" title="绝对震撼!10款动感图片展示js代码 (2010 年 01 月 16 日)" data-comment="0">绝对震撼!10款动感图片展示js代码</a></li>
	<li><a href="http://www.zfkun.com/176.html" title="原生JSON.parse解析异常问题 (2011 年 03 月 18 日)" data-comment="0">原生JSON.parse解析异常问题</a></li>
	<li><a href="http://www.zfkun.com/226.html" title="Windows7下搭建Node.js环境 (2011 年 04 月 06 日)" data-comment="1">Windows7下搭建Node.js环境</a></li>
	<li><a href="http://www.zfkun.com/109.html" title="Understanding and Solving Internet Explorer Leak Patterns (2010 年 02 月 28 日)" data-comment="0">Understanding and Solving Internet Explorer Leak Patterns</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/394.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]IE6、IE7、IE8 CSS Bug兼容解决记录</title>
		<link>http://www.zfkun.com/275.html</link>
		<comments>http://www.zfkun.com/275.html#comments</comments>
		<pubDate>Tue, 14 Jun 2011 10:05:04 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[ie]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=275</guid>
		<description><![CDATA[一份值得看下的IE6、IE7、IE8 CSS Bug兼容解决记录 <a href="http://www.zfkun.com/275.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>1：li边距“无故”增加</p>
<p>任何事情都是有原因的，li边距也不例外。</p>
<p>先描述一下具体状况：有些时候li边距会突然增 加很多，值也不固定（只在IE6/IE7有这种现象），让人摸不着头脑，仔细“研究”发现是由于其低级元素ul的padding引 起，padding的上下值对li有影响，左右无影 响。所以只好笨手笨脚地把padding去掉，换成margin。这是能解决问题，但往往不是我们想要的结果，或许 还会引起其他不必要的怪现象。</p>
<p>现在终于发现解决这个问题的方法，其实很简单，既然是有ul引 起的，就设置ul的显示形式为*display:inline-block;即可，前面加*是只 针对IE6/IE7有效，其他浏览器并不渲染这个属性。</p>
<p>2：分页数字 字体用“Arial ”加粗不抖动</p>
<pre class="html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type"content="text/html; charset=gb2312"/&gt;
&lt;title&gt;无标题文档&lt;/title&gt;
&lt;link href="css/style.css"rel="stylesheet"type="text/css"/&gt;
&lt;style type="text/css"&gt;
body, ul, h1 {
font-family:Arial;
font-size:12px;
}

.page {
text-align:center;
}

.page a {
display:inline-block;
padding:5px 8px;
text-decoration:none;
border:1px solid #09F;
background-color:#0CF;
color:#FFF;
}

.page a:hover, .page .selected {
border:1px solid #CCC;
background-color:#FFF;
color:#000;
font-weight:bold;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;分页样式&lt;/h1&gt;
&lt;div&gt; &lt;a href="#"&gt;1&lt;/a&gt; &lt;a href="#"class="selected"&gt;2&lt;/a&gt; &lt;a href="#"&gt;3&lt;/a&gt; &lt;a href="#"&gt;4&lt;/a&gt; &lt;a href="#"&gt;5&lt;/a&gt;

&lt;a href="#"&gt;6&lt;/a&gt; &lt;a href="#"&gt;7&lt;/a&gt; &lt;a href="#"&gt;8&lt;/a&gt; &lt;a href="#"&gt;9&lt;/a&gt; &lt;a href="#"&gt;10&lt;/a&gt; &lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p>3：IE6 CSS选择器区分IE6</p>
<p>IE6不支持子选择器；先针对IE6使用常规申明CSS选择器，然后再用子选择器针对IE7+及其他浏览器。</p>
<pre class="css">/*IE6 专用 */
.content {color:red;}

/* 其他浏览器 */
div&gt;p .content {color:blue;}</pre>
<p>4：IE6最小高度</p>
<p>IE6 不支持min-height属性，但它却认为height就是最小高度。解决方法：</p>
<p>使用ie6不支持但其余浏览器支持的属性!important。</p>
<pre class="css">#container{min-height:200px; height:auto !important; height:200px;}</pre>
<p>5：IE6100% 高度</p>
<p>在IE6下，如果要给元素定义100%高度，必须要明确定义它的父级元素的高度，如果你需要给元素定义满屏的高度，就得先给html和body定义height:100%;。</p>
<p>6：IE6躲猫猫bug</p>
<p>在IE6和IE7下，躲猫猫bug是一个非常恼人的问题。一个撑破了容器的浮动元素，如果在他之后有不浮动的内容，并且有一些定义了:hover的链接，当鼠标移到那些链接上时，在IE6下就会触发躲猫猫。</p>
<p>解决方法很简单：</p>
<p>1.在（那个未浮动的）内容之后添加一个&lt;span style=”clear: both;”&gt; &lt;/span&gt;<br />
2.触发包含了这些链接的容器的hasLayout，一个简单的方法就是给其定义height:1%;</p>
<p>7:IE6绝对定位元素的1像素间距bug</p>
<p>IE6下的这个错误是由于进位处理误差造成（IE7已修复），当绝对定位元素的父元素高或宽为奇数时，bottom和right会<br />
产生错误。唯一的解决办法就是给父元素定义明确的高宽值，但对于液态布局没有完美的解决方法。</p>
<p>8: IE下z-index的bug</p>
<p>在IE浏览器中，定位元素的z-index层级是相对于各自的父级容器，所以会导致z-index出现错误的表现。解决方法是给其父级元素定义z-index，有些情况下还需要定义position:relative。</p>
<p>9: Overflow Bug</p>
<p>在IE6/7中，overflow无法正确的隐藏有相对定位position:relative;的子元素。解决方法就是给外包容器.wrap加上position:relative;。</p>
<p>10: 横向列表宽度bug</p>
<p>如果你使用float:left;把&lt;li&gt;横向摆列，并且&lt;li&gt;内包含的&lt;a&gt;（或其他）触发了 hasLayout，在IE6下就会有错误的表现。解决方法很简单，只需要给&lt;a&gt;定义同样的float:left;即可。</p>
<p>11: 列表阶梯bug</p>
<p>列表阶梯bug通常会在给&lt;li&gt;的子元素&lt;a&gt;使用float:left;时触发，我们本意是要做一个横向的列表(通常 是导航栏)，但IE却可能呈现出垂直的或者阶梯状。<br />
解决办法就是给&lt;li&gt;定义float:left;而非子元素&lt;a&gt;，或者 给&lt;li&gt;定义display:inline;也可以解决。</p>
<p>12: 垂直列表间隙bug</p>
<p>当我们使用&lt;li&gt; 包含一个块级子元素时，IE6(IE7也有可能)会错误地给每条列表元素（&lt;li&gt;）之间添加空隙。<br />
解决方法：把&lt;a&gt;flaot并且清除float来解决这个问题；另外一个办法就是触发&lt;a&gt;的hasLayout（如定 义高宽、使用zoom:1;）；也可以给&lt;li&gt; 定义display:inline;来解决此问题；另外还有一个极有趣的方法，给包含的文本末尾添加一个空格。</p>
<p>13: IE6调整窗口大小的 Bug</p>
<p>当把body居中放置，改变IE浏览器大小的时候，任何在body里面的相对定位元素都会固定不动了。解决办法：</p>
<p>给body定义position:relative;就行了。</p>
<p>14: 文本重复Bug</p>
<p>在IE6中，一些隐藏的元素（如注释、display:none;的元素）被包含在一个浮动元素里，就有可能引发文本重复bug。</p>
<p>解决办法：给浮动元素添加display:inline;。</p>
<p>15：链接a的title属性中的文字换行</p>
<p>啥也不说，先上个图</p>
<p>我们都知道，可以给链接a加上title属性，这样鼠标移动上去会显示title属性定义的 文字，常常用来加一些提示语句，</p>
<p>比如说点击查看详情之类的，代码形如：</p>
<p>&lt;a href=”#” title=”点击查看详情”&gt;链接xx&lt;/a&gt;</p>
<p>。之前一直没有仔细注意过这个东西。如果鼠标浮动上去要显示更多东西的话，怎么实现呢。第一 反应是jquery的tooltip插件。今天无意中发现某个学院的网站鼠标移动上去可以显示这么完整的信息，效果看起来似乎还可以，就想看看怎么做的， 找了下，没发现有Javascript脚本，再往链接的地方一看，终于让我发现了门道了：</p>
<p>&lt;a href=&#8217;#&#8217; target=”_blank” title=”标题: 关于对我校2006年至2009年发展党员工作情况进…</p>
<p>发布日期: 2010-5-31 16:05:08 类别：院务通知 点击: 139&#8243;&gt;</p>
<p>[05-31]  关于对我校2006年至2009年发展党员工作情况进…</p>
<p>&lt;/a&gt;</p>
<p>注意到了吗。。很简单，只要使用 这样的转义符号,即可实现换行。在一些tooltip要求定制性不高的情况下，这样的显示效果相 当不错，而且是浏览器原生的效果，安逸。</p>
<p>哎，虽然号称精通div+css，但是发现一些小小但是很实用的技巧自己还不知道，看来html还有很多东西可以挖掘。</p>
<p>16：如何去掉点击链接时的虚线</p>
<p>解决方案1：在&lt;a href=”http://blog.sina.com/wangfengteacher”onFocus=”this.blur()&gt; Mike blog&lt;/a&gt;</p>
<p>解决方案2：在标签中加入 hidefocus&lt;a href=”http://blog.sina.com/wangfengteacher”hidefocus&gt; Mike blog&lt;/a&gt;</p>
<p>解决方案3: 如果连接太多，可以用外部链接 .HTC 文件。如，blur.htc</p>
<p>文件内容如下：</p>
<p>&lt;public:attach event=”onfocus”</p>
<p>onevent=”makeblur()”&gt;&lt;/public:attach&gt;</p>
<p>&lt;SCRIPT language=javascript&gt;</p>
<p>function makeblur(){</p>
<p>this.blur();</p>
<p>}</p>
<p>&lt;/SCRIPT&gt;</p>
<p>在 CSS 中加入如下代码：</p>
<p>A { behavior:url(blur.htc); }</p>
<p>解决方案4 ( 推荐 )：使用CSS样式，可加入代码：a {blr:expression_r(this.onFocus=this.blur())}</p>
<p>如果是FF等浏览器的话可这样写 a{ouline:none;}</p>
<p>17:制作1px细线表格</p>
<p>解决方案1 ( 推荐)：我们只要给这个table一个border-collapse:collapse的样式，就可以达到这个效果了。</p>
<p>具体如下：</p>
<p>1、HTML结构:</p>
<p>&lt;table width=”300&#8243; border=”1&#8243; cellpadding=”0&#8243;cellspacing=”0&#8243; bordercolor=”#C0C0C0&#8243;</p>
<p>style=”border-collapse:collapse;”&gt;</p>
<p>&lt;tr&gt;</p>
<p>&lt;td&gt; &lt;/td&gt;</p>
<p>&lt;td&gt; &lt;/td&gt;</p>
<p>&lt;/tr&gt;</p>
<p>&lt;tr&gt;</p>
<p>&lt;td&gt; &lt;/td&gt;</p>
<p>&lt;td&gt; &lt;/td&gt;</p>
<p>&lt;/tr&gt;</p>
<p>&lt;tr&gt;</p>
<p>&lt;td&gt; &lt;/td&gt;</p>
<p>&lt;td&gt; &lt;/td&gt;</p>
<p>&lt;/tr&gt;</p>
<p>&lt;/table&gt;</p>
<p>18：IE6 下z-index无效</p>
<p>在CSS中，通过z-index这个属性改变层级，要让z-index起作用有个前提，就是元素的position属性要 是relative，absolute或是fixed。</p>
<p>z-index层级越高，内容越应该在上面显示。在大部分的浏览器在大部分的情况下，确实如此，但是不绝对，尤其遇到IE6。</p>
<p>1、关于效果截图的些必要说明</p>
<p>下面的不是废话，是为了更容易的理解我下面唾沫横飞的内容。</p>
<p>以下所有结果截图的大背景如下：</p>
<p>1、页面上固定不动的，一成不变的，送豪宅也不会从良的是一个黑色背景，透明度 40%，几乎满屏显示的层级为1的绝对定位层。HTML为：</p>
<p>&lt;div&gt;&lt;/div&gt;</p>
<p>对应CSS为：#blank{width:100%; height:600px; background:black; opacity:0.4; filter:alpha(opacity=40); position:absolute; left:0; top:0; z-index:1;}</p>
<p>作用是为了让层级关系一目了然。看：</p>
<p>这说明内容在z-index为1的绝对定位层之下。</p>
<p>这说明内容在z-index为1的绝对定位层之上。</p>
<p>2、页面上做对比的是美女图片，图片在半透明黑色绝对定位层的上面还是下面很容易辨别，这样，您就能够对我所说的z- index不起作用有很直观的认识了。</p>
<p>2、IE6的抱怨：浮动让我沉沦</p>
<p>现在开始真正的讲述 问题的产生，原因以及解决了。首先讲讲第一种z-index无论设置多高都不起作用情况。这种情况发生的条件有三个：1、父标签 position属性为relative；2、问题标签无position属性（不包括static）；3、问题标签含有浮动(float)属性。</p>
<p>您 可以拿下面的代码自己做个简单测试：</p>
<p>&lt;div&gt;&lt;/div&gt;</p>
<p>&lt;div style=”position:relative; z-index:9999;”&gt;</p>
<p>&lt;img style=”float:left;” src=”http://image.zhangxinxu.com/image/study/s/s256/mm2.jpg” /&gt;</p>
<p>&lt;/div&gt;</p>
<p>丫的，这z-index都9999了，层级够高吧，但是，看下面的图：</p>
<p>这一对比就知道问题了，可能有人会疑问，这会不会是IE6的relative自己感冒了，而不是浮动(float)携带 了“甲流病毒”。好，我现在去掉浮动，HTML代码如下：</p>
<p>&lt;div&gt;&lt;/div&gt;</p>
<p>&lt;div style=”position:relative; z-index:9999;”&gt;</p>
<p>&lt;img src=”http://image.zhangxinxu.com/image/study/s/s256/mm2.jpg” /&gt;</p>
<p>&lt;/div&gt;</p>
<p>结果IE6下：</p>
<p>我想，问题应该都清楚了，至于原因，我起初以为是haslayout搞的鬼，后来，用zoom一测试，发现不是（IE7 下无此bug也证明不是 haslayout的原因），似乎就是这个float会让z-index失效。由于将外部div的position:relative属性改为 absolute可以解决这一问题，我就怀疑是不是浮动让relative发生了些变化，float与relative在水平定位上可以说是近亲，会不会 是因为这两者搅和在一起所以什么“畸形”“体弱多病”就出现了。这仅是我的猜测而已，真正的原因还是去问IE6的后妈吧。</p>
<p>解决方法，解决方法有三，1、position:relative改 为position:absolute；2、去除浮动；3、浮动 元素添加position属性（如relative，absolute等）。</p>
<p>3、固执的IE6：它只认第一个爸爸</p>
<p>可能不少人知 道，这IE6下，层级的高低不仅要看自己，还要看自己的老爸这个后台是否够硬。用术语具体描述为：</p>
<p>父标签position属性为relative 或absolute时，子标签的absolute属性是相对于父标签而言的。而在IE6下，层级的表现有时候不是看子标签的z-index多高，而要看它 们的父标签的z-index谁高谁低。</p>
<p>有一定经验的人可能都知道上面的事实。但是，相信这里面很多人不知道IE6下，决定层级高低的不是当前的父标签，而是整 个DOM tree（节点树）的第一个relative属性的父标签。有时平时我们多处理一个父标签，z-index层级多而复杂的情况不多见，所以难免会有认识上 的小小偏差。</p>
<p>好，下面展示这个bug。</p>
<p>条件很简单，只要绝对定位的第一个元素的第一个爸爸，或者说是最老的那个爸爸级别的人的relative属性小于黑色半 透明层的z-index层级。例如下面的HTML代码：</p>
<p>&lt;div&gt;&lt;/div&gt;</p>
<p>&lt;div style=”position:relative;”&gt;</p>
<p>&lt;div style=”position:relative; z-index:1000;”&gt;</p>
<p>&lt;div style=”position:absolute; z-index:9999;”&gt;</p>
<p>&lt;img src=”http://image.zhangxinxu.com/image/study/s/s256/mm3.jpg” /&gt;</p>
<p>&lt;/div&gt;</p>
<p>&lt;/div&gt;</p>
<p>&lt;/div&gt;</p>
<p>可以看到，mm3图片的父标签div 是绝对定位，层级9999，比1大多了，绝对定位的父标签层级1000(10000也一样)，也比黑色半透明层的z-index:1大多了，但是，我们可 怜的IE6童鞋——</p>
<p>再看看以Firefox为代表的其他童鞋：</p>
<p>IE7与IE6有着同样的bug，原因很简单，虽然图片所在div当前的老爸层级很高(1000)，但是由于老爸的老爸 不顶用，可怜了9999如此强势的孩子没有出头之日啊！</p>
<p>知道原因解决就很轻松了，给第一任老爸添加z-index后的HTML代 码如下：</p>
<p>&lt;div&gt;&lt;/div&gt;</p>
<p>&lt;div style=”position:relative; z-index:1;”&gt;</p>
<p>&lt;div style=”position:relative; z-index:1000;”&gt;</p>
<p>&lt;div style=”position:absolute; z-index:9999;”&gt;</p>
<p>&lt;img src=”http://image.zhangxinxu.com/image/study/s/s256/mm3.jpg” /&gt;</p>
<p>&lt;/div&gt;</p>
<p>&lt;/div&gt;</p>
<p>&lt;/div&gt;</p>
<p>结果IE6童鞋喜笑颜开，春光灿烂：</p>
<p>19：css reset中的list-style:none</p>
<p>在IE6,7下,当UL不具有float:left;display:inline;时:</p>
<p>无论有没有list-style:none这个属性,列 表符都被隐藏,不占位置(下面代码中的5,6)</p>
<p>当UL具有float:left;display:inline;属性时</p>
<p>list- style:none,列表符被隐藏,但是仍然留有位置(list-style-position:inside);</p>
<p>未 设置list-style:none;列表符被隐藏,也不占位(list-style-position:outside)</p>
<p>在firefox中只要list-style-type为none ,则 无论list-stype-position的值为outside或inside , list-style都能很好的被隐藏</p>
<p>而在IE6,7中,仅 设置list-style:none,并不足以解决所有问题</p>
<p>所以我认为在css reset的时候使用 list-style:none outside none 更好</p>
<p>20：链接去边线（完全兼容）</p>
<p>a,a:hover{outline:none; blur:expression(this.onFocus=this.blur());}</p>
<p>21: display:inline-block 额外产生的6PX 或者4px margin</p>
<p>今天在做一个Timeline的模块的时候遇到一个棘手的问题： 给元素添加display:inline-block 属性的时候会产生额外的4px的margin-right。</p>
<p>原始代码</p>
<p>.YP_timelineChart_box li{</p>
<p>display:-moz-inline-stack;</p>
<p>display:inline-block;</p>
<p>zoom:1;</p>
<p>*display:inline;</p>
<p>text-indent:-3000px;</p>
<p>width:5px;</p>
<p>vertical-align:bottom;</p>
<p>background-color:#00FF00;</p>
<p>position:relative;</p>
<p>}</p>
<p>页面渲染结果：</p>
<p>每一列都会向右产生外边距4px，苦思不得其解，尝试负的外边距，但是涉及到其他的问题:每个li标签会重叠1-2个px，妨碍到鼠标hover状 态的事件。尝试修改doctype类型也不见效果。后来尝试了另外一个方法：</p>
<p>把原来的HTML 代码结构：</p>
<p>更改为：</p>
<p>这样就不会产生额外的外边距，也弄不清楚为什么会出现这种问题。先暂时记下，以后再研究研究。</p>
<p>&nbsp;</p>
<p>22: IE6中伪类:hover的使用及BUG</p>
<p>以前未曾遇到类似的问题，一番google，才知道这是IE6处理CSS伪类:hover的Bug。例如如下的代码：</p>
<p>&lt;style&gt;</p>
<p>a {color: #333;}</p>
<p>a span {color: green;}</p>
<p>a:hover {}</p>
<p>a:hover span {color: red; }</p>
<p>&lt;/style&gt;</p>
<p>&lt;a href=”http://www.taobao.com“&gt; 淘宝网 &lt;span&gt; 淘你喜欢 &lt;/span&gt;&lt;/a&gt;</p>
<p>在IE7/FF中，鼠标移动到链接上时，”淘你喜欢”字样会变为红色，但IE6则无反应。所以IE6的bug就是如果a 与 a:hover 的css定义是一样的，也就是说如果a:hover 中没有样式的改变，hover就不会被触发。但如果在a:hover{}增加一些特定的属性，例如</p>
<p>a:hover{border:none;}</p>
<p>或者</p>
<p>a:hover{padding:0;}</p>
<p>又或者</p>
<p>a:hover{background: none;}</p>
<p>此时hover就可以触发了。</p>
<p>23：原来IE6支持!important</p>
<p>.demo { color:#F00!important; color:#000; }/*IE6显示错误理解：.demo显示为黑色*/</p>
<p>/*而下面IE6是正确理解的：.demo显示为红色*/</p>
<p>.demo { color:#F00!important;}</p>
<p>.demo { color:#000; }</p>
<p>24:去掉button按钮左右两边的留白</p>
<p>&lt;!DOCTYPE html&gt;</p>
<p>&lt;html&gt;</p>
<p>&lt;head&gt;</p>
<p>&lt;meta charset=”utf-8&#8243; /&gt;</p>
<p>&lt;style&gt;</p>
<p>*{padding:0; margin:0}</p>
<p>input,button{overflow:visible;padding:0;}</p>
<p>&lt;/style&gt;</p>
<p>&lt;/head&gt;</p>
<p>&lt;body&gt;</p>
<p>&lt;form id=”form1&#8243; name=”form1&#8243; method=”post” action=”"&gt;</p>
<p>&lt;input type=”submit” name=”button” id=”button” value=”button按钮左右留白的解决方法” /&gt;</p>
<p>&lt;/form&gt;</p>
<p>&lt;button&gt;&lt;span&gt;button按钮左右留白的解决方法&lt;/span&gt;&lt;/button&gt;</p>
<p>&lt;/body&gt;</p>
<p>&lt;/html&gt;</p>
<p>25:中文字体在css中的写法</p>
<p>黑体SimHei\9ED1\4F53黑体</p>
<p>宋体SimSun\5B8B\4F53宋体</p>
<p>新宋体 NSimSun\65B0\5B8B\4F53新宋体</p>
<p>仿宋FangSong\4EFF\5B8B仿宋</p>
<p>楷体KaiTi\6977\4F53 楷体</p>
<p>微软正黑体Microsoft JhengHei\5FAE\x8F6F\6B63\9ED1\4F53微软正黑体</p>
<p>微软雅黑Microsoft YaHei\5FAE\8F6F\96C5\9ED1微软雅黑</p>
<p>幼圆 YouYuan\5E7C\5706幼圆</p>
<p>26： ie6里width:100%是相对于上有高度设置的元素 其他浏览器是相对于上个相对定位或绝对定位的元素</p>
<p>&lt;div style=” width:600px; height:600px; background:#000;”&gt;</p>
<p>&lt;div style=” width:500px; height:500px; background:#333;”&gt;</p>
<p>&lt;div style=” float:left; background:#666; width:400px;” &gt;</p>
<p>&lt;div style=” width:300px; height:300px; background:#999;”&gt;</p>
<p>&lt;div style=” width:100%; height:100%; background:#f00; position:absolute; left:0; top:0;”&gt;</p>
<p>在非ie6的浏览器中都是满屏幕的红， 说明非ie6的浏览器的width和height的百分比，都是相对的上个相对定位或者绝对定位的元素，没有就为html元素，而ie6中的width和height 的百分比，相对的是上个有高宽显示设置的元素，而且height的百分比设置失效，所以上述代码在ie6中就出现宽度穿越了他的父元素而遇见width:500px;的元素的时候，边把自己设置成了width:500px;而height的设置则失效， 这个， 让人很蛋疼！ie6，真的该早点走了！</p>
<p>&lt;/div&gt;</p>
<p>&lt;/div&gt;</p>
<p>&lt;/div&gt;</p>
<p>&lt;/div&gt;</p>
<p>&lt;/div&gt;</p>
<p>27： ie不缓存背景图片的解决办法</p>
<p>高性能web开发中，一张小小的图片请求能省的就省，可IE6存在不缓存背景图的bug.如果重复使用了一个图片作为背景，那么每用一次就会重新去服务器拉一次。。。给服务器带来巨大的压力。解决方法有两种，</p>
<p>1：采用JS</p>
<p>var ua = navigator.userAgent.toLowerCase();</p>
<p>var isIE6 = ua.indexOf(“msie 6&#8243;) &gt; -1;//判断是否为IE6</p>
<p>// remove css image flicker</p>
<p>//IE6下默认不缓存背景图片，CSS里每次更改图片的位置时都会重新发起请求，用这个方法告诉IE6缓存背景图片</p>
<p>if(isIE6){</p>
<p>try{</p>
<p>document.execCommand(“BackgroundImageCache”, false, true);</p>
<p>}catch(e){}</p>
<p>}</p>
<p>2.在页面上直接使用1个DIV元素来加载该图片，这样加载图片就能真正被缓存，鼠标移动也不会发送请求了。</p>
<p>28:ie6下css实现max/min-width/height</p>
<p>_width:expression(this.width&gt;300?”300px”:ture); max-width:300px;</p>
<p>_height:expression(this.height&gt;300?”300px”:ture); max-height:300px;</p>
<p>29：css空白外边距互相叠加的解决方法</p>
<p>body{width:300px; font-family:&#8217;微软雅黑&#8217;; font-size:1em; text-indent:10px; line-height:1.25;}</p>
<p>div{background:#000;margin:10px;}</p>
<p>div p{background:#f60;margin:15px}</p>
<p>这是一个div元素内嵌套p的简单样例,先别复制保存为html测试,在你看完上面的代码后,你是否以为它出为你呈现如下图的效果?</p>
<p>好,现在你可以复制上面代码,保存到本地,然后在浏览器中打开.你会惊讶的发现,它呈现给你的效果是这样的:</p>
<p>为什么会这样呢?按CSS中,对于有块级子元素的元素计算高度的方式,如果元素没有垂直边框和填充,那其高度就是其子元素顶部和底部边框边缘之间的距离.故,子元素的顶部和底部空白边就突出到元素的外围了.p元素的15px外边距与div元素的10px的外边距形成一个单一的15px垂直空白边,另外,形式的这个空白边并非为div所包围,而是呈现在div的外围.所以,我们看到了第二张效果图.</p>
<p>如何解决?本人比较推荐两种解决方式:</p>
<p>其一,为外围元素定义透明边框.具体到本例,即在样式div中加入border:1px solid #ddd;</p>
<p>其二,为外围元素定义内边距填充..具体到本例,即在样式div中加入padding:1px</p>
<p>另外,还可以通过外围元素绝对定位,或者定义子元素浮动等方式实现.</p>
<p>30：纯css解决多行文字垂直居中</p>
<p>&lt;style type=”text/css”&gt;</p>
<p>.alert{</p>
<p>width:400px;</p>
<p>height:250px;</p>
<p>display:table-cell;</p>
<p>vertical-align:middle;</p>
<p>line-height:1.5em;</p>
<p>border:1px solid red;</p>
<p>}</p>
<p>.alert_blank{</p>
<p>height:100%;</p>
<p>width:0;</p>
<p>display:inline;</p>
<p>vertical-align:middle;</p>
<p>zoom:1;</p>
<p>}</p>
<p>.alert_con{</p>
<p>width:100%;</p>
<p>zoom:1;</p>
<p>display:inline;</p>
<p>vertical-align:middle;</p>
<p>}</p>
<p>&lt;/style&gt;</p>
<p>&lt;div&gt;</p>
<p>&lt;div&gt;哥乃多行文字垂直居中～哥乃多行文字垂直居中～哥乃多行文字垂直居中～哥乃多行文字垂直居中～&lt;/div&gt;</p>
<p>&lt;/div&gt;</p>
<p>其大概原理为：第一个alert_blank容器，display:inline以后作为行内元素，它的高度为100%，宽度却为0，相当于紧贴外层容器左边框的一条透明的线，这样就使得外层容器里面只存在一行。外层容易的vertical-align:middle使得其内部相当于一行文字垂直居中。真正盛放内容的div也是display:inline，它对外和blank垂直居中，只要内部文字不超过blank的高度，这个效果将是完美的。虽然从语义化上讲，用空白div布局说不太过去，但是瑕不掩瑜。另：zoom:1是为了触发hasLayout。</p>
<p>31:关于flash遮盖div浮动层</p>
<p>(a) place Flash embed script in &lt;div&gt; container (I use SWFObject.js)[将flash嵌入脚本放到一个div容器中]</p>
<p>(b) add wmode=transparent to Flash embed script[增加wmode=transparent 到flash嵌入脚本]</p>
<p>(c) set &lt;div id=”flashcontent”&gt; container with z-index:-1; [将外层容器的z-index设置为-1]</p>
<p>(d) set &lt;body&gt; tag with style .. position:relative;left:0px;top:0px;z-index:0;</p>
<p>(otherwise Firefox does not accept negative z-index)</p>
<p>(e) set floating iframe in container with z-index: 99;[将浮动的iframe在容器中的zindex设置为99]</p>
<p>(f) use CSS to position flashcontent and htmlcontent containers.[使用css来调整flash容器和html容器的位置]</p>
<p>其他方案网上比较多见,不做阐述.在此说下使用第一个方案如何解决:</p>
<p>var so = new SWFObject(“XXX.swf”, “flashId”, “宽度”, “高度”, “版本”, “背景色”);</p>
<p>//设置flash不遮盖div层</p>
<p>so.addParam(“wmode”, “opaque”);</p>
<p>so.write(“flashcontent”);</p>
<p>如此设置即可让flash无法遮盖住div</p>
<p>32:如何处理ie6的文字行高</p>
<p>ie6下汉字就会显示偏上位置，而在标准浏览器中不存在这个问题字体 Tahoma,试下</p>
<p>不过如果有规定第一个字体是用啥的，那就只能忽略这个问题..我终于明白淘宝为啥把Tahoma字体放到第一位了</p>
<p>&lt;!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;</p>
<p>&lt;html xmlns=”http://www.w3.org/1999/xhtml”&gt;</p>
<p>&lt;head&gt;</p>
<p>&lt;meta http-equiv=”Content-Type” content=”text/html; charset=utf-8&#8243; /&gt;</p>
<p>&lt;title&gt;测试ie6的文字行高表现&lt;/title&gt;</p>
<p>&lt;style type=”text/css”&gt;</p>
<p>body,ul,li,p {margin:0;padding:0;}</p>
<p>body { font:12px/1.5  Tahoma,”宋体”,Arial, Helvetica, sans-serif; }</p>
<p>ul {float:left;list-style:none; margin-bottom:10px;}</p>
<p>ul li, p { margin-top:4px;background:silver;clear:left;}</p>
<p>ul li {float:left;margin-top:4px;}</p>
<p>&lt;/style&gt;</p>
<p>&lt;/head&gt;</p>
<p>&lt;body&gt;</p>
<p>&lt;ul&gt;</p>
<p>&lt;li&gt;岁月不饶人哪&lt;/li&gt;</p>
<p>&lt;li&gt;hjgt&lt;/li&gt;</p>
<p>&lt;/ul&gt;</p>
<p>&lt;p&gt;岁月不饶人哪&lt;/p&gt;</p>
<p>&lt;p&gt;hjgt&lt;/p&gt;</p>
<p>&lt;/body&gt;</p>
<p>&lt;/html&gt;</p>
<p>33:利用 CSS 跨浏览器地隐藏文字一法</p>
<p>ont-size:0;        // for firefox &amp; opera</p>
<p>color: transparent; // for webkit</p>
<p>overflow:hidden;    // for IE</p>
<p>font-size:0;</p>
<p>filter:alpha(opacity=0);</p>
<p>自测后兼容的浏览器如下：</p>
<p>IE 6-8</p>
<p>Firefox 1-4</p>
<p>Opera 9-10</p>
<p>Safari 3-5</p>
<p>Chrome 1-6</p>
<p>34:button在chrome下默认有2px的margin</p>
<p>&lt;button&gt;在chrome下有两像素margin&lt;/button&gt;</p>
<p>35:ie6和ie7里面margin失效</p>
<p>&lt;div style=”padding:20px;background:#f00;”&gt;</p>
<p>&lt;div style=”background:#fff;height:200px;margin:50px;”&gt;我的margin在ie里面失效了&lt;/div&gt;</p>
<p>解决办法去掉里面div的高度</p>
<p>&nbsp;</p>

	标签：<a href="http://www.zfkun.com/tag/bug" title="bug" rel="tag">bug</a>, <a href="http://www.zfkun.com/tag/css" title="css" rel="tag">css</a>, <a href="http://www.zfkun.com/tag/ie" title="ie" rel="tag">ie</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/142.html" title="IE6+和FF的CSS Hack (2010 年 04 月 23 日)" data-comment="0">IE6+和FF的CSS Hack</a></li>
	<li><a href="http://www.zfkun.com/205.html" title="欺骗IE不出现Flash激活框的小发现 (2011 年 03 月 20 日)" data-comment="0">欺骗IE不出现Flash激活框的小发现</a></li>
	<li><a href="http://www.zfkun.com/344.html" title="WordPress 中文Tag 显示404错误的BUG修正 (2011 年 07 月 07 日)" data-comment="0">WordPress 中文Tag 显示404错误的BUG修正</a></li>
	<li><a href="http://www.zfkun.com/109.html" title="Understanding and Solving Internet Explorer Leak Patterns (2010 年 02 月 28 日)" data-comment="0">Understanding and Solving Internet Explorer Leak Patterns</a></li>
	<li><a href="http://www.zfkun.com/461.html" title="KISSY DataLazyLoad组件之事件BUG (2012 年 02 月 24 日)" data-comment="0">KISSY DataLazyLoad组件之事件BUG</a></li>
	<li><a href="http://www.zfkun.com/91.html" title="CSS圆角—透明圆角化背景图片 (2010 年 01 月 21 日)" data-comment="0">CSS圆角—透明圆角化背景图片</a></li>
	<li><a href="http://www.zfkun.com/87.html" title="CSS圆角—基本圆角框 (2010 年 01 月 21 日)" data-comment="0">CSS圆角—基本圆角框</a></li>
	<li><a href="http://www.zfkun.com/182.html" title="add bookmark for ie &#038; ff &#038; opera (2011 年 03 月 20 日)" data-comment="0">add bookmark for ie &#038; ff &#038; opera</a></li>
	<li><a href="http://www.zfkun.com/131.html" title="5 个简单实用的 CSS 属性 (2010 年 03 月 09 日)" data-comment="0">5 个简单实用的 CSS 属性</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/275.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Windows7下搭建Node.js环境</title>
		<link>http://www.zfkun.com/226.html</link>
		<comments>http://www.zfkun.com/226.html#comments</comments>
		<pubDate>Wed, 06 Apr 2011 08:34:18 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[cygwin]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[win7]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=226</guid>
		<description><![CDATA[1. 下载并安装Cygwin 及Node.js安装依赖的附加组件 cygwin下载:  http://cygwin.com/setup.exe (下载点最好选择台湾或日本的临近点，速度快) 附加组件选择: Devel : gcc-g++:    C++ compiler gcc-mingw-g++:   Mingw32 support headers and libraries for GCC C++ gcc4-g++:    G++ subpackage git:   Fast Version Control System – core files  (github方式下载时用) make:   The &#8230; <a href="http://www.zfkun.com/226.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>1. 下载并安装Cygwin 及Node.js安装依赖的附加组件</p>
<p>cygwin下载:  <a title="http://cygwin.com/setup.exe" href="http://cygwin.com/setup.exe">http://cygwin.com/setup.exe</a> (下载点最好选择台湾或日本的临近点，速度快)</p>
<p>附加组件选择:</p>
<p>Devel :<br />
<strong> gcc-g++</strong>:    C++ compiler<br />
<strong> gcc-mingw-g++</strong>:   Mingw32 support headers and libraries for GCC C++<br />
<strong>gcc4-g++</strong>:    G++ subpackage<br />
<strong>git</strong>:   Fast Version Control System – core files  (github方式下载时用)<br />
<strong>make</strong>:   The GNU version of the &#8216;make&#8217; utility<br />
<strong>openssl-devel</strong>:   The OpenSSL development environment<br />
<strong>pkg-config</strong>:   A utility used to retrieve information about installed libraries<br />
<strong>zlib-devel</strong>:   The zlib compression/decompression library (development)</p>
<p>Editor:<br />
<strong> vim</strong>:   Vi IMproved &#8211; enhanced vi editor</p>
<p>Python:<br />
全部</p>
<p>Web:<br />
<strong>wget</strong>:   Utility to retrieve files from the WWW via HTTP and FTP<br />
<strong>curl</strong>:   Multi-protocol file transfer command-line tool</p>
<p>2.  由于操作系统为 windows 7 (Windows Vista以后版本)，需要在ash模式下执行rebaseall才能保证 node.js的编译通过</p>
<p>a. 进入 cygwin安装目录/bin/<br />
b. 运行ash.exe<br />
c.  执行./rebaseall -v 命令<br />
d. 正常情况下就OK通过，而我编译出现错误，提示系统临时目录无写入 权限<br />
e.  我编译出现错误，提示系统临时目录无写入权限，遂，手动修改了 rebaseall 文件的 83行处代码，如下：</p>
<pre class="sh"># TmpDir="${TMP:-${TEMP:-/tmp}}"
TmpDir="D:/servers/cygwin_local/temp"</pre>
<p>3. 启动cygwin下载 node.js源码编译并安装</p>
<pre class="shell">$ cd /
$ git clone git://github.com/joyent/node.git
$ cd node
$ ./configure
$ make
$ make install</pre>
<p>4.  设置DNS</p>
<p>cygwin内部使用windows的DNS查询，且node.js采用c-ares函数库，而c-ares函数库读取的  /etc/resolv.conf 里的nameserver配置，</p>
<p>所以需要手动建立 /etc/resolv.conf , 并增加以下nameserver 来让node.js执行网络操作时正常运行：</p>
<pre class="shell">$ vi /ect/resolv.conf

nameserver 8.8.8.8
nameserver 8.8.4.4</pre>
<p>5. 测试node.js环境</p>
<p>查看下 node安装信息：</p>
<pre class="shell">node --version</pre>
<p>写个简单的 Http Server来测试下node.js环境，保存一下代码为/worksapce/test.js：</p>
<pre class="js">var http = require('http'), port = 8888;

http.createServer(function (request, response) {
response.writeHead(200, { 'Content-Type': 'text/html;charset=utf-8;' });
response.end('&lt;h1&gt;你好世界！&lt;/h1&gt;');
}).listen(port);

console.log('服务已启动 http://127.0.0.1:' + port + '/');
$ node /workspace/test.js</pre>
<p>开打浏览器访问 http://127.0.0.1:8888  查看效果</p>

	标签：<a href="http://www.zfkun.com/tag/cygwin" title="cygwin" rel="tag">cygwin</a>, <a href="http://www.zfkun.com/tag/js" title="js" rel="tag">js</a>, <a href="http://www.zfkun.com/tag/node" title="node" rel="tag">node</a>, <a href="http://www.zfkun.com/tag/nodejs" title="nodejs" rel="tag">nodejs</a>, <a href="http://www.zfkun.com/tag/win7" title="win7" rel="tag">win7</a>, <a href="http://www.zfkun.com/tag/windows" title="windows" rel="tag">windows</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/51.html" title="windows7 7068 X86三版本及下载 (2010 年 01 月 16 日)" data-comment="0">windows7 7068 X86三版本及下载</a></li>
	<li><a href="http://www.zfkun.com/449.html" title="Thinkpad 全系列驱动程序官方安装光盘下载 (2011 年 11 月 17 日)" data-comment="0">Thinkpad 全系列驱动程序官方安装光盘下载</a></li>
	<li><a href="http://www.zfkun.com/154.html" title="随机颜色 (2011 年 01 月 12 日)" data-comment="0">随机颜色</a></li>
	<li><a href="http://www.zfkun.com/59.html" title="腾讯TT、遨游浏览器检测 (2010 年 01 月 16 日)" data-comment="0">腾讯TT、遨游浏览器检测</a></li>
	<li><a href="http://www.zfkun.com/55.html" title="绝对震撼!10款动感图片展示js代码 (2010 年 01 月 16 日)" data-comment="0">绝对震撼!10款动感图片展示js代码</a></li>
	<li><a href="http://www.zfkun.com/277.html" title="微软MSDN windows 7 with sp1 中英文各版本x86x64下载地址 (2011 年 06 月 25 日)" data-comment="1">微软MSDN windows 7 with sp1 中英文各版本x86x64下载地址</a></li>
	<li><a href="http://www.zfkun.com/176.html" title="原生JSON.parse解析异常问题 (2011 年 03 月 18 日)" data-comment="0">原生JSON.parse解析异常问题</a></li>
	<li><a href="http://www.zfkun.com/147.html" title="前端资源文件缓存清除一法 (2010 年 11 月 25 日)" data-comment="0">前端资源文件缓存清除一法</a></li>
	<li><a href="http://www.zfkun.com/394.html" title="[转]利用跨域资源共享（CORS）实现ajax跨域调用 (2011 年 07 月 15 日)" data-comment="0">[转]利用跨域资源共享（CORS）实现ajax跨域调用</a></li>
	<li><a href="http://www.zfkun.com/80.html" title="[转]Google Closure: 糟糕的JavaScript (2010 年 01 月 19 日)" data-comment="0">[转]Google Closure: 糟糕的JavaScript</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/226.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>动态生成windows快捷方式文件</title>
		<link>http://www.zfkun.com/223.html</link>
		<comments>http://www.zfkun.com/223.html#comments</comments>
		<pubDate>Sat, 02 Apr 2011 07:52:01 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[shortcut]]></category>
		<category><![CDATA[url]]></category>
		<category><![CDATA[快捷方式]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=223</guid>
		<description><![CDATA[近期改版中涉及到此小需求。就看了下，其实挺简单，这里就做个简单记录，不需要分析了。简单的使用了PHP语言（其他也一样），扩展性很容易做（稍微做点可变处理就行），所以就没去刻意做，写死效率最高 - -。 <a href="http://www.zfkun.com/223.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>近期改版中涉及到此小需求。就看了下，其实挺简单，这里就做个简单记录，不需要分析了。</p>
<p>简单的使用了PHP语言（其他也一样），扩展性很容易做（稍微做点可变处理就行），所以就没去刻意做，写死效率最高 &#8211; -。</p>
<pre name="code" class="php">&lt;?php
$fileName = iconv("utf-8", "GBK", "7k7k小游戏");
header("Content-Type:application/octet-stream");
header("Content-Disposition:attachment;filename={$fileName}.url");
?&gt;[default]
BASEURL=http://www.7k7k.com/?ADTAG=deskto.home
[InternetShortcut]
URL=http://www.7k7k.com/?ADTAG=desktop.home
IconFile=http://www.7k7k.com/favicon.ico
IconIndex=1
HotKey=0
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2</pre>

	标签：<a href="http://www.zfkun.com/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.zfkun.com/tag/shortcut" title="shortcut" rel="tag">shortcut</a>, <a href="http://www.zfkun.com/tag/url" title="url" rel="tag">url</a>, <a href="http://www.zfkun.com/tag/%e5%bf%ab%e6%8d%b7%e6%96%b9%e5%bc%8f" title="快捷方式" rel="tag">快捷方式</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/135.html" title="挑战 hax.tor.hu 申请带ssh的免费php+mysql空间 (2010 年 03 月 19 日)" data-comment="0">挑战 hax.tor.hu 申请带ssh的免费php+mysql空间</a></li>
	<li><a href="http://www.zfkun.com/39.html" title="基于OpenCV的PHP图像人脸识别技术 (2010 年 01 月 16 日)" data-comment="0">基于OpenCV的PHP图像人脸识别技术</a></li>
	<li><a href="http://www.zfkun.com/417.html" title="WordPress Rewrite SEO 之404方式折腾笔记 (2011 年 07 月 17 日)" data-comment="1">WordPress Rewrite SEO 之404方式折腾笔记</a></li>
	<li><a href="http://www.zfkun.com/102.html" title="Windows 下 Nginx + PHP5 的安装与配置 (2010 年 01 月 28 日)" data-comment="0">Windows 下 Nginx + PHP5 的安装与配置</a></li>
	<li><a href="http://www.zfkun.com/35.html" title="PHP CURL函数库 (2010 年 01 月 16 日)" data-comment="0">PHP CURL函数库</a></li>
	<li><a href="http://www.zfkun.com/95.html" title="Nginx 0.8.x + PHP 5.2.10（FastCGI）搭建胜过Apache十倍的Web服务器（第5版） (2010 年 01 月 28 日)" data-comment="0">Nginx 0.8.x + PHP 5.2.10（FastCGI）搭建胜过Apache十倍的Web服务器（第5版）</a></li>
	<li><a href="http://www.zfkun.com/21.html" title="iconv 方法使用 (2010 年 01 月 16 日)" data-comment="0">iconv 方法使用</a></li>
	<li><a href="http://www.zfkun.com/229.html" title="fastcgi_finish_request提速程序执行 (2011 年 04 月 13 日)" data-comment="3">fastcgi_finish_request提速程序执行</a></li>
	<li><a href="http://www.zfkun.com/33.html" title="domdocument::domdocument() expects at least 1 parameter解决办法 (2010 年 01 月 16 日)" data-comment="0">domdocument::domdocument() expects at least 1 parameter解决办法</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/223.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 canvas 初级入门教程</title>
		<link>http://www.zfkun.com/220.html</link>
		<comments>http://www.zfkun.com/220.html#comments</comments>
		<pubDate>Sun, 20 Mar 2011 11:38:24 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[js]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=220</guid>
		<description><![CDATA[HTML5 canvas 即HTML5画布，是一个现代浏览器都支持的HTML5非插件绘图的功能，本文将展示如何通过HTML5 canvas API操作canvas元素、绘制图形、改变绘图颜色以及删除图形，让我们开始进入这很酷的新技术的短暂旅行吧。 <a href="http://www.zfkun.com/220.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>HTML5 canvas 即HTML5画布，是一个现代浏览器都支持的HTML5非插件绘图的功能，本文将展示如何通过HTML5 canvas API操作canvas元素、绘制图形、改变绘图颜色以及删除图形，让我们开始进入这很酷的新技术的短暂旅行吧。</p>
<h2>canvas元素简介</h2>
<p>使用canvas元素相当简单，它只是一个单纯的HTML标签，外加宽高两个特性。</p>
<pre name="code" class="html">&lt;canvas width="500" height="500"&gt;
&lt;!-- 在这里插入向后兼容的内容，不支持canvas的浏览器可以解析和显示 --&gt;
&lt;/canvas&gt;</pre>
<p>上面的代码在页面中插入了一个透明的画布，canvas元素内部的内容可以在不支持canvas功能的浏览器下显示你想给你的用户提供的信息，联想下&lt;noscript&gt;元素就可以。</p>
<h2>浏览器支持</h2>
<p>很重要的一点就是浏览器对canvas的支持还是相当不错的，所有现代浏览器都支持它，包括最新版的IE9：</p>
<blockquote><p>Internet Explorer 9.0+<br />
Safari 3.0+<br />
Firefox 3.0+<br />
Chrome 3.0+<br />
Opera 10.0+<br />
iOS 1.0+<br />
Android 1.0+</p></blockquote>
<p>有趣的是，你可以在IE8以及更低版本的IE浏览器下使用canvas功能，借助<a title="ExplorerCanas" href="http://code.google.com/p/explorercanvas/" target="_blank">ExplorerCanvas 插件</a>。</p>
<h2>画布尺寸</h2>
<p>当定义canvas元素的尺寸时，最好通过HTML设置它的width和height特性，因为通过CSS设置宽高会导致画布按比例缩放到你设置的值，这背后有它的逻辑原因：在canvas元素的内部存在一个名为2d渲染环境（2d redering context）的对象，所以，通过CSS设置画布尺寸会引起奇怪的效果。</p>
<h2>探索2d 渲染环境</h2>
<p>我们上面提到的canvas元素只是canvas功能的一部分，另一部分是2d渲染环境，它可以让你实现很酷的看得到的东西。</p>
<p>需要完全理清的是：当你使用canvas，你不是在canvas元素上画图，事实上你是在canvas元素内部的2d渲染环境上。</p>
<h2>坐标系统</h2>
<p>如果你曾经使用过2d绘图编程语言（比如ActionScript、Processing等），你应该会了解基于屏幕（screen-based）的坐标系统。canvas内部的2d渲染环境并没有什么不同之处，它采用标准的笛卡尔坐标系统，原点位于屏幕左上角，向右移动会增加x坐标的值，向下移动会增加y坐标的值，很容易理解。</p>
<p><a href="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444647417_e731191271.jpg" target="_blank"><img class="aligncenter size-full wp-image-354" title="canvas unit" src="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444647417_e731191271.jpg" alt="" width="500" height="353" /></a></p>
<p>通常坐标系统的单位是屏幕的1像素。</p>
<h2>操作2d渲染环境</h2>
<p>需要利用Javascript提供的API来获取2d渲染环境对象，该方法为：getContext()，看下简单的例子：</p>
<pre name="code" class="html">&lt;canvas id="csser-com-Canvas" width="500" height="500"&gt;
   &lt;!-- 向后兼容的内容 --&gt;
&lt;/canvas&gt;
&lt;script&gt;
var canvas = document.getElementById("csser-com-Canvas");
var c = canvas.getContext("2d");
&lt;/script&gt;</pre>
<p>通过调用canvas对象的getContext()方法，c变量就包含了指向2d渲染环境的引用，这意味着你现在已经完成了在画布上绘图的一切准备，接下来可以开始绘图了。</p>
<h2>绘制矩形</h2>
<p>获得了2d渲染环境对象，就可以通过调用API提供的大量方法来进行绘图了，一个最基本的方法就是fillRect()，通过它可以绘制一个填充颜色的矩形（颜色默认值为黑色）。</p>
<p>在c变量的下面增加以下代码：</p>
<pre name="code" class="js">c.fillRect(0, 0, 50, 50);</pre>
<p>这将在画布左上角绘制绘制一个黑色背景的正方形：</p>
<p><a href="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444673295_e0f869e948_m.jpg" target="_blank"><img class="aligncenter size-full wp-image-355" title="canvas fillRect" src="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444673295_e0f869e948_m.jpg" alt="canvas fillRect" width="58" height="60" /></a></p>
<p>在调用fillRect()方法时传入了4个参数：</p>
<ul>
<li>第一个是基于原点的x坐标位置</li>
<li>第二个是基于原点的y坐标位置</li>
<li>第三个是宽度</li>
<li>第四个是高度</li>
</ul>
<p>fillRect的伪代码看起来应该像这个样子：</p>
<pre name="code" class="js">c.fillRect(x, y, width, height);</pre>
<p>很酷的是，不仅可以绘制填充的矩形，你还可以绘制线框矩形，使用strokeRect()方法，绘制四周产生描边效果的矩形，如：</p>
<pre name="code" class="js">c.strokeRect(50, 50, 100, 100);</pre>
<p>strokeRect的参数与fillRect是一致的，绘制的结果如下：</p>
<p><a href="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444673313_94f0bb9556_m.jpg" target="_blank"><img class="aligncenter size-full wp-image-356" title="canvas strokeRect" src="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444673313_94f0bb9556_m.jpg" alt="canvas strokeRect" width="160" height="160" /></a></p>
<p>利用canvas绘图，简单、优美，所有的方法都很易懂，但是当放在一起使用可以让你画出很漂亮的图形。</p>
<h2>绘制路径</h2>
<p>矩形是唯一一个可以通过单个API方法绘制的图形，先把它放在一边，我们来学习下路径（Paths）绘制。使用路径，可以绘制线条、连续的曲线以及复合图形。</p>
<p>绘制一个简单的路径需要利用一些AIP方法：</p>
<blockquote><p>beginPath 开始一个新路径<br />
moveTo 移动路径的绘图起点<br />
lineTo 从moveTo定义的点开始绘制连续的路径，或者从上一次的lineTo的终点开始绘制。<br />
closePath 连接最后的点和最初的点并关闭路径绘制<br />
fill 用颜色填充路径<br />
stroke 描变路径</p></blockquote>
<p>尝试执行下面的代码：</p>
<pre name="code" class="js">c.beginPath();
c.moveTo(50, 50);
c.lineTo(50, 250);
c.lineTo(250, 250);
c.closePath;
c.fill();</pre>
<p>执行结果为：</p>
<p><a href="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5445275668_000b7c58f1_m.jpg" target="_blank"><img class="aligncenter size-full wp-image-357" title="canvas paths" src="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5445275668_000b7c58f1_m.jpg" alt="canvas paths" width="208" height="207" /></a></p>
<p>你可以用同样的方法绘制你希望的图形，canvas还包含更高级的路径绘制，比如圆弧（可以绘制圆形）和贝塞尔曲线（用于绘制很酷的曲线效果），总之，绘制路径要比绘制矩形复杂的多。</p>
<h2>改变颜色</h2>
<p>到目前为止，我们的示例所绘制的都是填充或描边的黑色，canvas也提供了一些属性用于改变绘制图形的颜色，它们是fillStyle和strokeStyle，它们的语法都是可以自解释的，所以我们直接来改变一个矩形的填充颜色：</p>
<pre name="code" class="js">c.fillStyle = "rgb(255, 0, 0)";
c.fillRect(50, 50, 100, 100);</pre>
<p>结果：</p>
<p><a href="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5445275680_58dc82498b_m.jpg" target="_blank"><img class="aligncenter size-full wp-image-358" title="canvas fillStyle" src="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5445275680_58dc82498b_m.jpg" alt="canvas fillStyle" width="107" height="107" /></a></p>
<p>或者，你可以改变描边的颜色：</p>
<pre name="code" class="js">c.strokeStyle = "rgb(255, 0, 0)";
c.strokeRect(50, 50, 100, 100);</pre>
<p>结果：</p>
<p><a href="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5445275718_085b9c4e07_m.jpg" target="_blank"><img class="aligncenter size-full wp-image-359" title="canvas strokeStyle" src="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5445275718_085b9c4e07_m.jpg" alt="canvas strokeStyle" width="109" height="109" /></a></p>
<p>fillStyle和strokeStyle属性很漂亮的一点就是，它们都支持普通CSS颜色值，这意味着你可以使用RGB、RGBA、HSA、颜色名称以及十六进制颜色值。</p>
<p>还有一点需要指出的是，改变画布中的颜色值不会影响已经绘制的任何图形，例如，如果你绘制了一个黑色的矩形，然后设置填充为红色，接着绘制了另一个矩形，这时第一个矩形仍然为黑色。</p>
<h2>改变线宽</h2>
<p>除了可以改变颜色，还可以利用lineWidth属性改变描边线条的宽度，按照上面的例子，改变线条宽度：</p>
<pre name="code" class="js">c.lineWidth = 20;
c.strokeStyle = "#f00";
c.strokeRect(50, 50, 100, 100);</pre>
<p>结果：</p>
<p><a href="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444673423_370c8a9c4e_m.jpg" target="_blank"><img class="aligncenter size-full wp-image-360" title="canvas lineWidth" src="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444673423_370c8a9c4e_m.jpg" alt="canvas lineWidth" width="133" height="133" /></a></p>
<p>同样的可以改变路径的线宽：</p>
<pre name="code" class="js">c.lineWidth = 20;
c.beginPath();
c.moveTo(50, 50);
c.lineTo(50, 250);
c.lineTo(250, 250);
c.closePath();
c.stroke();</pre>
<p>结果：</p>
<p><a href="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444673489_5a79a07697_m.jpg" target="_blank"><img class="aligncenter size-full wp-image-361" title="canvas lineWidth paths" src="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444673489_5a79a07697_m.jpg" alt="canvas lineWidth paths" width="240" height="240" /></a></p>
<p>还有一些其它的改变线条的方式，比如lineCap设置线条的末端，lineJoin设置线条的角。</p>
<h2>删除图形</h2>
<p>最后我们来了解下如何删除已经绘制的图形，删除图形只需Javascript API提供的一个名为clearRect的方法，其原理是使参数指定的矩形区域背景变为透明。</p>
<p>本文示例画布长宽分别为500像素，要想删除整个画布图形，可以这样做：</p>
<pre name="code" class="js">c.fillRect(50, 50, 100, 100);
c.clearRect(0, 0, 500, 500);</pre>
<p>上面的代码执行后，你会什么都看不到，事实上填充的矩形已经绘制，只是瞬间被删除了，所以你看不到它。</p>
<p>如果你不清楚画布的具体宽高，清除整个画布可以这样：</p>
<pre name="code" class="js">c.clearRect(0, 0, canvas.width, canvas.height);</pre>
<h2>删除画布中的区域</h2>
<p>如果你不想删除整个画布的图形，而仅仅删除画布中的一个区域，假如，你绘制了一个黑色的正方形，旁边绘制了一个红色的正方形：</p>
<pre name="code" class="js">c.fillRect(50, 50, 100, 100);
c.fillStyle = "#f00";
c.fillRect(200, 50, 100, 100);</pre>
<p>看起来是这个样子：</p>
<p><a href="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444673565_a360d6e213_m.jpg" target="_blank"><img class="aligncenter size-full wp-image-362" title="canvas clearRect" src="http://www.zfkun.com/blog/wp-content/uploads/2011/03/5444673565_a360d6e213_m.jpg" alt="canvas clearRect" width="240" height="104" /></a></p>
<p>接下来你可以通过clearRect删除黑色背景的正方形而只保留红色正方形：</p>
<pre name="code" class="js">c.clearRect(50, 50, 100, 100);</pre>
<p>注意传入clearRect的参数能确保能覆盖要被删除的图形的区域。</p>
<p>原文：<a href="http://net.tutsplus.com/tutorials/javascript-ajax/canvas-from-scratch-introducing-canvas/" target="_blank">Canvas From Scratch: Introducing Canvas</a></p>

	标签：<a href="http://www.zfkun.com/tag/api" title="api" rel="tag">api</a>, <a href="http://www.zfkun.com/tag/canvas" title="canvas" rel="tag">canvas</a>, <a href="http://www.zfkun.com/tag/html" title="html" rel="tag">html</a>, <a href="http://www.zfkun.com/tag/html5" title="html5" rel="tag">html5</a>, <a href="http://www.zfkun.com/tag/js" title="js" rel="tag">js</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/157.html" title="MooTools Upgrade from 1.2 to 1.3 (2011 年 01 月 13 日)" data-comment="0">MooTools Upgrade from 1.2 to 1.3</a></li>
	<li><a href="http://www.zfkun.com/html5" title="HTML5 (2011 年 06 月 03 日)" data-comment="0">HTML5</a></li>
	<li><a href="http://www.zfkun.com/154.html" title="随机颜色 (2011 年 01 月 12 日)" data-comment="0">随机颜色</a></li>
	<li><a href="http://www.zfkun.com/59.html" title="腾讯TT、遨游浏览器检测 (2010 年 01 月 16 日)" data-comment="0">腾讯TT、遨游浏览器检测</a></li>
	<li><a href="http://www.zfkun.com/55.html" title="绝对震撼!10款动感图片展示js代码 (2010 年 01 月 16 日)" data-comment="0">绝对震撼!10款动感图片展示js代码</a></li>
	<li><a href="http://www.zfkun.com/176.html" title="原生JSON.parse解析异常问题 (2011 年 03 月 18 日)" data-comment="0">原生JSON.parse解析异常问题</a></li>
	<li><a href="http://www.zfkun.com/147.html" title="前端资源文件缓存清除一法 (2010 年 11 月 25 日)" data-comment="0">前端资源文件缓存清除一法</a></li>
	<li><a href="http://www.zfkun.com/394.html" title="[转]利用跨域资源共享（CORS）实现ajax跨域调用 (2011 年 07 月 15 日)" data-comment="0">[转]利用跨域资源共享（CORS）实现ajax跨域调用</a></li>
	<li><a href="http://www.zfkun.com/80.html" title="[转]Google Closure: 糟糕的JavaScript (2010 年 01 月 19 日)" data-comment="0">[转]Google Closure: 糟糕的JavaScript</a></li>
	<li><a href="http://www.zfkun.com/226.html" title="Windows7下搭建Node.js环境 (2011 年 04 月 06 日)" data-comment="1">Windows7下搭建Node.js环境</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/220.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何检测HTML表单已经发生改变</title>
		<link>http://www.zfkun.com/218.html</link>
		<comments>http://www.zfkun.com/218.html#comments</comments>
		<pubDate>Sun, 20 Mar 2011 11:36:46 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[change]]></category>
		<category><![CDATA[defaultChecked]]></category>
		<category><![CDATA[defaultSelected]]></category>
		<category><![CDATA[defaultValue]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[检测]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=218</guid>
		<description><![CDATA[表单是Web应用不可缺少的功能，它是服务器端与浏览器端数据交换的最基本的方法。你应该已经读过很多关于HTML5和Javascript的表单标签和数据验证的文章，今天我们来讨论下如何检查表单数据是否被改变了。 <a href="http://www.zfkun.com/218.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>表单是Web应用不可缺少的功能，它是服务器端与浏览器端数据交换的最基本的方法。你应该已经读过很多关于HTML5和Javascript的表单标签和数据验证的文章，今天我们来讨论下如何检查表单数据是否被改变了。</p>
<h2>为什么要检查表单数据被改变？</h2>
<p>有很多理由需要检测表单数据是否有修改，让我们来看一个很常见的场景，如果用户修改了一个或多个表单域的值，当用户跳离当前页面时，你会给出用户类似“你的修改尚未保存”的提示。你甚至可以给出用户是否保存数据（比如Ajax）的选项。另外的情况，如果表单项没有被修改，这时略去冗余的表单验证和数据发送将会增强用户体验。</p>
<h2>Javascript onchange事件</h2>
<p>为HTML表单元素添加onchange事件处理器是一种可行的方法，这也是用的最多的，但是onchange的实现有一些问题存在：</p>
<ol>
<li>如果用户改变表单域的值，然后再修改回原始值，程序仍将认为表单的修改已经发生。</li>
<li>如果表单项的值是通过Javascript动态修改的，onchange事件不会被自动触发。</li>
<li>为每一个表单元素增加onchange事件会引起性能问题，特别是较大的表单。</li>
<li>如果将表单元素从DOM中增加或移除，你需要相应的注册或移除事件侦听。</li>
<li>checkbox和radio的onchange事件在某些浏览器下不能按预期工作（你应该知道是哪个浏览器）。</li>
<li>除了onchange，还有更简单有效的方案。</li>
</ol>
<h2>比较默认值</h2>
<p>幸运的是，我们不需要为了复杂的事件处理而写过多的废话，每个表单元素都有与该对象相关联的默认值，即页面加载完后表单控件显示或者默认的数据值，该值可与用户操作后的值进行对比以得出表单域的值是否发生了改变。</p>
<p>有点麻烦的是，不同类型的表单元素的默认值属性（properties）不尽相同（做些判断好了，并不影响什么）</p>
<h2>input和textarea</h2>
<p>让我们从简单的元素开始，所有的textarea对象和除了checkbox、radio之外的 input对象都有一个名为defaultValue的属性，我们可以对比文本域的当前值和默认值是否相同以决定文本域的修改是否发生。</p>
<pre>&lt;!-- name input --&gt;
&lt;input type="text" id="name" name="name" value="www.csser.com" /&gt;
&lt;script&gt;
var name = document.getElementById("name");
if (n.value != n.defaultValue) alert("#name has changed");
&lt;/script&gt;</pre>
<p><strong>小提示</strong>：HTML4或XHTML中，文本域类型为text、hidden、password或file的对象有defaultValue属性。HTML5新的表单类型也有defaultValue属性并且可以用相同的方式检测默认值是否改变过，这些新表单元素包含email、tel、url、range、date、color和search。</p>
<h2>checkbox和radio</h2>
<p>checkbox和radio对象有一个defaultChecked属性，其取值为true或false，我们可以通过对比当前选中状态与默认选中状态进行比较，如：</p>
<pre>&lt;!-- newsletter opt-in --&gt;
&lt;input type="checkbox" id="optin" name="optin" checked="checked" /&gt;
&lt;script&gt;
var optin = document.getElementById("optin");
if (n.checked != n.defaultChecked) alert("#optin has changed by csser");
&lt;/script&gt;</pre>
<p>注意checkbox和radio对象也有defaultValue属性，但它仅被分配给元素的value特性（attribute）而不能标识当前的选中状态。</p>
<h2>下拉列表select</h2>
<p>select控件通常用于提供一个下拉列表供用户选择，相比上面提到的控件，select有一点复杂，select元素本身并不具有默认值属性，它的默认值存在于其option元素集合内。当页面加载完毕，默认选中的option拥有selected特性，也就是这个option对象拥有defaultSelected属性且值为true。</p>
<p>我们可以从select节点的selectedIndex属性取得当前选中的option的索引值，如果该option对象的defaultSelected属性为false，那么select控件的值一定被修改了，如：</p>
<pre>&lt;!-- job title select box --&gt;
&lt;select id="job" name="job"&gt;
   &lt;option&gt;web designer&lt;/option&gt;
   &lt;option selected="selected"&gt;csser.com developer&lt;/option&gt;
   &lt;option&gt;graphic artist&lt;/option&gt;
   &lt;option&gt;IT professional&lt;/option&gt;
   &lt;option&gt;other&lt;/option&gt;
&lt;/select&gt;
&lt;script&gt;
var job = document.getElementById("job");
if (!job.options[job.selectedIndex].defaultSelected) alert("#job has changed");
&lt;/script&gt;</pre>
<p>上面的代码在单选下拉列表并且有一个option拥有selected特性时运行正常，但我们需要留意一些陷阱：</p>
<ol>
<li>如果没有option被赋予selected特性，浏览器会将第一个设为默认选中，但其defaultSelected属性值却为false</li>
<li>如果两个或更多option拥有selected特性（这不合逻辑，但是可能的），每个option都会拥有defaultSelected属性且值为true，但是浏览器仅能得到最后一个的默认值。</li>
<li>多重选择控件允许用户选择任意个option：</li>
</ol>
<pre>&lt;!-- skills multi-select box --&gt;
&lt;select id="skills" name="skills" multiple="multiple"&gt;
   &lt;option selected="selected"&gt;HTML&lt;/option&gt;
   &lt;option selected="selected"&gt;CSSer&lt;/option&gt;
   &lt;option selected="selected"&gt;JavaScript&lt;/option&gt;
   &lt;option&gt;PHP&lt;/option&gt;
&lt;/select&gt;</pre>
<p>多选下拉列表并不常用，因为用多个checkbox可以提供更友好的界面，但是，如果使用多选下拉列表，多个option具有defaultSelected属性且值为true，select节点的selectedIndex属性已经无效，所以需要循环每一个option才能判断其selected属性是否与其defaultSelected属性相匹配。下面的代码可以解决这个问题：</p>
<pre>var  skills = document.getElementById("skills"),c = false, def = 0, o, ol, opt;
for (o = 0, ol = n.options.length; o &lt; ol; o++) {
   opt = skills.options[o];
   c = c || (opt.selected != opt.defaultSelected);
   if (opt.defaultSelected) def = o;
}
if (c &amp;&amp; !skills.multiple) c = (def != skills.selectedIndex);
if (c) alert("#skills has changed");</pre>
<p>上面这些就是本文介绍的如何检测一个表单值是否改变的内容。</p>
<p>&nbsp;</p>
<p>原文：<a href="http://blogs.sitepoint.com/2011/02/18/detect-html-form-changes/" target="_blank">How to Check That an HTML Form Has Been Changed</a></p>

	标签：<a href="http://www.zfkun.com/tag/change" title="change" rel="tag">change</a>, <a href="http://www.zfkun.com/tag/defaultchecked" title="defaultChecked" rel="tag">defaultChecked</a>, <a href="http://www.zfkun.com/tag/defaultselected" title="defaultSelected" rel="tag">defaultSelected</a>, <a href="http://www.zfkun.com/tag/defaultvalue" title="defaultValue" rel="tag">defaultValue</a>, <a href="http://www.zfkun.com/tag/form" title="form" rel="tag">form</a>, <a href="http://www.zfkun.com/tag/%e6%a3%80%e6%b5%8b" title="检测" rel="tag">检测</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/59.html" title="腾讯TT、遨游浏览器检测 (2010 年 01 月 16 日)" data-comment="0">腾讯TT、遨游浏览器检测</a></li>
	<li><a href="http://www.zfkun.com/216.html" title="Javascript浏览器另类探测技巧 (2011 年 03 月 20 日)" data-comment="0">Javascript浏览器另类探测技巧</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/218.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>webkit的自定义图片滚动条</title>
		<link>http://www.zfkun.com/208.html</link>
		<comments>http://www.zfkun.com/208.html#comments</comments>
		<pubDate>Sun, 20 Mar 2011 10:51:17 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[scrollbar]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=208</guid>
		<description><![CDATA[&#160; http://trac.webkit.org/export/41842/trunk/LayoutTests/scrollbars/overflow-scrollbar-combinations.html &#160; 非常不错, only webkit的话，还是不错的。 标签：scrollbar, webkit]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p><a href="http://trac.webkit.org/export/41842/trunk/LayoutTests/scrollbars/overflow-scrollbar-combinations.html" target="_blank">http://trac.webkit.org/export/41842/trunk/LayoutTests/scrollbars/overflow-scrollbar-combinations.html</a></p>
<p>&nbsp;</p>
<p>非常不错, only webkit的话，还是不错的。</p>

	标签：<a href="http://www.zfkun.com/tag/scrollbar" title="scrollbar" rel="tag">scrollbar</a>, <a href="http://www.zfkun.com/tag/webkit" title="webkit" rel="tag">webkit</a><br />
]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/208.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Repaint 跟踪浏览器的渲染</title>
		<link>http://www.zfkun.com/196.html</link>
		<comments>http://www.zfkun.com/196.html#comments</comments>
		<pubDate>Sun, 20 Mar 2011 09:32:35 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[MozAfterPaint]]></category>
		<category><![CDATA[reflow]]></category>
		<category><![CDATA[repaint]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=196</guid>
		<description><![CDATA[前端优化，从很久就开始了。随着研究的深入，关注的点就越来越多。最近也有不少的前端开发同学在研究浏览器的Reflow和Repaint  <a href="http://www.zfkun.com/196.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>前端优化，从很久就开始了。随着研究的深入，关注的点就越来越多。最近也有不少的前端开发同学在研究浏览器的<a title="分析Reflow和Repaint的文章" href="http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/">Reflow和Repaint</a> . 引用以为Yahoo前端开发工程师的分析</p>
<blockquote>
<div>repaint(重绘)是在一个元素的外观被改变，但没有改变布局的情况下发生，如改变visibility、outline、前景色。</div>
<div>“According to <a title="Opera" href="http://dev.opera.com/articles/view/efficient-javascript/?page=3#reflow">Opera</a> , repaint is expensive because the browser must verify the visibility of all other nodes in the DOM tree.”</div>
<div>当repaint发生时，浏览器会验证DOM树上的所有其它结点的visibility属性。</div>
<div>reflow(回流)是导致DOM脚本执行低效的关键因素之一。页面上任何一个结点触发reflow，都会导致它的子结点及祖先结点重新渲染。</div>
<div><a href="http://blog.360.yahoo.com/blog-sOW1QOA9crUyOdXFxOeK4xc-?cq=1&amp;p=213" target="_blank">文本出自</a></div>
</blockquote>
<div>而 Firefox 3.5 给我们提供了一个很好的观察 Repaint 的接口 <a href="https://developer.mozilla.org/en/Gecko-Specific_DOM_Events" target="_blank">MozAfterPaint</a>. 通过这个事件，我们可以看到我们网页的渲染情况是如何，这样会给我们分析reflow带来帮助。</div>
<div>下面的例子需要 <a href="http://www.mozilla.com/en-US/firefox/all-beta.html" target="_blank">firefox 3.5 beta</a></div>
<div></div>
<div><a href="http://www.pjhome.net/web/paint_tester.html" target="_blank"><img src="http://www.pjhome.net/images/icons/page_white_code.gif" alt="" />监听网页的重绘情况</a></div>
<p>&nbsp;</p>

	标签：<a href="http://www.zfkun.com/tag/mozafterpaint" title="MozAfterPaint" rel="tag">MozAfterPaint</a>, <a href="http://www.zfkun.com/tag/reflow" title="reflow" rel="tag">reflow</a>, <a href="http://www.zfkun.com/tag/repaint" title="repaint" rel="tag">repaint</a><br />
]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/196.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IE9允许前端开发获取到页面性能数据</title>
		<link>http://www.zfkun.com/187.html</link>
		<comments>http://www.zfkun.com/187.html#comments</comments>
		<pubDate>Sun, 20 Mar 2011 08:25:53 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[开发编程]]></category>
		<category><![CDATA[ie9]]></category>
		<category><![CDATA[msPerformance]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=187</guid>
		<description><![CDATA[长期以来，为了改善站点的用户体验，我们一直都是在页面顶端加上一个 (new Date()).getTime() 来获取用户打开页面的时间，使用httpwatch来分析页面打开的解释时间。httpwatch虽然强大，但是还是无法让我们深入到用户的环境去了解用户打开页面前的一些情况，例如:DNS解释时间，请求和响应时间，以及更加深入的页面渲染时间等重要信息。这些信息对用户环境分析是至关重要的。 如今，这个情况即将改变，微软的IE9将给前端开发们提供有力的性能分析接口让我们能够深入分析页面的性能，这就是强大的msPerformance接口。这个接口其实是基于HTML5草案Web Timing的定义来开发的（有意思的是这个接口是google提供的，chrome目前还没支持，IE9先行了）。 我们来看看通过Web Timing我们可以获取到什么数据 &#160; window.msPerformance.navigation { requestCount : 76 type : 0 startTime : 1277821481923 redirectedCount : 5 uniqueDomains : 31 } &#160; &#160; window.msPerformance.timingMeasures { request : 22 domContentLoaded : 342 response : 10 &#8230; <a href="http://www.zfkun.com/187.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>长期以来，为了改善站点的用户体验，我们一直都是在页面顶端加上一个<em><strong> (new Date()).getTime()</strong></em> 来获取用户打开页面的时间，使用<a href="http://www.httpwatch.com/" target="_blank">httpwatch</a>来分析页面打开的解释时间。<a href="http://www.httpwatch.com/" target="_blank">httpwatch</a>虽然强大，但是还是无法让我们深入到用户的环境去了解用户打开页面前的一些情况，例如:DNS解释时间，请求和响应时间，以及更加深入的页面渲染时间等重要信息。这些信息对用户环境分析是至关重要的。</p>
<p>如今，这个情况即将改变，微软的<a href="http://ie.microsoft.com/testdrive/" target="_blank">IE9</a>将给前端开发们提供有力的性能分析接口让我们能够深入分析页面的性能，这就是强大的<a href="http://blogs.msdn.com/b/ie/archive/2010/06/28/measuring-web-page-performance.aspx" target="_blank">msPerformance</a>接口。这个接口其实是基于HTML5草案<a href="http://dev.w3.org/2006/webapi/WebTiming/" target="_blank">Web Timing</a>的定义来开发的（有意思的是这个接口是google提供的，chrome目前还没支持，IE9先行了）。</p>
<p>我们来看看通过<a href="http://dev.w3.org/2006/webapi/WebTiming/" target="_blank">Web Timing</a>我们可以获取到什么数据</p>
<p>&nbsp;</p>
<p><strong>window.msPerformance.navigation</strong></p>
<p>{</p>
<p>requestCount : 76</p>
<p>type : 0</p>
<p>startTime : 1277821481923</p>
<p>redirectedCount : 5</p>
<p>uniqueDomains : 31</p>
<p>}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>window.msPerformance.timingMeasures</strong></p>
<p>{</p>
<p>request : 22</p>
<p>domContentLoaded : 342</p>
<p>response : 10</p>
<p>firstPaint : 29</p>
<p>domInteractive : 342</p>
<p>msStyleContentLoaded : 342</p>
<p>fetch : 459</p>
<p>domComplete : 342</p>
<p>load : 89</p>
<p>connect : 3</p>
<p>}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>window.msPerformance.timing</strong></p>
<p>{</p>
<p>domLoading : 1277821481950</p>
<p>responseEnd : 1277821481960</p>
<p>navigationStart : 1277821481923</p>
<p>fetchStart : 1277821481923</p>
<p>msStyleContentLoaded : 1277821482293</p>
<p>firstPaint : 1277821481952</p>
<p>fullyLoaded : 0</p>
<p>requestStart : 1277821481927</p>
<p>loadEnd : 1277821482383</p>
<p>unloadStart : 1277821481923</p>
<p>}</p>
<p>&nbsp;</p>
<p>通过这些数据我们可以更加深入得分析页面的性能和用户的网络环境，提供更加好的差异化服务。</p>
<p><a href="http://ie.microsoft.com/testdrive/" target="_blank"> 到这里下载IE9预览版</a></p>
<p>&nbsp;</p>
<p>发现IE9pre3的console列出的接口不全，直接用调试器把这个接口和方法全部列出来了，更加直观</p>
<p><img title="在新窗口打开图片" src="http://www.pjhome.net/attachments/month_1006/20100629231752.jpg" alt="" /></p>
<p>&nbsp;</p>

	标签：<a href="http://www.zfkun.com/tag/ie9" title="ie9" rel="tag">ie9</a>, <a href="http://www.zfkun.com/tag/msperformance" title="msPerformance" rel="tag">msPerformance</a><br />
]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/187.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>前端资源文件缓存清除一法</title>
		<link>http://www.zfkun.com/147.html</link>
		<comments>http://www.zfkun.com/147.html#comments</comments>
		<pubDate>Thu, 25 Nov 2010 07:02:43 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[js]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=147</guid>
		<description><![CDATA[对于前端开发来说，经常要面对JS，CSS，图片等资源的缓存更新问题（CDN永久缓存的就另当别论）。

大部分情况，为了节省服务器压力及带宽且又不失可维护性，习惯对这些资源文件添加比较久的缓存时间，这样就给前端开发人员带来一个自动更新的棘手问题。

其实，较简单的解决办法，就是固定周期或有条件的或每次（这样要缓存何用？）的增加随机数击穿缓存，强制更新即可。

这里说一个也较为简单的方式，利用AJAX的访问来更新本地缓存。

原理很简单，使用http协议的 If-Modified-Since 和 Cache-Control 两个header头参数即可。
 <a href="http://www.zfkun.com/147.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>对于前端开发来说，经常要面对JS，CSS，图片等资源的缓存更新问题（CDN永久缓存的就另当别论）。</p>
<p>大部分情况，为了节省服务器压力及带宽且又不失可维护性，习惯对这些资源文件添加比较久的缓存时间，这样就给前端开发人员带来一个自动更新的棘手问题。</p>
<p>其实，较简单的解决办法，就是固定周期或有条件的或每次（这样要缓存何用？）的增加随机数击穿缓存，强制更新即可。</p>
<p>这里说一个也较为简单的方式，利用AJAX的访问来更新本地缓存。</p>
<p>原理很简单，使用http协议的 If-Modified-Since 和 Cache-Control 两个header头参数即可。</p>
<p>脚本举例:</p>
<pre class="js">var xhr = false;
try {
 xhr = new XMLHttpRequest();
} catch(e1) {
 try {
  xhr = new ActiveXObject("Msxml2.XMLHTTP");
 } catch (e2) {
  try {
   xhr = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (failed) {
   xhr = false;
  }
 }
}
if (xhr) {
 xhr.open('GET', '要缓存的资源文件地址');
 xhr.setRequestHeader('If-Modified-Since', '0');
 xhr.setRequestHeader('Cache-Control', 'no-cache');
 xhr.send();
}</pre>
<p>当然，这种做法有一个显而易见的局限性，就是不能跨域更新。</p>
<p>不过换个思路也可以简单解决，把这个更新服务脚本分别部署到有需要的资源文件服务器上即可。</p>
<p>就如腾讯，微博里就很多在这样使用。</p>
<p>腾讯的更新服务页面代码：</p>
<pre class="js">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</a>"&gt;
&lt;html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
&lt;title&gt;更新文件--Ptlogin&lt;/title&gt;
&lt;script&gt;
function cleanCache(f){
 var xmlHttp = false;
 try {
   xmlHttp = new XMLHttpRequest();
 } catch (trymicrosoft) {
    try {
        xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (othermicrosoft) {
     try {
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
     } catch (failed) {
      xmlHttp = false;
     }
    }
  }
 if (!xmlHttp){
  alert("请按F5刷新页面");
  return;
 }
 xmlHttp.open('GET', f);
 xmlHttp.setRequestHeader('If-Modified-Since', '0');
 xmlHttp.setRequestHeader('Cache-Control', 'no-cache');
 xmlHttp.send();
}
if (location.hash){
 //var file = location.hash.substring(1,location.href.length);
 var file = location.href.substring(location.href.indexOf("#")+1, location.href.length);
 cleanCache(file);
}
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>使用上，很明显，利用IFRAME去访问此页面即可。而部署，则会将此文件复制多份，部署在需要更新的资源服务器对应目录内。</p>

	标签：<a href="http://www.zfkun.com/tag/ajax" title="ajax" rel="tag">ajax</a>, <a href="http://www.zfkun.com/tag/cache" title="cache" rel="tag">cache</a>, <a href="http://www.zfkun.com/tag/header" title="header" rel="tag">header</a>, <a href="http://www.zfkun.com/tag/http" title="http" rel="tag">http</a>, <a href="http://www.zfkun.com/tag/js" title="js" rel="tag">js</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/394.html" title="[转]利用跨域资源共享（CORS）实现ajax跨域调用 (2011 年 07 月 15 日)" data-comment="0">[转]利用跨域资源共享（CORS）实现ajax跨域调用</a></li>
	<li><a href="http://www.zfkun.com/115.html" title="Comet—“服务器推”技术 (2010 年 03 月 03 日)" data-comment="0">Comet—“服务器推”技术</a></li>
	<li><a href="http://www.zfkun.com/154.html" title="随机颜色 (2011 年 01 月 12 日)" data-comment="0">随机颜色</a></li>
	<li><a href="http://www.zfkun.com/59.html" title="腾讯TT、遨游浏览器检测 (2010 年 01 月 16 日)" data-comment="0">腾讯TT、遨游浏览器检测</a></li>
	<li><a href="http://www.zfkun.com/55.html" title="绝对震撼!10款动感图片展示js代码 (2010 年 01 月 16 日)" data-comment="0">绝对震撼!10款动感图片展示js代码</a></li>
	<li><a href="http://www.zfkun.com/176.html" title="原生JSON.parse解析异常问题 (2011 年 03 月 18 日)" data-comment="0">原生JSON.parse解析异常问题</a></li>
	<li><a href="http://www.zfkun.com/80.html" title="[转]Google Closure: 糟糕的JavaScript (2010 年 01 月 19 日)" data-comment="0">[转]Google Closure: 糟糕的JavaScript</a></li>
	<li><a href="http://www.zfkun.com/226.html" title="Windows7下搭建Node.js环境 (2011 年 04 月 06 日)" data-comment="1">Windows7下搭建Node.js环境</a></li>
	<li><a href="http://www.zfkun.com/388.html" title="window.open() 之句柄保持和重连 (2011 年 07 月 14 日)" data-comment="0">window.open() 之句柄保持和重连</a></li>
	<li><a href="http://www.zfkun.com/109.html" title="Understanding and Solving Internet Explorer Leak Patterns (2010 年 02 月 28 日)" data-comment="0">Understanding and Solving Internet Explorer Leak Patterns</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/147.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IE6+和FF的CSS Hack</title>
		<link>http://www.zfkun.com/142.html</link>
		<comments>http://www.zfkun.com/142.html#comments</comments>
		<pubDate>Thu, 22 Apr 2010 16:59:21 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[ff]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[ie]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=142</guid>
		<description><![CDATA[一、CSS HACK 以下两种方法几乎能解决现今所有HACK. 1, !important 随着IE7对!important的支持, !important 方法现在只针对IE6的HACK.(注意写法.记得该声明位置需要提前.) &#60;style&#62; #wrapper { width: 100px!important; /* IE7+FF */ width: 80px; /* IE6 */ } &#60;/style&#62; 2, IE6/IE77对FireFox *+html 与 *html 是IE特有的标签, firefox 暂不支持.而*+html 又为 IE7特有标签. &#60;style&#62; #wrapper { #wrapper { width: 120px; &#8230; <a href="http://www.zfkun.com/142.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>一、CSS HACK<br />
以下两种方法几乎能解决现今所有HACK.</p>
<p>1, !important</p>
<p>随着IE7对!important的支持, !important 方法现在只针对IE6的HACK.(注意写法.记得该声明位置需要提前.)<br />
&lt;style&gt;<br />
#wrapper<br />
{<br />
width: 100px!important; /* IE7+FF */<br />
width: 80px; /* IE6 */<br />
}<br />
&lt;/style&gt;</p>
<p>2, IE6/IE77对FireFox</p>
<p>*+html 与 *html 是IE特有的标签, firefox 暂不支持.而*+html 又为 IE7特有标签.<br />
&lt;style&gt;<br />
#wrapper<br />
{<br />
#wrapper { width: 120px; } /* FireFox */<br />
*html #wrapper { width: 80px;} /* ie6 fixed */<br />
*+html #wrapper { width: 60px;} /* ie7 fixed, 注意顺序 */<br />
}<br />
&lt;/style&gt;</p>
<p>注意:<br />
*+html 对IE7的HACK 必须保证HTML顶部有如下声明：<br />
&lt;!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”　”http://www.w3.org/TR/html4/loose.dtd”&gt;</p>
<p>二、万能 float 闭合(非常重要!)</p>
<p>关于 clear float 的原理可参见 [How To Clear Floats Without Structural Markup]<br />
将以下代码加入Global CSS 中,给需要闭合的div加上 即可,屡试不爽.<br />
&lt;style&gt;<br />
/* Clear Fix */</p>
<p>.clearfix:after<br />
{<br />
content:”.”;<br />
display:block;<br />
height:0;<br />
clear:both;<br />
visibility:hidden;<br />
}<br />
.clearfix<br />
{<br />
display:inline-block;<br />
}<br />
/* Hide from IE Mac */<br />
.clearfix {display:block;}<br />
/* End hide from IE Mac */<br />
/* end of clearfix */<br />
&lt;/style&gt;</p>
<p>三、其他兼容技巧(再次啰嗦)</p>
<p>1, FF下给 div 设置 padding 后会导致 width 和 height 增加, 但IE不会.(可用!important解决)<br />
2, 居中问题.<br />
1).垂直居中.将 line-height 设置为 当前 div 相同的高度, 再通过 vertical-align: middle.( 注意内容不要换行.)<br />
2).水平居中. margin: 0 auto;(当然不是万能)<br />
3, 若需给 a 标签内内容加上 样式, 需要设置 display: block;(常见于导航标签)<br />
4, FF 和 IE 对 BOX 理解的差异导致相差 2px 的还有设为 float的div在ie下 margin加倍等问题.<br />
5, ul 标签在 FF 下面默认有 list-style 和 padding . 最好事先声明, 以避免不必要的麻烦. (常见于导航标签和内容列表)<br />
6, 作为外部 wrapper 的 div 不要定死高度, 最好还加上 overflow: hidden.以达到高度自适应.<br />
7, 关于手形光标. cursor: pointer. 而hand 只适用于 IE.</p>
<p>1 针对firefox ie6 ie7的css样式<br />
现在大部分都是用!important来hack，对于ie6和firefox测试可以正常显示，<br />
但是ie7对!important可以正确解释，会导致页面没按要求显示！找到一个针<br />
对IE7不错的hack方式就是使用“*+html”，现在用IE7浏览一下，应该没有问题了。<br />
现在写一个CSS可以这样：</p>
<p>#1 { color: #333; } /* Moz */<br />
* html #1 { color: #666; } /* IE6 */<br />
*+html #1 { color: #999; } /* IE7 */<br />
那么在firefox下字体颜色显示为#333，IE6下字体颜色显示为#666，IE7下字体颜色显示为#999。</p>
<p>2 css布局中的居中问题<br />
主要的样式定义如下：</p>
<p>body {TEXT-ALIGN: center;}<br />
#center { MARGIN-RIGHT: auto; MARGIN-LEFT: auto; }<br />
说明：<br />
首先在父级元素定义TEXT-ALIGN: center;这个的意思就是在父级元素内的内容居中；对于IE这样设定就已经可以了。<br />
但在mozilla中不能居中。解决办法就是在子元素定义时候设定时再加上“MARGIN-RIGHT: auto;MARGIN-LEFT: auto; ”<br />
需要说明的是，如果你想用这个方法使整个页面要居中，建议不要套在一个DIV里，你可以依次拆出多个div，<br />
只要在每个拆出的div里定义MARGIN-RIGHT: auto;MARGIN-LEFT: auto; 就可以了。</p>
<p>3 盒模型不同解释.</p>
<p>#box{ width:600px; //for ie6.0- w\idth:500px; //for ff+ie6.0}<br />
#box{ width:600px!important //for ff width:600px; //for ff+ie6.0 width /**/:500px; //for ie6.0-}</p>
<p>4 浮动ie产生的双倍距离</p>
<p>#box{ float:left; width:100px; margin:0 0 0 100px; //这种情况之下IE会产生200px的距离 display:inline; //使浮动忽略}<br />
这里细说一下block,inline两个元素,Block元素的特点是:总是在新行上开始,高度,宽度,行高,边距都可以控制(块元素);Inline元素的特点是:和其他元素在同一行上,&#8230;不可控制(内嵌元素);</p>
<p>#box{ display:block; //可以为内嵌元素模拟为块元素 display:inline; //实现同一行排列的的效果 diplay:table;</p>
<p>5 IE与宽度和高度的问题</p>
<p>IE不认得min-这个定义，但实际上它把正常的width和height当作有min的情况来使。这样问题就大了，如果只用宽度和高度，<br />
正常的浏览器里这两个值就不会变，如果只用min-width和min-height的话，IE下面根本等于没有设置宽度和高度。<br />
比如要设置背景图片，这个宽度是比较重要的。要解决这个问题，可以这样：<br />
#box{ width: 80px; height: 35px;}html&gt;body #box{ width: auto; height: auto; min-width: 80px; min-height: 35px;}</p>
<p>6 页面的最小宽度</p>
<p>min-width是个非常方便的CSS命令，它可以指定元素最小也不能小于某个宽度，这样就能保证排版一直正确。但IE不认得这个，<br />
而它实际上把width当做最小宽度来使。为了让这一命令在IE上也能用，可以把一个&lt;div&gt; 放到 &lt;body&gt; 标签下，然后为div指定一个类：<br />
然后CSS这样设计：<br />
#container{ min-width: 600px; width:expression(document.body.clientWidth &lt; 600? “600px”: “auto” );}<br />
第一个min-width是正常的；但第2行的width使用了Javascript，这只有IE才认得，这也会让你的HTML文档不太正规。它实际上通过Javascript的判断来实现最小宽度。</p>
<p>7 清除浮动</p>
<p>.hackbox{ display:table; //将对象作为块元素级的表格显示}或者.hackbox{ clear:both;}<br />
或者加入:after（伪对象）,设置在对象后发生的内容，通常和content配合使用，IE不支持此伪对象，非Ie 浏览器支持，<br />
所以并不影响到IE/WIN浏览器。这种的最麻烦的&#8230;&#8230;#box:after{ content: “.”; display: block; height: 0; clear: both; visibility: hidden;}</p>
<p>8 DIV浮动IE文本产生3象素的bug</p>
<p>左边对象浮动，右边采用外补丁的左边距来定位，右边对象内的文本会离左边有3px的间距.</p>
<p>#box{ float:left; width:800px;}#left{ float:left; width:50%;}#right{ width:50%;}*html #left{ margin-right:-3px; //这句是关键}<br />
HTML代码&lt;div&gt; &lt;div&gt;&lt;/div&gt; &lt;div&gt;&lt;/div&gt;&lt;/div&gt;</p>
<p>9 属性选择器(这个不能算是兼容,是隐藏css的一个bug)</p>
<p>p[id]{}div[id]{}<br />
这个对于IE6.0和IE6.0以下的版本都隐藏,FF和OPera作用<br />
属性选择器和子选择器还是有区别的,子选择器的范围从形式来说缩小了,属性选择器的范围比较大,如p[id]中,所有p标签中有id的都是同样式的.</p>
<p>10 IE捉迷藏的问题</p>
<p>当div应用复杂的时候每个栏中又有一些链接，DIV等这个时候容易发生捉迷藏的问题。<br />
有些内容显示不出来，当鼠标选择这个区域是发现内容确实在页面。<br />
解决办法：对#layout使用line-height属性 或者给#layout使用固定高和宽。页面结构尽量简单。</p>
<p>11 高度不适应</p>
<p>高度不适应是当内层对象的高度发生变化时外层高度不能自动进行调节，特别是当内层对象使用<br />
margin 或paddign 时。<br />
例：<br />
&lt;div&gt;<br />
&lt;p&gt;p对象中的内容&lt;/p&gt;<br />
&lt;/div&gt;<br />
CSS：#box {background-color:#eee; }<br />
#box p {margin-top: 20px;margin-bottom: 20px; text-align:center; }<br />
解决方法：在P对象上下各加2个空的div对象CSS代码：.1{height:0px;overflow:hidden;}或者为DIV加上border属性。</p>

	标签：<a href="http://www.zfkun.com/tag/css" title="css" rel="tag">css</a>, <a href="http://www.zfkun.com/tag/ff" title="ff" rel="tag">ff</a>, <a href="http://www.zfkun.com/tag/hack" title="hack" rel="tag">hack</a>, <a href="http://www.zfkun.com/tag/ie" title="ie" rel="tag">ie</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/275.html" title="[转]IE6、IE7、IE8 CSS Bug兼容解决记录 (2011 年 06 月 14 日)" data-comment="1">[转]IE6、IE7、IE8 CSS Bug兼容解决记录</a></li>
	<li><a href="http://www.zfkun.com/182.html" title="add bookmark for ie &#038; ff &#038; opera (2011 年 03 月 20 日)" data-comment="0">add bookmark for ie &#038; ff &#038; opera</a></li>
	<li><a href="http://www.zfkun.com/205.html" title="欺骗IE不出现Flash激活框的小发现 (2011 年 03 月 20 日)" data-comment="0">欺骗IE不出现Flash激活框的小发现</a></li>
	<li><a href="http://www.zfkun.com/417.html" title="WordPress Rewrite SEO 之404方式折腾笔记 (2011 年 07 月 17 日)" data-comment="1">WordPress Rewrite SEO 之404方式折腾笔记</a></li>
	<li><a href="http://www.zfkun.com/109.html" title="Understanding and Solving Internet Explorer Leak Patterns (2010 年 02 月 28 日)" data-comment="0">Understanding and Solving Internet Explorer Leak Patterns</a></li>
	<li><a href="http://www.zfkun.com/366.html" title="Market Enabler &#8211; Android越狱改区利器 (2011 年 07 月 10 日)" data-comment="2">Market Enabler &#8211; Android越狱改区利器</a></li>
	<li><a href="http://www.zfkun.com/216.html" title="Javascript浏览器另类探测技巧 (2011 年 03 月 20 日)" data-comment="0">Javascript浏览器另类探测技巧</a></li>
	<li><a href="http://www.zfkun.com/91.html" title="CSS圆角—透明圆角化背景图片 (2010 年 01 月 21 日)" data-comment="0">CSS圆角—透明圆角化背景图片</a></li>
	<li><a href="http://www.zfkun.com/87.html" title="CSS圆角—基本圆角框 (2010 年 01 月 21 日)" data-comment="0">CSS圆角—基本圆角框</a></li>
	<li><a href="http://www.zfkun.com/131.html" title="5 个简单实用的 CSS 属性 (2010 年 03 月 09 日)" data-comment="0">5 个简单实用的 CSS 属性</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/142.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data URI 和 MHTML</title>
		<link>http://www.zfkun.com/138.html</link>
		<comments>http://www.zfkun.com/138.html#comments</comments>
		<pubDate>Sat, 10 Apr 2010 03:32:45 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[base64]]></category>
		<category><![CDATA[datauri]]></category>
		<category><![CDATA[mhtml]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=138</guid>
		<description><![CDATA[Data URI是由RFC 2397定义的一种把小文件直接嵌入文档的方案。通过如下语法就可以把小文件变成指定编码直接嵌入到页面中。
MHTML是MIME HTML (Multipurpose Internet Mail Extension HTML)的缩写，是由RFC 2557定义的把一个多媒体的页面所有内容都保存到同一个文档解决方案。这个方案是由微软提出从IE5.0开始支持，另外Opera9.0也开始支持，Safari可以把文件保存为.mht（MHTML文件的后缀）格式，但不支持显示它。 <a href="http://www.zfkun.com/138.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>Data URI</h3>
<p><a href="http://en.wikipedia.org/wiki/Data_URI_scheme">Data URI</a>是由<a href="http://tools.ietf.org/html/rfc2397">RFC 2397</a>定义的一种把小文件直接嵌入文档的方案。通过如下语法就可以把小文件变成指定编码直接嵌入到页面中：</p>
<pre><code>data:[&lt;MIME-type&gt;][;base64],&lt;data&gt;
</code></pre>
<ol>
<li>MIME-type：指定嵌入数据的<a href="http://zh.wikipedia.org/wiki/MIME">MIME</a>。其形式是<code>[type]/[subtype]; parameter</code>，比如png图片对应的MIME是image/png。parameter可以用來指定附加的信息，更多情況下是用于指定text/plain和text/htm等的文字编码方式的charset参数。默认是text/plain;charset=US-ASCII。</li>
<li>base64：声明后面的数据的编码是<a href="http://zh.wikipedia.org/wiki/Base64">base64</a>的，否则数据必须要用百分号编码（即对内容进行urlencode）。</li>
</ol>
<p> </p>
<p>在上个世纪<a href="http://www.w3.org/TR/1999/REC-html401-19991224/struct/objects.html#h-13.3.1">HTML4.01引入了Data URI方案</a>，到今天为止<a href="http://en.wikipedia.org/wiki/Data_URI_scheme#Web_browser_support">除了IE6和IE7之外，所有主流浏览器都支持</a>，但<a href="http://msdn.microsoft.com/en-us/library/cc848897%28VS.85%29.aspx">IE8对Data URI的支持还是有限制的</a>，只支持object（仅是图片时）、img、input type=image、link和CSS中的URL，且数据量不能大于32K。</p>
<h4>优点：</h4>
<ol>
<li><a href="http://developer.yahoo.com/performance/rules.html#num_http">减少HTTP请求数</a>，没有了TCP连接消耗和同一域名下浏览器的并发数限制。</li>
<li>对于小文件会降低带宽。虽然编码后数据量会增加，但是却减少了http头，当http头的数据量大于文件编码的增量，那么就会降低带宽。</li>
<li>对于HTTPS站点，HTTPS和HTTP混用会有安全提示，而HTTPS相对于HTTP来讲开销要大更多，所以Data URI在这方面的优势更明显。</li>
<li>可以把整个多媒体页面保存为一个文件。</li>
</ol>
<h4>缺点：</h4>
<ol>
<li>无法被重复利用，同一个文档应用多次同一个内容，则需要重复多次，数据量大量增加，增加了下载时间。</li>
<li>无法被独自缓存，所以其包含文档重新加载时，它也要重新加载。</li>
<li>客户端需要重新解码和显示，增加了点消耗。</li>
<li>不支持数据压缩，base64编码会增加1/3大小，而urlencode后数据量会增加更多。</li>
<li>不利于安全软件的过滤，同时也存在一定的安全隐患。</li>
</ol>
<h3>MHTML</h3>
<p>MHTML是<a href="http://en.wikipedia.org/wiki/MHTML">MIME HTML (Multipurpose Internet Mail Extension HTML)</a>的缩写，是由<a href="http://tools.ietf.org/html/rfc2557">RFC 2557</a>定义的把一个多媒体的页面所有内容都保存到同一个文档解决方案。这个方案是由微软提出从IE5.0开始支持，另外Opera9.0也开始支持，Safari可以把文件保存为.mht（MHTML文件的后缀）格式，但不支持显示它。</p>
<p>MHTML和Data URI还比较类似，有更强大的功能和更复杂的语法，并且没有Data URI中“无法被重复利用”的缺点，但MHTML使用起来不够灵活方便，比如对资源引用的URL在mht文件中可以是相对地址，否则必须是绝对地址。hedger在<a href="http://www.hedgerwow.com/360/dhtml/base64-image/demo.php">《Cross Browser Base64 Encoded Images Embedded in HTML》</a>针对IE的解决方案使用的是相对路径就是因为声明了<code>Content-type:message/rfc822</code>使IE按照MHTML来解析，如果不修改<code>Content-type</code>则需要使用MHTML协议，这个时候必须使用绝对路径，如<a href="http://www.phpied.com/mhtml-when-you-need-data-uris-in-ie7-and-under/">《MHTML – when you need data: URIs in IE7 and under》</a>。</p>
<h3>应用</h3>
<p>Data URI和MHTML两者的配合可以完整的解决所有的主流浏览器，它们由于无法被缓存和重复利用的缺陷，所以并不适合直接在页面中使用，但在CSS和JavaScript文件中对图片适当地使用有非常大的优越性：</p>
<ol>
<li>大大减少请求数，现在大型网站的CSS引用了大量的图片资源。</li>
<li>CSS和JavaScript都可以被缓存，间接的实现了数据的缓存。</li>
<li>利用CSS可以解决Data URI的重复利用问题</li>
<li>告别<a href="http://www.alistapart.com/articles/sprites">CSS Sprites</a>，CSS Sprites的出现是为了减少请求数，但它除了<a href="http://blog.vlad1.com/2009/06/22/to-sprite-or-not-to-sprite/">带来在不确定情况下的异常</a>外，CSS Sprites还需要人为的图片合并，即使有合并工具也依旧必须人为地在如何有效的拼图上耗费大量的时间，并带来维护的困难。当你遵循一定的设计原则后，你就可以完全抛弃CSS Sprites来编写CSS，最后使用工具在上传到服务器环节把图片转换成Data URI和MHTML，如<a href="http://bluehua.org/tag/data-uri">《利用data-uri合并样式表和图片》</a>中用python实现的工具，这可以节约大量的时间。</li>
<li>base64编码把图片文件增加了1/3，Data URI和MHTML同时使用相当于增加了2/3，但CSS和JavaScript可以使用<a href="http://developer.yahoo.com/performance/rules.html#gzip">gzip压缩</a>，其可以节省2/3的数据量，所以使用gzip压缩后的最终数据量是<code>(1 + 1/3) * 2 * (1/3) = 8/9</code>，所以最终流量是减少的。</li>
</ol>
<p>为了方便在CSS中实现Data URI和MHTML，我写了一个Data URI &amp; MHTML 生成器，你可以看利用其生成<a href="http://dancewithnet.com/lab/2009/data-uri-mhtml/create/1250345288.php">Data URI &amp; MHTML应用实例</a>。</p>
<p>其他DEMO：   <a href="http://phpied.com/files/mhtml/mhtml.html" target="_blank">demo1</a>      <a href="http://labs.aoao.org.cn/yep/test.html" target="_blank">demo2</a></p>

	标签：<a href="http://www.zfkun.com/tag/base64" title="base64" rel="tag">base64</a>, <a href="http://www.zfkun.com/tag/datauri" title="datauri" rel="tag">datauri</a>, <a href="http://www.zfkun.com/tag/mhtml" title="mhtml" rel="tag">mhtml</a><br />
]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/138.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5 个简单实用的 CSS 属性</title>
		<link>http://www.zfkun.com/131.html</link>
		<comments>http://www.zfkun.com/131.html#comments</comments>
		<pubDate>Tue, 09 Mar 2010 01:57:06 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[clip]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[cursor]]></category>
		<category><![CDATA[display]]></category>
		<category><![CDATA[min-height]]></category>
		<category><![CDATA[white-space]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=131</guid>
		<description><![CDATA[这篇文章介绍了 5 个实用的 CSS 属性。你应该很熟悉，但很可能很少会使用到。我并不是在谈论展望全新的 CSS3 属性，我指的是旧的 CSS2 中的属性，如：clip，min-height，white-space，curosr 和 display 等一些被所有浏览器广泛支持的属性。 <a href="http://www.zfkun.com/131.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>这篇文章介绍了 5 个实用的 <strong>CSS</strong> 属性。你应该很熟悉，但很可能很少会使用到。我并不是在谈论展望全新的 CSS3 属性，我指的是旧的 CSS2 中的属性，如：clip，min-height，white-space，curosr 和 display 等一些被所有浏览器广泛支持的属性。因此，千万不要错过这篇文章，因为你可能发现它们竟有如此之大的用途。</p>
<p><strong>1、CSS Clip</strong></p>
<p>剪辑 (clip) 属性就像一个面具。它允许你使用矩形掩盖页面元素的内容。要剪辑一个元素：你必须指定其 position 属性为 absolute，然后指定相对于元素的 top，right，bottom，left 值。</p>
<p><img src="http://www.blueidea.com/articleimg/2010/03/7410/01.gif" border="0" alt="" width="470" height="349" /></p>
<p><strong>图片剪辑实例（<a href="http://www.webdesignerwall.com/wp-content/uploads/2009/11/css-clip.html" target="_blank">演示</a>）</strong></p>
<p>以下示例演示了如何使用 clip 属性掩盖一张图片。首先，指定 &lt;div&gt; 元素为 position:relative，然后指定 &lt;img&gt; 元素为 position:absolute，并且根据实际需要设定 rect 值。</p>
<p><img src="http://www.blueidea.com/articleimg/2010/03/7410/02.gif" border="0" alt="" width="470" height="219" /></p>
<pre name="code" class="css">
.clip {
  position: relative;
  height: 130px;
  width: 200px;
  border: solid 1px #ccc;
}
.clip img {
  position: absolute;
  clip: rect(30px 165px 100px 30px);
}
</pre>
<pre><strong>图像调整尺寸和剪辑（<a href="http://www.webdesignerwall.com/wp-content/uploads/2009/11/css-clip.html" target="_blank">演示</a>）</strong></pre>
<p>在这个示例中，我将展示如何调整图像尺寸和剪辑图片。素材图片是矩形的，我想将其削减至 50％ 的尺寸，用来创建一个正方形格式的缩略图。因此，我用宽度和高度属性来调整图像，并使用 clip 剪辑属性予以掩盖。然后用 left 属性将图片移开左侧 15px 的距离。</p>
<p><img src="http://www.blueidea.com/articleimg/2010/03/7410/03.gif" border="0" alt="" width="470" height="422" /></p>
<pre name="code" class="css">
.gallery li {
  float: left;
  margin: 0 10px 0 0;
  position: relative;
  width: 70px;
  height: 70px;
  border: solid 1px #000;
}
.gallery img {
  width: 100px;
  height: 70px;
  position: absolute;
  clip: rect(0 85px 70px 15px);
  left: -15px;
}
</pre>
<pre><strong>2、Min-height （<a href="http://www.webdesignerwall.com/wp-content/uploads/2009/11/min-height.html" target="_blank">演示</a>）</strong></pre>
<p>min-height 属性允许你指定元素的最小高度，适用于需要平衡布局的情况。我将它用于 <a href="http://jobs.webdesignerwall.com/" target="_blank">Job 面板</a>上，以确保内容区域高于侧边栏。</p>
<p><img src="http://www.blueidea.com/articleimg/2010/03/7410/04.gif" border="0" alt="" width="470" height="270" /></p>
<pre name="code" class="css">
.with_minheight {
  min-height: 550px;
}
</pre>
<p><strong>IE6 的 Min-height hack</strong></p>
<p>注：神奇的 IE6 原生不支持 min-height 属性，不过幸好有一个 <a href="http://www.dustindiaz.com/min-height-fast-hack/">min-height hack</a>。</p>
<pre name="code" class="css">
.with_minheight {
  min-height:550px;
  height:auto !important;
  height:550px;
}
</pre>
<pre><strong>3、White-space（<a href="http://www.webdesignerwall.com/wp-content/uploads/2009/11/white-space.html" target="_blank">演示</a>）</strong></pre>
<p>white-space 属性指定了元素中空白的处理方式。比如，指定 white-space:nowrap 会阻止文本自动换行。</p>
<p><img src="http://www.blueidea.com/articleimg/2010/03/7410/05.gif" border="0" alt="" width="470" height="258" /></p>
<pre name="code" class="css">
em {
  white-space: nowrap;
}
</pre>
<p><strong>4、Cursor（<a href="http://www.webdesignerwall.com/wp-content/uploads/2009/11/cursor.html" target="_blank">演示</a>）</strong></p>
<p>如果你改变了按钮的行为，其指针也应该随之改变。比如，当一个按钮不可用时，指针应该改变为默认的箭头，来表明它不可点击。因此，cursor 属性在开发 Web 应用程序时相当有用。</p>
<p><img src="http://www.blueidea.com/articleimg/2010/03/7410/06.gif" border="0" alt="" width="470" height="200" /></p>
<pre name="code" class="css">
.disabled {
  cursor: default;
}

.busy {
  cursor: wait;
}

.clickable:hover {
  cursor: pointer;
}
</pre>
<pre><strong>5、Display inline / block（<a href="http://www.webdesignerwall.com/wp-content/uploads/2009/11/display.html" target="_blank">演示</a>）</strong></pre>
<p>如果你不知道：块级元素是作为独立的一行来渲染的，而行内元素是在同一行被渲染的。&lt;div&gt;，&lt;h1&gt; 和 &lt;p&gt; 标签都是块级元素，&lt;em&gt;，&lt;span&gt;，&lt;strong&gt; 都是行内元素。通过 display:inline 或 block 的方式，你可以重设这些元素的 display 样式。</p>
<p><img src="http://www.blueidea.com/articleimg/2010/03/7410/07.gif" border="0" alt="" width="470" height="206" /></p>
<pre name="code" class="css">
.block em {
  display: block;
}

.inline h4, .inline p {
  display: inline;
}
</pre>
<pre>英文原稿：<a href="http://www.webdesignerwall.com/tutorials/5-simple-but-useful-css-properties" target="_blank">5 Simple, But Useful CSS Properties | WebDesignWall</a>
翻译整理：<a href="http://www.mangguo.org/5-simple-but-useful-css-properties" target="_blank">5 个简单实用的 CSS 属性 | 芒果</a></pre>
<p>本文链接：<a href="http://www.blueidea.com/tech/web/2010/7410.asp" target="_blank">http://www.blueidea.com/tech/web/2010/7410.asp</a></p>

	标签：<a href="http://www.zfkun.com/tag/clip" title="clip" rel="tag">clip</a>, <a href="http://www.zfkun.com/tag/css" title="css" rel="tag">css</a>, <a href="http://www.zfkun.com/tag/cursor" title="cursor" rel="tag">cursor</a>, <a href="http://www.zfkun.com/tag/display" title="display" rel="tag">display</a>, <a href="http://www.zfkun.com/tag/min-height" title="min-height" rel="tag">min-height</a>, <a href="http://www.zfkun.com/tag/white-space" title="white-space" rel="tag">white-space</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/163.html" title="获取 Textarea 的光标位置 (2011 年 01 月 13 日)" data-comment="0">获取 Textarea 的光标位置</a></li>
	<li><a href="http://www.zfkun.com/275.html" title="[转]IE6、IE7、IE8 CSS Bug兼容解决记录 (2011 年 06 月 14 日)" data-comment="1">[转]IE6、IE7、IE8 CSS Bug兼容解决记录</a></li>
	<li><a href="http://www.zfkun.com/142.html" title="IE6+和FF的CSS Hack (2010 年 04 月 23 日)" data-comment="0">IE6+和FF的CSS Hack</a></li>
	<li><a href="http://www.zfkun.com/91.html" title="CSS圆角—透明圆角化背景图片 (2010 年 01 月 21 日)" data-comment="0">CSS圆角—透明圆角化背景图片</a></li>
	<li><a href="http://www.zfkun.com/87.html" title="CSS圆角—基本圆角框 (2010 年 01 月 21 日)" data-comment="0">CSS圆角—基本圆角框</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/131.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comet—“服务器推”技术</title>
		<link>http://www.zfkun.com/115.html</link>
		<comments>http://www.zfkun.com/115.html#comments</comments>
		<pubDate>Wed, 03 Mar 2010 06:02:46 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[push]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=115</guid>
		<description><![CDATA[Comet指的是一种Web应用程序架构。可以直接说，它不是一种技术，而是一种思想，只是这种思想采用了已有的技术去实现。在这种思想里，客户端（Client）不需要显式地向服务器端（Server）发出请求，Server会在其数据发生变化的时候主动将数据异步发送给Client，从而使Client能够及时更新数据并呈现给用户。它不同于传统的Web，也不同于当前流行的Ajax，这种思想非常架构思想非常适合event-driven(事件驱动)式的Web应用和对交互性及实时性要求很强的应用，比如股票交易，聊天室，Web IM，网游等。 <a href="http://www.zfkun.com/115.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>一、名称解释：</h2>
<p>Comet最早是由Alex Russell（Dojo Toolkit 项目主管和Dojo Foundation主席）在自己的博客中提出的术语，他是这样说的：”New services like Jot Live and Meebo are built with a style of data transmission that is neither traditional nor Ajax. Their brand of low-latency data transfer to the browser is unique, and it is becoming ever-more common. Lacking a better term, I’ve taken to calling this style of event-driven, server-push data streaming “Comet”.” “They all use long-lived HTTP connections to reduce the latency with which messages are passed to the server. In essence, they do not poll the server occasionally. Instead the server has an open line of communication with which it can push data to the client.”</p>
<p>Comet指的是一种Web应用程序架构。可以直接说，它不是一种技术，而是一种思想，只是这种思想采用了已有的技术去实现。在这种思想里，客户端（Client）不需要显式地向服务器端（Server）发出请求，Server会在其数据发生变化的时候主动将数据异步发送给Client，从而使Client能够及时更新数据并呈现给用户。它不同于传统的Web，也不同于当前流行的Ajax，这种思想非常架构思想非常适合event-driven(事件驱动)式的Web应用和对交互性及实时性要求很强的应用，比如股票交易，聊天室，Web IM，网游等。</p>
<h2>二、成功案例：</h2>
<ul>
<li><a href="http://mail.google.com/mail/help/chat.html" target="_blank">GMail’s GTalk integration</a></li>
<li><a href="http://jotlive.com/" target="_blank">Jot Live</a></li>
<li><a href="http://renkoo.com/" target="_blank">Renkoo</a></li>
<li><a href="http://meebo.com/" target="_blank">Meebo</a></li>
</ul>
<h2>三、实现方式：</h2>
<p>Comet使用Client和Server之前的HTTP长链接最为数据传输的通道。</p>
<p>实现Comet，最常见的有下面两种方式：</p>
<ol>
<li>Ajax的长轮询（long-polling）：Javascript在处理完服务器返回的信息后再次发出请求，重新建立连接。不同于一般的Ajax，Javascript请求Server，无数据时Server不中断请求，still loading，在一定时间内，获取到数据后，返回请求，又Javascript获取数据后再次发出请求，由此轮询。需要注意的是请求的间隔时间以及每次请求的最长Loading时间。<br />
优点：异步请求；无需浏览器任何插件支持；采用Ajax技术，兼容性强；<br />
缺点：会产生大量的通信量，只能通过增加轮询的时间间隔来减轻Server的压力；</li>
<li>Iframe结合Htmlfile流（streaming）：通过在页面上嵌入一个隐藏的Iframe，设置其src属性为一个长连接的请求，Server采用flush方式将数据作为前端Javascript函数的参数传递；<br />
优点：不会有很大的通信量，而且数据接收非常及时，并且无中断；<br />
缺点：会产生进度条的Loading状态并一直穿着，用户使用体验很不好，在Google Talk中，通过Htmlfile Active解决了IE下的进度条显示问题；保持长期链接也非常耗服务器资源；</li>
</ol>
<h2>四、临时采用方案：</h2>
<p>目前，白社会(bai.sohu.com)采用了第一种方式来实现实时消息的推送，这种方式还存在一个问题就是，在多个tab页下，如何保证没有相同域的长连接请求（IE在同域下只能同时支持两个长链接），于是采用了子域形式来区分多个域，以保证每个tab页下访问的地址都不在一个域名下，此时问题又出来了，出现了Ajax跨域名请求，不过这个问题比较常见，解决方案也很多，我们采用的是Iframe形式；由此，为了实现Comet，我们走了很长一条路，虽然路的确走完了，但是走得很长很艰难，这也是为什么称它为“临时解决方案”，因为它并不是一个完美的方案，但我也相信，以后会更加完美。</p>
<h2>五、现有可参考框架</h2>
<ol>
<li>Cometd：官方地址：<a href="http://www.cometd.org" target="_blank">www.cometd.org<br />
</a>可以参考<a href="http://www.blogjava.net/xmatthew/archive/2008/11/20/208911.html" target="_blank">http://www.blogjava.net/xmatthew/archive/2008/11/20/208911.html</a></li>
<li>Pushlet：官方地址：<a href="http://www.pushlets.com" target="_blank">www.pushlets.com</a><br />
pushlet 提供了基于 AJAX 的 JavaScript 库文件用于实现长轮询方式的”服务器推”；还提供了基于 iframe 的 JavaScript 库文件用于实现流方式的”服务器推”。<br />
可以参考<a href="http://http://www.javaeye.com/topic/89158" target="_blank">http://www.javaeye.com/topic/89158</a></li>
</ol>
<h2>六、文章参考</h2>
<ol>
<li><a href="http://www.ibm.com/developerworks/cn/web/wa-lo-comet/" target="_blank">Comet：基于 HTTP 长连接的”服务器推”技术</a></li>
<li><a href="http://www.ibm.com/developerworks/cn/web/wa-lo-w2fpak-comet/index.html" target="_blank">实战 Comet 应用程序开发</a></li>
<li><a href="http://en.wikipedia.org/wiki/Comet_(programming)" target="_blank">Comet on wikipedia</a></li>
</ol>
<p>最后，本人对Comet也未进行深入的研究，只是希望通过此文能给大家起一个抛砖引玉的作用，希望大家能够在客户端实时技术上能够起点帮助作用，能够越来越丰富我们前端技术。</p>
<p>原文地址： <a href="http://ued.sohu.com/article/118">http://ued.sohu.com/article/118</a></p>

	标签：<a href="http://www.zfkun.com/tag/ajax" title="ajax" rel="tag">ajax</a>, <a href="http://www.zfkun.com/tag/comet" title="comet" rel="tag">comet</a>, <a href="http://www.zfkun.com/tag/js" title="js" rel="tag">js</a>, <a href="http://www.zfkun.com/tag/push" title="push" rel="tag">push</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/147.html" title="前端资源文件缓存清除一法 (2010 年 11 月 25 日)" data-comment="0">前端资源文件缓存清除一法</a></li>
	<li><a href="http://www.zfkun.com/394.html" title="[转]利用跨域资源共享（CORS）实现ajax跨域调用 (2011 年 07 月 15 日)" data-comment="0">[转]利用跨域资源共享（CORS）实现ajax跨域调用</a></li>
	<li><a href="http://www.zfkun.com/154.html" title="随机颜色 (2011 年 01 月 12 日)" data-comment="0">随机颜色</a></li>
	<li><a href="http://www.zfkun.com/59.html" title="腾讯TT、遨游浏览器检测 (2010 年 01 月 16 日)" data-comment="0">腾讯TT、遨游浏览器检测</a></li>
	<li><a href="http://www.zfkun.com/55.html" title="绝对震撼!10款动感图片展示js代码 (2010 年 01 月 16 日)" data-comment="0">绝对震撼!10款动感图片展示js代码</a></li>
	<li><a href="http://www.zfkun.com/176.html" title="原生JSON.parse解析异常问题 (2011 年 03 月 18 日)" data-comment="0">原生JSON.parse解析异常问题</a></li>
	<li><a href="http://www.zfkun.com/80.html" title="[转]Google Closure: 糟糕的JavaScript (2010 年 01 月 19 日)" data-comment="0">[转]Google Closure: 糟糕的JavaScript</a></li>
	<li><a href="http://www.zfkun.com/226.html" title="Windows7下搭建Node.js环境 (2011 年 04 月 06 日)" data-comment="1">Windows7下搭建Node.js环境</a></li>
	<li><a href="http://www.zfkun.com/388.html" title="window.open() 之句柄保持和重连 (2011 年 07 月 14 日)" data-comment="0">window.open() 之句柄保持和重连</a></li>
	<li><a href="http://www.zfkun.com/109.html" title="Understanding and Solving Internet Explorer Leak Patterns (2010 年 02 月 28 日)" data-comment="0">Understanding and Solving Internet Explorer Leak Patterns</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/115.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Understanding and Solving Internet Explorer Leak Patterns</title>
		<link>http://www.zfkun.com/109.html</link>
		<comments>http://www.zfkun.com/109.html#comments</comments>
		<pubDate>Sun, 28 Feb 2010 06:01:57 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[closure]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[gc]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[leak]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[reference]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=109</guid>
		<description><![CDATA[In the past, memory leaks haven't posed huge problems for Web developers. Pages were kept relatively simple and navigation between different locations within a site was a great way to clean up any loose memory. If there was a leak, it was most likely small enough to go unnoticed.

New Web applications live up to higher standards. A page might run for hours without being navigated and retrieve updated information dynamically through Web services. Language features are pushed to the breaking point by combining complex event schemes, object-oriented JScript, and closures to produce entire applications. With these and other changes, certain memory leak patterns are becoming more prominent, especially those previously hidden by navigation.

The good news is that memory leak patterns can be easily spotted if you know what to look for. Most of the troublesome patterns you might face have known workarounds requiring only a small amount of extra work on your behalf. While some pages might still fall prey to small memory leaks, the most noticeable ones can be easily removed. <a href="http://www.zfkun.com/109.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2><strong>Understanding and Solving Internet Explorer Leak Patterns</strong></h2>
<p><!--Content type: PSDK_3. Transform: webcollection2mtps.xslt.--><a id="ie_leakpattern"><!----></a></p>
<p>Justin Rogers<br />
Microsoft Corporation</p>
<p>June 2005</p>
<h2>The Evolution of the Web Developer</h2>
<p>In the past, memory leaks haven&#8217;t posed huge problems for Web developers. Pages were kept relatively simple and navigation between different locations within a site was a great way to clean up any loose memory. If there was a leak, it was most likely small enough to go unnoticed.</p>
<p>New Web applications live up to higher standards. A page might run for hours without being navigated and retrieve updated information dynamically through Web services. Language features are pushed to the breaking point by combining complex event schemes, object-oriented JScript, and closures to produce entire applications. With these and other changes, certain memory leak patterns are becoming more prominent, especially those previously hidden by navigation.</p>
<p>The good news is that memory leak patterns can be easily spotted if you know what to look for. Most of the troublesome patterns you might face have known workarounds requiring only a small amount of extra work on your behalf. While some pages might still fall prey to small memory leaks, the most noticeable ones can be easily removed.</p>
<h2>Leak Patterns</h2>
<p>The following sections will discuss patterns of memory leaks and point out some common examples of each pattern. One great example of a pattern is the closure feature of JScript, while another example is the use of closures in hooking events. If you&#8217;re familiar with the event hooking example, you might be able to find and fix many of your memory leaks, but other closure-related issues might go unnoticed.</p>
<p>Now, let&#8217;s look at the following patterns:</p>
<ol>
<li>Circular References—When mutual references are counted between Internet Explorer&#8217;s COM infrastructure and any scripting engine, objects can leak memory. This is the broadest pattern.</li>
<li>Closures—Closures are a specific form of circular reference that pose the largest pattern to existing Web application architectures. Closures are easy to spot because they rely on a specific language keyword and can be searched for generically.</li>
<li>Cross-Page Leaks—Cross-page leaks are often very small leaks of internal book-keeping objects as you move from site to site. We&#8217;ll examine the DOM Insertion Order issue, along with a workaround that shows how small changes to your code can prevent the creation of these book-keeping objects.</li>
<li>Pseudo-Leaks—These aren&#8217;t really leaks, but can be extremely annoying if you don&#8217;t understand where your memory is going. We&#8217;ll examine the script element rewriting and how it appears to leak quite a bit of memory, when it is really performing as required.</li>
</ol>
<h2>Circular References</h2>
<p>Circular references are the root of nearly every leak. Normally, script engines handle circular references through their garbage collectors, but certain unknowns can prevent their heuristics from working properly. The unknown in the case of IE would be the status of any DOM elements that a portion of script has access to. The basic principle would be as follows:</p>
<p><!--src=[ie_leak_patterns_fig01.gif]--><img src="http://i.msdn.microsoft.com/Bb250448.ie_leak_patterns_fig01(en-us,VS.85).gif" alt="Figure 1 Basic Circular Reference Pattern" /></p>
<p><strong>Figure 1. Basic Circular Reference Pattern</strong></p>
<p>The cause of the leak in this pattern is based on COM reference counting. The script engine objects will hold a reference to the DOM element and will be waiting for any outstanding references to be removed before cleaning up and releasing the DOM element pointer. In our case we have two references on the script engine object: the script engine scope, and the DOM element expando property. While terminating the script engine will release the first reference, the DOM element reference will never be released because it is waiting on the script engine object to release it! You might think it would be easy to detect this scenario and fix the problem, but in practice the basic case presented is only the tip of the iceberg. You could have circular references at the end of a 30 object chain and those would be much harder to detect.</p>
<p>If you are wondering what this pattern looks like in HTML, you can cause a leak by using a global script engine variable and a DOM element as shown.</p>
<pre><code>&lt;html&gt;
    &lt;head&gt;
        &lt;script language="JScript"&gt;

        var myGlobalObject;

        function SetupLeak()
        {
            // First set up the script scope to element reference
            myGlobalObject =
                document.getElementById("LeakedDiv");

            // Next set up the element to script scope reference
            document.getElementById("LeakedDiv").expandoProperty =
                myGlobalObject;
        }

        function BreakLeak()
        {
            document.getElementById("LeakedDiv").expandoProperty =
                null;
        }
        &lt;/script&gt;
    &lt;/head&gt;

    &lt;body onload="SetupLeak()" onunload="BreakLeak()"&gt;
        &lt;div id="LeakedDiv"&gt;&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>To break the leak pattern you can make use of explicit null assignments. By assigning null before the document unloads you are telling the script engine there is no longer an association between the element and the object inside the engine. It can now properly clean up references and will release the DOM element. In this case, you as the Web developer know more about the relationships between your objects than the script engine does.</p>
<p>While that is the basic pattern, it can be difficult to spot more complex scenarios. A common usage of object-oriented JScript is to extend DOM elements by encapsulating them inside of a JScript object. During the construction process, you generally pass in the DOM element you want to attach to and then store a reference to the DOM element on the newly constructed object while at the same time storing an instance of the newly constructed object on the DOM element. That way your application model always has access to everything it needs. The problem is this is a very explicit circular reference, but because it uses different language aspects it might go unnoticed. Breaking up this kind of pattern can become more complex, and you can use the same simple methods discussed earlier.</p>
<pre><code>&lt;html&gt;
    &lt;head&gt;
        &lt;script language="JScript"&gt;

        function Encapsulator(element)
        {
            // Set up our element
            this.elementReference = element;

            // Make our circular reference
            element.expandoProperty = this;
        }

        function SetupLeak()
        {
            // The leak happens all at once
            new Encapsulator(document.getElementById("LeakedDiv"));
        }

        function BreakLeak()
        {
            document.getElementById("LeakedDiv").expandoProperty =
                null;
        }
        &lt;/script&gt;
    &lt;/head&gt;

    &lt;body onload="SetupLeak()" onunload="BreakLeak()"&gt;
        &lt;div id="LeakedDiv"&gt;&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>More complex solutions to this problem involve registration schemes to note which elements/properties need to be unhooked, having the peer element hook events so that it can clean up before the document unloads, but often you can run into additional leak patterns without actually fixing the problem.</p>
<h2>Closures</h2>
<p>Closures are very often responsible for leaks because they create circular references without the programmer being fully aware. It isn&#8217;t immediately obvious that parent function parameters and local variables will be frozen in time, referenced, and held until the closure itself is released. In fact this has become such a common programming tactic, and users have run into issues so often, there are quite a few resources already available. Because they detail some of the history behind closures as well as some of the specific instances of closure leaks we&#8217;ll check those out after applying the closure model to our circular reference diagram and figuring out where these extra references are coming from.</p>
<p><!--src=[ie_leak_patterns_fig02.gif]--><img src="http://i.msdn.microsoft.com/Bb250448.ie_leak_patterns_fig02(en-us,VS.85).gif" alt="Figure 2 Circular References with Closures" /></p>
<p><strong>Figure 2. Circular References with Closures</strong></p>
<p>With normal circular references there were two solid objects holding references to each other, but closures are different. Rather than make the references directly, they are made instead by importing information from their parent function&#8217;s scope. Normally, a function&#8217;s local variables and the parameters used when calling a function only exist for the lifetime of the function itself. With closures, these variables and parameters continue to have an outstanding reference as long as the closure is alive, and since closures can live beyond the lifetime of their parent function so can any of the locals and parameters in that function. In the example, Parameter 1 would normally be released as soon as the function call was over. Because we&#8217;ve added a closure, a second reference is made, and that second reference won&#8217;t be released until the closure is also released. If you happened to attach the closure to an event, then you would have to detach it from that event. If you happened to attach the closure to an expando then you would need to null that expando.</p>
<p>Closures are also created per call, so calling this function twice will create two individual closures, each holding references to the parameters passed in each time. Because of this transparent nature it is really easy to leak closures. The following example provides the most basic of leaks using closures:</p>
<pre><code>&lt;html&gt;
    &lt;head&gt;
        &lt;script language="JScript"&gt;

        function AttachEvents(element)
        {
            // This structure causes element to ref ClickEventHandler
            element.attachEvent("onclick", ClickEventHandler);

            function ClickEventHandler()
            {
                // This closure refs element
            }
        }

        function SetupLeak()
        {
            // The leak happens all at once
            AttachEvents(document.getElementById("LeakedDiv"));
        }

        function BreakLeak()
        {
        }
        &lt;/script&gt;
    &lt;/head\&gt;

    &lt;body onload="SetupLeak()" onunload="BreakLeak()"&gt;
        &lt;div id="LeakedDiv"&gt;&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>If you are wondering how to break this leak, it won&#8217;t be as easy as a normal circular reference. The “closure” can be viewed as a temporary object that exists in the function scope. Once the function exits, you lose reference to the closure itself, so what would you end up calling <strong>detachEvent</strong> with? One of the most interesting approaches to this problem was demonstrated on <a id="ctl00_MTCS_main_ctl03" onclick="javascript:Track('ctl00_MTCS_main_ctl00|ctl00_MTCS_main_ctl03',this);" href="http://spaces.msn.com/members/siteexperts/Blog/cns!1pNcL8JwTfkkjv4gg6LkVCpw!338.entry">MSN spaces thanks to Scott Isaacs</a>. The approach uses a second closure to additionally hook the window&#8217;s <strong>onUnload</strong> event, and because this closure has the same “scoped” objects it is able to detach the event, detach itself, and finish the clean up process. To make everything easily fit with our model we can also store the closure on an expando, detach it, and then null the expando, as in the following example.</p>
<pre><code>&lt;html&gt;
    &lt;head&gt;
        &lt;script language="JScript"&gt;

        function AttachEvents(element)
        {
            // In order to remove this we need to put
            // it somewhere. Creates another ref
            element.expandoClick = ClickEventHandler;

            // This structure causes element to ref ClickEventHandler
            element.attachEvent("onclick", element.expandoClick);

            function ClickEventHandler()
            {
                // This closure refs element
            }
        }

        function SetupLeak()
        {
            // The leak happens all at once
            AttachEvents(document.getElementById("LeakedDiv"));
        }

        function BreakLeak()
        {
            document.getElementById("LeakedDiv").detachEvent("onclick",
                document.getElementById("LeakedDiv").expandoClick);
            document.getElementById("LeakedDiv").expandoClick = null;
        }
        &lt;/script&gt;
    &lt;/head&gt;

    &lt;body onload="SetupLeak()" onunload="BreakLeak()"&gt;
        &lt;div id="LeakedDiv"&gt;&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>In a <a id="ctl00_MTCS_main_ctl04" onclick="javascript:Track('ctl00_MTCS_main_ctl00|ctl00_MTCS_main_ctl04',this);" href="http://support.microsoft.com/default.aspx?scid=KB;EN-US;830555">Knowledge Base article</a>, we actually recommend that you try not to use closures unless they are necessary. In the example, I&#8217;ve given we don&#8217;t need to use a closure as the event handler, instead we can move the closure to a global scope. When the closure becomes a function, it no longer inherits the parameters or local variables from its parent function so we don&#8217;t have to worry about closure-based circular references at all. Most code can be fixed by creating an architecture that doesn&#8217;t rely on closures where they aren&#8217;t necessary.</p>
<p>Finally, Eric Lippert, one of the developers of the scripting engines, has a <a id="ctl00_MTCS_main_ctl05" onclick="javascript:Track('ctl00_MTCS_main_ctl00|ctl00_MTCS_main_ctl05',this);" href="http://blogs.msdn.com/ericlippert/archive/2003/09/17/53028.aspx">great post on closures in general</a>. His final recommendations are also along the lines of only using closures when truly necessary. While his article doesn&#8217;t mention any of the workarounds for the closure pattern, hopefully we&#8217;ve covered enough examples here to get you started.</p>
<h2>Cross-Page Leaks</h2>
<p>Leaks that are based on order of insertion are almost always caused by the creation of intermediate objects that don&#8217;t get cleaned up properly. That is exactly the case when creating dynamic elements and then attaching them to the DOM. The basic pattern is attaching two dynamically created objects together temporarily which creates a scope from the child to the parent element. Later, when you attach this two-element tree to the primary tree, they both inherit the scope of the document and a temporary object is leaked. The following diagram shows two methods for attaching dynamically created elements to the tree. In the first model, attach each child element to its parent, and finally attach the entire subtree to the primary tree. This method can cause leaks through temporary objects if other conditions are met. In the second model, we attach elements into the primary tree working our way from top-level dynamically created element down through all of the children. Because each attachment inherits the scope of the primary document we never generate temporary scopes. This method is much better at avoiding potential memory leaks.</p>
<p><!--src=[ie_leak_patterns_fig03.gif]--><img src="http://i.msdn.microsoft.com/Bb250448.ie_leak_patterns_fig03(en-us,VS.85).gif" alt="Figure 3 DOM Insertion Order Leak Model" /></p>
<p><strong>Figure 3. DOM Insertion Order Leak Model</strong></p>
<p>Next, we are going to cover an example of a leak that is transparent to most leak-detection algorithms. Because we don&#8217;t leak any publicly visible elements and the objects we leak are very small you might never notice this problem. For our example to work, the dynamically created elements will have to contain a script pointer in the form of an inline function. This will allow us to leak an internal script object that is created temporarily as we attach elements together. Because the leak is small, we&#8217;ll have to run thousands of samples. In fact, the objects leaked are only a few bytes. By running the sample and navigating to an empty page, you can see the difference in memory consumption between the two versions. When we use the first DOM model of attaching child to parent, then parent to the primary tree, our memory usage goes up a bit. This is a cross-navigation leak and the memory isn&#8217;t reclaimed until you restart the IE process. If you run the sample a few more times, using the second DOM model of attaching the parent to the primary tree and then the child to the parent, your memory won&#8217;t continue to climb and you&#8217;ll find that you&#8217;ve fixed the cross-page navigation leak.</p>
<pre><code>&lt;html&gt;
    &lt;head&gt;
        &lt;script language="JScript"&gt;

        function LeakMemory()
        {
            var hostElement = document.getElementById("hostElement");

            // Do it a lot, look at Task Manager for memory response

            for(i = 0; i &lt; 5000; i++)
            {
                var parentDiv =
                    document.createElement("&lt;div onClick='foo()'&gt;");
                var childDiv =
                    document.createElement("&lt;div onClick='foo()'&gt;");

                // This will leak a temporary object
                parentDiv.appendChild(childDiv);
                hostElement.appendChild(parentDiv);
                hostElement.removeChild(parentDiv);
                parentDiv.removeChild(childDiv);
                parentDiv = null;
                childDiv = null;
            }
            hostElement = null;
        }

        function CleanMemory()
        {
            var hostElement = document.getElementById("hostElement");

            // Do it a lot, look at Task Manager for memory response

            for(i = 0; i &lt; 5000; i++)
            {
                var parentDiv =
                    document.createElement("&lt;div onClick='foo()'&gt;");
                var childDiv =
                    document.createElement("&lt;div onClick='foo()'&gt;");

                // Changing the order is important, this won't leak
                hostElement.appendChild(parentDiv);
                parentDiv.appendChild(childDiv);
                hostElement.removeChild(parentDiv);
                parentDiv.removeChild(childDiv);
                parentDiv = null;
                childDiv = null;
            }
            hostElement = null;
        }
        &lt;/script&gt;
    &lt;/head&gt;

    &lt;body&gt;
        &lt;button onclick="LeakMemory()"&gt;Memory Leaking Insert&lt;/button&gt;
        &lt;button onclick="CleanMemory()"&gt;Clean Insert&lt;/button&gt;
        &lt;div id="hostElement"&gt;&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>This leak deserves clarification, because our workaround goes against some best practices in IE. The key points to understand about the leak are that DOM elements are being created with scripts already attached. This is actually crucial to the leak, because if we create DOM elements that don&#8217;t contain any script and attach them together in the same manner we don&#8217;t have a leak problem. This gives rise to a second workaround that might be even better for larger subtrees (in the example we only have two elements, so building the tree off the primary DOM isn&#8217;t a performance hit). The second workaround would be to create your elements with no scripts attached initially so that you can safely build your subtree. After you&#8217;ve attached your subtree to the primary DOM, go back and wire up any script events at that point. Remember to follow the principles for circular references and closures so you don&#8217;t cause a different leak in your code as you hook up your events.</p>
<p>I really wanted to point out this issue because it shows that not all memory leaks are easy to find. It could take thousands of iterations of a smaller pattern to become visible, and it might be something slight, like the order of insertion of DOM elements that causes the problem to arise. If you tend to program using only best practices, then you think you are safe, but this leak shows that even best practices can exhibit leaks. Our solution here was to improve upon the best practice or even introduce a new best practice in order to remove the leaking condition.</p>
<h2>Pseudo-Leaks</h2>
<p>Often times the actual behavior and expected behavior of some APIs can lead you to misdiagnose memory leaks. Pseudo-leaks almost always appear on the same page during dynamic scripting operations and should rarely be visible after navigation away from the page to a blank page. That is how you can eliminate the issue as a cross-page leak and then start to work on whether the memory consumption is expected. We&#8217;ll use script text rewriting as our example of a pseudo-leak.</p>
<p>Like the DOM Insertion Order issue, this issue also relies on the creation of temporary objects in order to “leak” memory. By rewriting the script text inside of a script element over and over again, slowly you&#8217;ll begin to leak various script engine objects that were attached to the previous contents. In particular, objects related to debugging script are left behind as are fully formed code elements.</p>
<pre><code>&lt;html&gt;
    &lt;head&gt;
        &lt;script language="JScript"&gt;

        function LeakMemory()
        {
            // Do it a lot, look at Task Manager for memory response

            for(i = 0; i &lt; 5000; i++)
            {
                hostElement.text = "function foo() { }";
            }
        }
        &lt;/script&gt;
    &lt;/head&gt;

    &lt;body&gt;
        &lt;button onclick="LeakMemory()"&gt;Memory Leaking Insert&lt;/button&gt;
        &lt;script id="hostElement"&gt;function foo() { }&lt;/script&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>If you run the above code and use the Task Manager trick again, while navigating between the “leaking” page and a blank page, you won&#8217;t notice a script leak. This script leak is entirely within a page and when you navigate away then you get your memory back. The reason this one is bad is due to expected behavior. You expect that after rewriting some script that the original script won&#8217;t stay around. But it really has to, because it might have been used already for event attachments and there might be outstanding reference counts. As you can see, this is a pseudo-leak. On the surface the amount of memory consumption looks really bad, but there is a completely valid reason.</p>
<h2>Conclusion</h2>
<p>Every Web developer builds a personal list of code examples that they know leak and learns to work around those leaks when they see them in code. This is extremely handy and is the reason the Web is relatively leak-free today. Thinking about the leaks in terms of patterns instead of individual code examples, you can start to develop even better strategies for dealing with them. The idea is to take them into account during the design phase and make sure you have plans for any potential leaks. Use defensive coding practices and assume that you&#8217;ll need to clean up all your own memory. While this is an overstatement of the problem, you very rarely need to clean up your own memory; it becomes obvious which variables and expando properties have the potential for leaking.</p>
<p>In the interest of patterns and design I highly recommend <a id="ctl00_MTCS_main_ctl07" onclick="javascript:Track('ctl00_MTCS_main_ctl00|ctl00_MTCS_main_ctl07',this);" href="http://spaces.msn.com/members/siteexperts/Blog/cns!1pNcL8JwTfkkjv4gg6LkVCpw!338.entry">Scott&#8217;s short blog entry</a> because it demonstrates a general purpose example of removing all closure-based leaks. It does require a bit more code, but the practice is sound and the improved pattern is easy to spot in code and to debug. Similar registration schemes can be used for expando-based circular references as long as care is taken that the registration method itself isn&#8217;t riddled with leaks (especially where closures are used)!</p>
<p><!----></p>
<p><!----></p>
<p><strong>About the author</strong></p>
<p><strong>Justin Rogers</strong> recently joined the Internet Explorer team as an Object Model developer working on extensibility and previously worked on such notable projects as the .NET QuickStart Tutorials, .NET Terrarium, and SQL Reporting Services Management Studio in SQL Server 2005.</p>

	标签：<a href="http://www.zfkun.com/tag/closure" title="closure" rel="tag">closure</a>, <a href="http://www.zfkun.com/tag/dom" title="dom" rel="tag">dom</a>, <a href="http://www.zfkun.com/tag/gc" title="gc" rel="tag">gc</a>, <a href="http://www.zfkun.com/tag/ie" title="ie" rel="tag">ie</a>, <a href="http://www.zfkun.com/tag/js" title="js" rel="tag">js</a>, <a href="http://www.zfkun.com/tag/leak" title="leak" rel="tag">leak</a>, <a href="http://www.zfkun.com/tag/memory" title="memory" rel="tag">memory</a>, <a href="http://www.zfkun.com/tag/reference" title="reference" rel="tag">reference</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/80.html" title="[转]Google Closure: 糟糕的JavaScript (2010 年 01 月 19 日)" data-comment="0">[转]Google Closure: 糟糕的JavaScript</a></li>
	<li><a href="http://www.zfkun.com/211.html" title="JavaScript Memory Leak Detector (v2) (2011 年 03 月 20 日)" data-comment="0">JavaScript Memory Leak Detector (v2)</a></li>
	<li><a href="http://www.zfkun.com/125.html" title="contains vs compareDocumentPosition (2010 年 03 月 07 日)" data-comment="0">contains vs compareDocumentPosition</a></li>
	<li><a href="http://www.zfkun.com/154.html" title="随机颜色 (2011 年 01 月 12 日)" data-comment="0">随机颜色</a></li>
	<li><a href="http://www.zfkun.com/59.html" title="腾讯TT、遨游浏览器检测 (2010 年 01 月 16 日)" data-comment="0">腾讯TT、遨游浏览器检测</a></li>
	<li><a href="http://www.zfkun.com/55.html" title="绝对震撼!10款动感图片展示js代码 (2010 年 01 月 16 日)" data-comment="0">绝对震撼!10款动感图片展示js代码</a></li>
	<li><a href="http://www.zfkun.com/205.html" title="欺骗IE不出现Flash激活框的小发现 (2011 年 03 月 20 日)" data-comment="0">欺骗IE不出现Flash激活框的小发现</a></li>
	<li><a href="http://www.zfkun.com/176.html" title="原生JSON.parse解析异常问题 (2011 年 03 月 18 日)" data-comment="0">原生JSON.parse解析异常问题</a></li>
	<li><a href="http://www.zfkun.com/147.html" title="前端资源文件缓存清除一法 (2010 年 11 月 25 日)" data-comment="0">前端资源文件缓存清除一法</a></li>
	<li><a href="http://www.zfkun.com/394.html" title="[转]利用跨域资源共享（CORS）实现ajax跨域调用 (2011 年 07 月 15 日)" data-comment="0">[转]利用跨域资源共享（CORS）实现ajax跨域调用</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/109.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSS圆角—透明圆角化背景图片</title>
		<link>http://www.zfkun.com/91.html</link>
		<comments>http://www.zfkun.com/91.html#comments</comments>
		<pubDate>Thu, 21 Jan 2010 03:11:53 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[sprites]]></category>
		<category><![CDATA[圆角]]></category>
		<category><![CDATA[弹性]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=91</guid>
		<description><![CDATA[序言：第一章中我介绍了最基本的纯CSS圆角框的实现原理，并给出Demo，在本章中会对上一个模型作一些新的创新，实现将背景图片透明圆角化。并给出一些漂亮的通用演示效果。
在上面的案例中，我只给出最为原始的圆角框模型，它还是存在一些不足之处。比如不能将图片应用到圆角框内。而在本例中，我会在上面的基础上作出一些创新。就是将背景图片也圆角化。 <a href="http://www.zfkun.com/91.html">阅读全文 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>作者：<a href="http://www.blueidea.com/common/contact.asp?type=作者&amp;username=by0001" target="_blank">by0001</a>　来自：<a href="http://www.blueidea.com/">蓝色理想</a><br />
原文：<a href="http://www.blueidea.com/tech/web/2010/7353.asp">http://www.blueidea.com/tech/web/2010/7353.asp</a></p>
<p>序言：第一章中我介绍了最基本的纯CSS圆角框的实现原理，并给出Demo，在本章中会对上一个模型作一些新的创新，实现将背景图片透明圆角化。并给出一些漂亮的通用演示效果。</p>
<p>在上面的案例中，我只给出最为原始的圆角框模型，它还是存在一些不足之处。比如不能将图片应用到圆角框内。而在本例中，我会在上面的基础上作出一些创新。就是将背景图片也圆角化，好像目前在网络上还没有这样的功能应用，我只见过用js方式来实现的，可以参看我的《<a href="http://www.blueidea.com/tech/web/2009/6488.asp" target="_blank">超圆滑圆角框的半完美解决方案</a>》一文中后面几种JS方案。但是纯CSS方式的实现可是我独家所创，如有雷同，只能说英雄所见略同。呵呵！</p>
<p>还是先看看最终的效果图，让大家有一个大概的印象。</p>
<p style="text-align: center;"><img class="aligncenter" src="http://www.blueidea.com/articleimg/2010/01/7353/01.jpg" border="0" alt="" width="510" height="533" /></p>
<p style="text-align: center;">图一</p>
<p>像这种小面积布局在网页设计中应用得很普遍，但目前网络流行的作法都是采用图片的方式来实现的，将图片按上中下切成三块内容，然后使用三个同级的DIV或SPAN容器各自填充一张图，但是这种方法有一个最大的毛病：不能自动适应宽度的变化，一般做法都是采用固定宽度的方式，这是由于图片的宽度决定的。</p>
<p>当然对于一些比较有经验的人员来说，可以采用九宫格布局（可参看我的另一篇文章《<a href="http://www.blueidea.com/tech/web/2009/6800.asp" target="_blank">九宫格基本布局</a>》）方式或者滑动门方式来做到自适应宽度的变化，九宫格一般都需要用到八张图片，而滑动门虽然只用一张图片，但为了适应宽度的变化，这张图片一般都做得很大。<br />
而我现在独创的这种方法可以完全做到适应不同宽度的需要，并且全部兼容所有的浏览器，而所需要的仅仅是一张很小的水平平辅的背景图片而已。</p>
<p><strong>基本原理</strong>：</p>
<p style="text-align: center;">我们都知道图片是方方正正的，不可能做出圆角效果，那么我们如何来做外圆透明的图片呢？其实道理说明了也就是一件很简单的事情，你看过下面的放大示意图后可能就会“哦”地一声，原来不过如此……<br />
<img class="aligncenter" src="http://www.blueidea.com/articleimg/2010/01/7353/02.jpg" border="0" alt="" width="464" height="388" /></p>
<p style="text-align: center;">图二</p>
<p>是的，看到这个效果图你会一目了然，可是要想到这个方法，我却浪费了不少脑细胞。呵呵！</p>
<p>实现这种方法原理很简单：<strong>在每个b标签中各加载一次同样的图片，并结合背景定位background-position方式来达到效果。</strong>我们知道，同一张图片加载多少次对于性能的影响并不大，因为这张图片已经被电脑缓存到本地，和用css sprites合并图片一样的道理。</p>
<p>但是需要注意的是：每个B标签加载图片的定位是不一样的。</p>
<p><strong>背景图片定位原理</strong>：　　</p>
<p>b1标签位于第一位，它主要用来描绘上边框线，所以它不需要加载背景图片。</p>
<p>b2标签位于第二位，它是第一个需要加载背景图片的，但是不需要图片负偏移，所以直接居左居顶定位就可以了。</p>
<pre name="code" class="css">
.b2{background-position:left top;}
</pre>
<p>b3标签位于第三位，它需要加载背景图片，让它的背景图片向上负偏移b2的高度值就可以，也就是1px。</p>
<pre name="code" class="css">
.b3{background-position:left -1px;}
</pre>
<p>b4位于第四位，所以它向上负偏移b2+b3高度值的和，为2px.。</p>
<pre name="code" class="css">
.b4{background-position:left -2px;}
</pre>
<p>H3标签位于第五位，所以它的背景图片需要向上负偏移b2+b3+b4高度值的各，也就是4px；</p>
<pre name="code" class="css">
h3{background-position:left -4px;}
</pre>
<p>这样，b2、b3、b4、h3的图片叠加起来和原始图片上下渐变的效果完全重合，如同一张图片，这样就达到模拟圆角图片的效果。<br />
怎么样，原理够简单明了吧！</p>
<p>原理清楚后，要实现起来也就是一件水到渠成的事！</p>
<p><strong>HTML结构层</strong>：</p>
<p>如同我们在第一章中模型所见，保持结构不变。</p>
<p><strong>CSS样式层：（只写关键代码）</strong></p>
<p>将上面的几句代码进行合并，如下所示：</p>
<pre name="code" class="css">
.sharp b.b2{background-position:left top;}
.sharp b.b3{background-position:left -1px;}
.sharp b.b4{background-position:left -2px;}
.sharp .content h3{background-position:left -4px;}
</pre>
<p>和第一章中同样的道理，我们肯定要在各个不同的块框中有不同的背景图片的变化，也就是说，我们也要实现不同的换肤方案，当一个页面要多次调用同一个圆角框时，也可以让它们有些丰富的变化。实现不同的风格。OK，没问题，你只需要简单的将下面的样式中的背景图片的路径改变一下就可以了。</p>
<pre name="code" class="css">
.color1 .b2,.color1 .b3,.color1 .b4,.color1 h3{background:url(images/bg1.gif) repeat-x;}
</pre>
<p>你可以实现不同的颜色方案，就看你的设计师给你多少张不同图片了。</p>
<p>一种风格的定制也是一件简单的事情：</p>
<pre name="code" class="css">
*颜色方案一,绿色风格----------------------------------------*/
/*边框色*/
.color1 .b2,.color1 .b3,.color1 .b4,.color1 .b5,.color1 .b6,
.color1 .b7,.color1 .content{border-color:#A0C044;}
.color1 .b1,.color1 .b8{background:#A0C044;}
.color1 h3{border-bottom:1px #679800 solid;}
/*图片路径*/
.color1 .b2,.color1 .b3,.color1 .b4,.color1 h3{background:url(images/bg1.gif) repeat-x;}
/*文字内容背景色*/
.color1 .b5,.color1 .b6,.color1 .b7{background:#FFF;}
</pre>
<p>你只需要复制上面的代码，简单修改一下边框色，背景色，图片路径就变成你想要的风格了，是不是很简单呢？然后在你想应用样式的容器上定义这个color1类名即可。</p>
<p>在我的演示模型中，我定义了9种风格的变化，看看有没有适合你需要，直接复制就可以使用了，祝您用得开心！</p>
<p><strong>为了演示效果，本模型的宽度值全部采用百分比实现的，你可以随意伸缩宽度，看看它能否适应弹性的变化。</strong></p>
<p><strong>本模型在以下浏览器中完美通过：<br />
IE5.5、IE6、IE7、IE8、FF3、TT、Maxthon2.1.5、Opera9.6、Safari4.0、Chrome2.0。</strong></p>
<p><a class="aligncenter" href="http://www.zfkun.com/soft/CSS_RoundAngle_2.rar" target="_blank">压缩包下载</a></p>

	标签：<a href="http://www.zfkun.com/tag/css" title="css" rel="tag">css</a>, <a href="http://www.zfkun.com/tag/sprites" title="sprites" rel="tag">sprites</a>, <a href="http://www.zfkun.com/tag/%e5%9c%86%e8%a7%92" title="圆角" rel="tag">圆角</a>, <a href="http://www.zfkun.com/tag/%e5%bc%b9%e6%80%a7" title="弹性" rel="tag">弹性</a><br />

	<h4>相关推荐</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.zfkun.com/87.html" title="CSS圆角—基本圆角框 (2010 年 01 月 21 日)" data-comment="0">CSS圆角—基本圆角框</a></li>
	<li><a href="http://www.zfkun.com/275.html" title="[转]IE6、IE7、IE8 CSS Bug兼容解决记录 (2011 年 06 月 14 日)" data-comment="1">[转]IE6、IE7、IE8 CSS Bug兼容解决记录</a></li>
	<li><a href="http://www.zfkun.com/142.html" title="IE6+和FF的CSS Hack (2010 年 04 月 23 日)" data-comment="0">IE6+和FF的CSS Hack</a></li>
	<li><a href="http://www.zfkun.com/131.html" title="5 个简单实用的 CSS 属性 (2010 年 03 月 09 日)" data-comment="0">5 个简单实用的 CSS 属性</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/91.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

