<?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>Plane Art</title>
	<atom:link href="http://www.planeart.cn/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.planeart.cn</link>
	<description>专注平面艺术与web易用性的融合</description>
	<lastBuildDate>Sun, 05 Sep 2010 08:02:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>jQuery live 事件绑定性能测试</title>
		<link>http://www.planeart.cn/?p=835</link>
		<comments>http://www.planeart.cn/?p=835#comments</comments>
		<pubDate>Tue, 24 Aug 2010 04:04:24 +0000</pubDate>
		<dc:creator>唐 斌</dc:creator>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[live，内存]]></category>

		<guid isPermaLink="false">http://www.planeart.cn/?p=835</guid>
		<description><![CDATA[昨天和我们可爱的后端架构师在争论这个问题，我很多UI组件中大量使用了jQuery live进行事件绑定，众所周知它最直观的好处在于可以一直“监听”我们操作，对于新增的DOM节点也会有效，而不需要重新绑定。也许是因为这个“监听”让我们很多人联想到他会不断的去绑定、判断，会造成性能问题，这也是他给我的意见，真的是这样吗？ 在我开始认识live之前，我也看过网上很多文章说live会降低性能，昨天架构师也给我这么一篇：《jQuery性能优化指南》，此文说到live上完全就是避重就轻，原因都还没谈直接给出定结论——“虽然我把绑定事件重新写了一次，代码多了点，但这种方式的效率明显高于live()方式，特别是在频繁的DOM操作中，这点非常明显。”，鄙视之。 在此之前，我认为我这篇文章是毫无意义的，因为live是类似于绑定父节点，去监听子节点产生的冒泡才去执行相应的事件，这种代理的好处几乎已经得到js编程哥公认了。可是前端面对环境的问题往往要比后端复杂，这也是前端经常需要与人分享的原因，通过前端工程师不断的积累让很多浏览器的问题明朗起来，让彼此避免陷入泥潭中。理论上的争执永远比不过一个实测来得直观。下面是我对live与普通绑定的内存占用测试： 环境：IE8。 工具：sIEve。 jQuery:1.42 普通方式： jQuery(function($){ var li = '&#60;li&#62;&#60;a href=&#34;#&#34;&#62;test&#60;/a&#62;&#60;/li&#62;', newLi = li; for (i = 0; i &#60; 6000; i++) { newLi += li; }; $('#test').html(newLi); $('#test a').click(function(){ alert(0); return false; }); }); 测试结果：绑定前 20880KB &#124; 绑定后 64932KB &#124; 执行事件后 64980KB live 代理方式： jQuery(function($){ var li = '&#60;li&#62;&#60;a href=&#34;#&#34;&#62;test&#60;/a&#62;&#60;/li&#62;', newLi [...]]]></description>
			<content:encoded><![CDATA[<p>昨天和我们可爱的后端架构师在争论这个问题，我很多UI组件中大量使用了jQuery live进行事件绑定，众所周知它最直观的好处在于可以一直“监听”我们操作，对于新增的DOM节点也会有效，而不需要重新绑定。也许是因为这个“监听”让我们很多人联想到他会不断的去绑定、判断，会造成性能问题，这也是他给我的意见，真的是这样吗？</p>
<p>在我开始认识live之前，我也看过网上很多文章说live会降低性能，昨天架构师也给我这么一篇：<a href="http://www.w2blog.net/view/467.html">《jQuery性能优化指南》</a>，此文说到live上完全就是避重就轻，原因都还没谈直接给出定结论——“<del datetime="2010-08-25T06:12:01+00:00">虽然我把绑定事件重新写了一次，代码多了点，但这种方式的效率明显高于live()方式，特别是在频繁的DOM操作中，这点非常明显</del>。”，鄙视之。</p>
<p>在此之前，我认为我这篇文章是毫无意义的，因为live是类似于绑定父节点，去监听子节点产生的冒泡才去执行相应的事件，这种代理的好处几乎已经得到js编程哥公认了。可是前端面对环境的问题往往要比后端复杂，这也是前端经常需要与人分享的原因，通过前端工程师不断的积累让很多浏览器的问题明朗起来，让彼此避免陷入泥潭中。理论上的争执永远比不过一个实测来得直观。下面是我对live与普通绑定的内存占用测试：</p>
<p>环境：IE8。 工具：sIEve。 jQuery:1.42<br />
普通方式：</p>
<pre><code class="javascript">jQuery(function($){
	var li = '&lt;li&gt;&lt;a href=&quot;#&quot;&gt;test&lt;/a&gt;&lt;/li&gt;',
	newLi = li;

	for (i = 0; i &lt; 6000; i++) {
  		newLi += li;
	};
	$('#test').html(newLi);
	$('#test a').click(function(){
  		alert(0);
  		return false;
	});
});</code></pre>
<p>测试结果：绑定前 20880KB | 绑定后 64932KB | 执行事件后 64980KB</p>
<p>live 代理方式：</p>
<pre><code>jQuery(function($){
	var li = '&lt;li&gt;&lt;a href=&quot;#&quot;&gt;test&lt;/a&gt;&lt;/li&gt;',
	newLi = li;

	for (i = 0; i &lt; 6000; i++) {
  		newLi += li;
	};
	$('#test').html(newLi);
	$('#test a').live('click', function(){
  		alert(0);
  		return false;
	});
});</code></pre>
<p>测试结果：绑定前 21056KB | 绑定后 20936KB | 执行事件后 20936KB</p>
<p>从结果可以得知在内存消耗方面live几乎完胜（执行效率与这个无关）。总之绑定6000次与绑定1次的区别还是比较大的。</p>
<p>前段时间我也浅浅的阅读了jQuery的源码，也曾经尝试写过自己的微型DOM引擎，因为我认为解决jQuery常用的方法可以控制在8Kb之内，后来在处理事件机制的时候才知道这个是无法“微型”，无法自动处理内存泄漏，所以jQuery源码中有一大片地方是给事件机制的，在1.42源码中竟然达到了1069行！</p>
<p>了解jQuery应该从他实现的原理开始，也可以自己尝试写DOM操作引擎，看别人造轮子与自己造轮子都会让一切将明朗起来！</p>
<p>事件代理机制扩展阅读：<a href="http://bbs.51js.com/viewthread.php?tid=87369&#038;page=1&#038;fromuid=81151#pid607391">http://bbs.51js.com/viewthread.php?tid=87369&#038;page=1&#038;fromuid=81151#pid607391</a></p>
<p>原创文章，原始地址： http://www.planeart.cn/?p=835</p>
]]></content:encoded>
			<wfw:commentRss>http://www.planeart.cn/?feed=rss2&amp;p=835</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>artDialog v3预览版 2010.08.29 更新</title>
		<link>http://www.planeart.cn/?p=828</link>
		<comments>http://www.planeart.cn/?p=828#comments</comments>
		<pubDate>Mon, 23 Aug 2010 07:40:42 +0000</pubDate>
		<dc:creator>唐 斌</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.planeart.cn/?p=828</guid>
		<description><![CDATA[最近上网不太方便，现在在一个咖啡厅匆匆忙忙的上传了预览版。一直在断断续续的写第三版，由于实在精力有限，我没有对IE6、IE7做深入的测试，只用IEtester反复测试了几遍，由于不可避免未知BUG，我希望大家帮我测试下，完善后正式发布。 感谢您的参与！ 2010-08-29 更新 修复升级后几个皮肤文件IE6兼容问题 动画引擎测试 2010-08-27 更新 修复iframe给IE6、7带来的input不能输入的问题，感谢newlux的帮助。 iframe在父元素被移除的时候仍然会在ie6\7占用“内存”，虽然底层remove()方法为了防止IE内存泄漏移除元素前把子元素都删除并且null了，但是仍然没能解决iframe带来的问题。经过实测只需要在关闭前把iframe地址重置即可，现在已经通过IEtester测试。 2010.08.25 更新 1、再次提升IE下性能，优化核心样式，对老版本浏览器体验进行降级处理，减少内存占用。以前使用的滤镜每次调用几乎都会要耗费IE 4MB的内存，且无法销毁元素后收回，这也是很多使用滤镜效果javascript组件的通病。为了解决这个问题IE6的锁屏遮罩我使用网格gif图片模拟，IE6+使用png图片，其他浏览器则使用CSS3半透明，现在每次调用一个对话框几乎都不会造成内存占用了:-) 2、修复IE6静止定位+拖动时候导致input无法输入的问题 关于artDialog支持IE6，它是用了一个特殊的方法让其支持定位fixed属性，在效果上貌似已经是最好的解决方案了，拖动滚动条也能完美静止。本以为是一个完美的方案，但是在测试iframe bug的时候发现了它的瓶颈，它会触发IE另外一个问题，静止定位下方的对话框在关闭之前不能输入文字，非得为IE6换成常规方案？。。。 在线演示 源代码：artDialog3beta4.zip（里面提供的min版本不是最新的，如需要请自己去压缩）]]></description>
			<content:encoded><![CDATA[<p>最近上网不太方便，现在在一个咖啡厅匆匆忙忙的上传了预览版。一直在断断续续的写第三版，由于实在精力有限，我没有对IE6、IE7做深入的测试，只用IEtester反复测试了几遍，由于不可避免未知BUG，我希望大家帮我测试下，完善后正式发布。</p>
<p>感谢您的参与！</p>
<p><strong>2010-08-29 更新</strong></p>
<p>修复升级后几个皮肤文件IE6兼容问题</p>
<p><a href="http://www.planeart.cn/demo/artDialog/effectTest.html">动画引擎测试</a></p>
<p><strong>2010-08-27 更新</strong></p>
<p>修复iframe给IE6、7带来的input不能输入的问题，感谢newlux的帮助。</p>
<p>iframe在父元素被移除的时候仍然会在ie6\7占用“内存”，虽然底层remove()方法为了防止IE内存泄漏移除元素前把子元素都删除并且null了，但是仍然没能解决iframe带来的问题。经过实测只需要在关闭前<strong>把iframe地址重置即可</strong>，现在已经通过IEtester测试。</p>
<p><strong>2010.08.25 更新</strong></p>
<p>1、再次提升IE下性能，优化核心样式，对老版本浏览器体验进行降级处理，减少内存占用。以前使用的滤镜每次调用几乎都会要耗费IE 4MB的内存，且无法销毁元素后收回，这也是很多使用滤镜效果javascript组件的通病。为了解决这个问题IE6的锁屏遮罩我使用网格gif图片模拟，IE6+使用png图片，其他浏览器则使用CSS3半透明，现在每次调用一个对话框几乎都不会造成内存占用了:-)</p>
<p>2、修复IE6静止定位+拖动时候导致input无法输入的问题</p>
<p>关于artDialog支持IE6，它是用了一个特殊的方法让其支持定位fixed属性，在效果上貌似已经是最好的解决方案了，拖动滚动条也能完美静止。本以为是一个完美的方案，但是在测试iframe bug的时候发现了它的瓶颈，它会触发IE另外一个问题，静止定位下方的对话框在关闭之前不能输入文字，非得为IE6换成常规方案？。。。</p>
<p><a href="http://www.planeart.cn/demo/artDialog/doc.html">在线演示</a></p>
<p><a href="http://www.planeart.cn/demo/artDialog/artDialog3beta4.zip">源代码：artDialog3beta4.zip</a>（里面提供的min版本不是最新的，如需要请自己去压缩）</p>
]]></content:encoded>
			<wfw:commentRss>http://www.planeart.cn/?feed=rss2&amp;p=828</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>artDialog 第三版预告</title>
		<link>http://www.planeart.cn/?p=821</link>
		<comments>http://www.planeart.cn/?p=821#comments</comments>
		<pubDate>Sat, 14 Aug 2010 05:34:44 +0000</pubDate>
		<dc:creator>唐 斌</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.planeart.cn/?p=821</guid>
		<description><![CDATA[v2发布已经有一段时间了，通过网友的BUG反馈已经发现有两处无法容忍的的BUG： 1、IE6下锁屏开启锁屏遮罩，如果对话框中有下拉控件将会被隐藏。 2、iframe模式关闭后可能会在IE6、7父页面的输入控件失效 现在这段时间我非常的忙，一时间无法更新v2版本，如果你项目中喜欢用iframe参数创建消息，建议换成content参数，并且关闭lock功能。现在正在开发的V3版已经完成80%，从v1开始每一个主版本号更新就预示着代码结构大幅度的优化，当然最重要的还是要解决老版本遗留的问题。 现在网友们询问的问题大部分是关于iframe 下js获取对象的基础javascript问题，还有就是对话框本身在iframe应用范围的BUG，在v3中我会让让iframe操作更加简便，同时也会写一个更好的API文档，尽量照顾更多的人。 v3版的主要更新： 1、代码结构优化，方便二次开发：内建微型DOM操作引擎，底层与业务层分开；引入模板引擎，让对话框HTML结构更加清晰；公开了默认配置接口 2、增加插件机制：插件可以扩展content,如iframe、ajax、img的预先加载，也利用artDialog核心扩展相册、弹出菜单等UI组件等 3、增强UI机制：支持多皮肤同时共存，并且可以让皮肤在页面载入时候就被缓存好；内建微型动画引擎，支持动画 4、提供更多的内部控制接口 5、大幅度提高性能(IE) 最后，它仍然保持一个小巧的身材。]]></description>
			<content:encoded><![CDATA[<p>v2发布已经有一段时间了，通过网友的BUG反馈已经发现有两处无法容忍的的BUG：</p>
<p>1、IE6下锁屏开启锁屏遮罩，如果对话框中有下拉控件将会被隐藏。</p>
<p>2、iframe模式关闭后可能会在IE6、7父页面的输入控件失效</p>
<p>现在这段时间我非常的忙，一时间无法更新v2版本，如果你项目中喜欢用iframe参数创建消息，建议换成content参数，并且关闭lock功能。现在正在开发的V3版已经完成80%，从v1开始每一个主版本号更新就预示着代码结构大幅度的优化，当然最重要的还是要解决老版本遗留的问题。</p>
<p>现在网友们询问的问题大部分是关于iframe 下js获取对象的基础javascript问题，还有就是对话框本身在iframe应用范围的BUG，在v3中我会让让iframe操作更加简便，同时也会写一个更好的API文档，尽量照顾更多的人。</p>
<p>v3版的主要更新：<br />
1、代码结构优化，方便二次开发：内建微型DOM操作引擎，底层与业务层分开；引入模板引擎，让对话框HTML结构更加清晰；公开了默认配置接口<br />
2、增加插件机制：插件可以扩展content,如iframe、ajax、img的预先加载，也利用artDialog核心扩展相册、弹出菜单等UI组件等<br />
3、增强UI机制：支持多皮肤同时共存，并且可以让皮肤在页面载入时候就被缓存好；内建微型动画引擎，支持动画<br />
4、提供更多的内部控制接口<br />
<strong>5、大幅度提高性能(IE)</strong></p>
<p>最后，它仍然保持一个小巧的身材。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.planeart.cn/?feed=rss2&amp;p=821</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>轻量级输入字数提示jQuery插件 &#8211; artTxtCount</title>
		<link>http://www.planeart.cn/?p=806</link>
		<comments>http://www.planeart.cn/?p=806#comments</comments>
		<pubDate>Thu, 10 Jun 2010 16:09:24 +0000</pubDate>
		<dc:creator>唐 斌</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[原创作品]]></category>
		<category><![CDATA[artTxtCount]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.planeart.cn/?p=806</guid>
		<description><![CDATA[artTxtCount是一个基于jQuery的简单输入字符统计与限制的插件，可以实现类似twitter、新浪微博、腾讯微博等字符统计的效果。 虽然网上已经有好几个同类型的插件了，但是封装过度，实际应用中总是有那么一丝牵绊，因为它们不能指定提示消息的容器。其实我们只需要一个简单的效果就可以了： 预览：http://www.planeart.cn/downs/artTxtCount/ /* tangbin - http://www.planeArt.cn - MIT Licensed */ (function($){ // tipWrap: 提示消息的容器 // maxNumber: 最大输入字符 $.fn.artTxtCount = function(tipWrap, maxNumber){ var countClass = 'js_txtCount', // 定义内部容器的CSS类名 fullClass = 'js_txtFull', // 定义超出字符的CSS类名 disabledClass = 'disabled'; // 定义不可用提交按钮CSS类名 // 统计字数 var count = function(){ var btn = $(this).closest('form').find(':submit'), val = $(this).val().length, // 是否禁用提交按钮 disabled = [...]]]></description>
			<content:encoded><![CDATA[<p>artTxtCount是一个基于jQuery的简单输入字符统计与限制的插件，可以实现类似twitter、新浪微博、腾讯微博等字符统计的效果。</p>
<p>虽然网上已经有好几个同类型的插件了，但是封装过度，实际应用中总是有那么一丝牵绊，因为它们不能指定提示消息的容器。其实我们只需要一个简单的效果就可以了：</p>
<p>预览：<a target="_blank" href="http://www.planeart.cn/downs/artTxtCount/">http://www.planeart.cn/downs/artTxtCount/</a><br />
<span id="more-806"></span></p>
<pre><code class="javascript">
/* tangbin - http://www.planeArt.cn - MIT Licensed */
(function($){
	// tipWrap: 	提示消息的容器
	// maxNumber: 	最大输入字符
	$.fn.artTxtCount = function(tipWrap, maxNumber){
		var countClass = 'js_txtCount',		// 定义内部容器的CSS类名
			fullClass = 'js_txtFull',		// 定义超出字符的CSS类名
			disabledClass = 'disabled';		// 定义不可用提交按钮CSS类名

		// 统计字数
		var count = function(){
			var btn = $(this).closest('form').find(':submit'),
				val = $(this).val().length,

				// 是否禁用提交按钮
				disabled = {
					on: function(){
						btn.removeAttr('disabled').removeClass(disabledClass);
					},
					off: function(){
						btn.attr('disabled', 'disabled').addClass(disabledClass);
					}
				};

			if (val == 0) disabled.off();
			if(val <= maxNumber){
				if (val > 0) disabled.on();
				tipWrap.html('<span class="' + countClass + '">\u8FD8\u80FD\u8F93\u5165 <strong>' + (maxNumber - val) + '</strong> \u4E2A\u5B57</span>');
			}else{
				disabled.off();
				tipWrap.html('<span class="' + countClass + ' ' + fullClass + '">\u5DF2\u7ECF\u8D85\u51FA <strong>' + (val - maxNumber) + '</strong> \u4E2A\u5B57</span>');
			};
		};
		$(this).bind('keyup change', count);

		return this;
	};
})(jQuery);
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.planeart.cn/?feed=rss2&amp;p=806</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>简易的全屏透明遮罩(lightBox)解决方案</title>
		<link>http://www.planeart.cn/?p=792</link>
		<comments>http://www.planeart.cn/?p=792#comments</comments>
		<pubDate>Fri, 28 May 2010 19:17:22 +0000</pubDate>
		<dc:creator>唐 斌</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[网页设计]]></category>
		<category><![CDATA[lightBox]]></category>

		<guid isPermaLink="false">http://www.planeart.cn/?p=792</guid>
		<description><![CDATA[前不久有个正要毕业的网友给我发邮件，他毕业设计需要实现锁屏的效果，他问能不能把之前我写的对话框组件的锁屏代码原理说明下，我当时说过两天就发。由于最近比较忙，我现在才想起来，但愿现在此文还来得及。 步入正题： 现在全屏的半透明遮罩层在web2.0网站应用非常广泛了，绝大多数遮罩是通过计算页面大小，然后覆盖一个与页面同等大小的层实现，如腾讯qzone, wordpress后台。这种方式本来无可非议，但是在页面很长的时候在IE8下会失效（国外资料的解释是与机器显卡相关），有些完美情节的同学遇到这个问题后就抓破了头，无奈之下甚至想让IE8强制使用IE7的方式解析他的作品。其实我们有一个更好的方法，咱们用CSS去解决它！ 还记得“position:fixed”吗？它是css2的一个新增的属性，他可以让一个元素静止在页面上，拖动滚动条也不会动，如Qzone顶部固定的导航栏就是这样实现的。同样我们也可以用一个100%高宽的层覆盖浏览器视口，这样就可以实现全屏遮罩了。不用再计算页面的大小，调整浏览器大小的时候也不要去动态修改尺寸了。 查看示例一 可是有一个头疼的问题，IE6不支持“position:fixed”，咱们只能通过js动态的修改它的TOP值以模拟静止定位，拖动滚动条的时候遮罩成肯定会抖动，因为每改变一次IE会重新渲染一次。但是微软却给我们提供了一个非常有趣的特性，如果给html或者body标签设置一个静止定位的背景图片，层在拖动滚动条的时候就不会抖动了，几乎完美的模拟了“position:fixed”。我在实际项目中发现这个特性他还能触发其他的特异功能，以后再说明。 为了省事，咱们针对IE6用万恶expression在CSS中写点脚本，拖动滚动条的时候重新定位我们的遮罩层。传说中expression是非常耗性能的，可是咱们的expression几乎没有损耗，有兴趣的同学可以深入研究下expression。 查看示例二 好了，兼容IE6这个大头娃娃后，咱们的锁屏遮罩已经通杀主流浏览器了，但是呢用js写效果的同学们总是非常的蛋疼，总想折腾点什么来，咱们就再添加一点脚本，让锁屏的时候后可以中断用户操作，把滚动条、滚轮、tab键、全选、刷新、右键统统禁止掉，模拟真正的‘锁屏’： 查看示例三]]></description>
			<content:encoded><![CDATA[<p>前不久有个正要毕业的网友给我发邮件，他毕业设计需要实现锁屏的效果，他问能不能把之前我写的对话框组件的锁屏代码原理说明下，我当时说过两天就发。由于最近比较忙，我现在才想起来，但愿现在此文还来得及。</p>
<p>步入正题：</p>
<p>现在全屏的半透明遮罩层在web2.0网站应用非常广泛了，绝大多数遮罩是通过计算页面大小，然后覆盖一个与页面同等大小的层实现，如腾讯qzone, wordpress后台。这种方式本来无可非议，但是在页面很长的时候在IE8下会失效（国外资料的解释是与机器显卡相关），有些完美情节的同学遇到这个问题后就抓破了头，无奈之下甚至想让IE8强制使用IE7的方式解析他的作品。其实我们有一个更好的方法，咱们用CSS去解决它！</p>
<p>还记得“position:fixed”吗？它是css2的一个新增的属性，他可以让一个元素静止在页面上，拖动滚动条也不会动，如Qzone顶部固定的导航栏就是这样实现的。同样我们也可以用一个100%高宽的层覆盖浏览器视口，这样就可以实现全屏遮罩了。不用再计算页面的大小，调整浏览器大小的时候也不要去动态修改尺寸了。</p>
<p><a href="http://www.planeart.cn/blog/wp-content/uploads/2010/05/lock1.html" target="_blank"><strong>查看示例一</strong></a></p>
<p>可是有一个头疼的问题，IE6不支持“position:fixed”，咱们只能通过js动态的修改它的TOP值以模拟静止定位，拖动滚动条的时候遮罩成肯定会抖动，因为每改变一次IE会重新渲染一次。但是微软却给我们提供了一个非常有趣的特性，如果给html或者body标签设置一个静止定位的背景图片，层在拖动滚动条的时候就不会抖动了，几乎完美的模拟了“position:fixed”。我在实际项目中发现这个特性他还能触发其他的特异功能，以后再说明。</p>
<p>为了省事，咱们针对IE6用万恶expression在CSS中写点脚本，拖动滚动条的时候重新定位我们的遮罩层。传说中expression是非常耗性能的，可是咱们的expression几乎没有损耗，有兴趣的同学可以深入研究下expression。</p>
<p><a href="http://www.planeart.cn/blog/wp-content/uploads/2010/05/lock2.html" target="_blank"><strong>查看示例二</strong></a></p>
<p>好了，兼容IE6这个大头娃娃后，咱们的锁屏遮罩已经通杀主流浏览器了，但是呢用js写效果的同学们总是非常的蛋疼，总想折腾点什么来，咱们就再添加一点脚本，让锁屏的时候后可以中断用户操作，把滚动条、滚轮、tab键、全选、刷新、右键统统禁止掉，模拟真正的‘锁屏’：</p>
<p><a href="http://www.planeart.cn/blog/wp-content/uploads/2010/05/lock3.html" target="_blank"><strong>查看示例三</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.planeart.cn/?feed=rss2&amp;p=792</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>密码保护：《javascript 语言精粹》精华部分</title>
		<link>http://www.planeart.cn/?p=769</link>
		<comments>http://www.planeart.cn/?p=769#comments</comments>
		<pubDate>Fri, 07 May 2010 12:07:45 +0000</pubDate>
		<dc:creator>唐 斌</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.planeart.cn/?p=769</guid>
		<description><![CDATA[无法提供摘要。这是一篇受保护的文章。]]></description>
			<content:encoded><![CDATA[<form action="http://www.planeart.cn/blog/wp-pass.php" method="post">
<p>这是一篇受密码保护的文章。您需要提供访问密码：</p>
<p><label for="pwbox-769">密码：<br />
<input name="post_password" id="pwbox-769" type="password" size="20" /></label><br />
<input type="submit" name="Submit" value="提交" /></p></form>
]]></content:encoded>
			<wfw:commentRss>http://www.planeart.cn/?feed=rss2&amp;p=769</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>发布:javascript对话框组件artDialog v2</title>
		<link>http://www.planeart.cn/?p=713</link>
		<comments>http://www.planeart.cn/?p=713#comments</comments>
		<pubDate>Sat, 03 Apr 2010 17:45:06 +0000</pubDate>
		<dc:creator>唐 斌</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[原创作品]]></category>
		<category><![CDATA[对话框]]></category>
		<category><![CDATA[弹出层]]></category>

		<guid isPermaLink="false">http://www.planeart.cn/?p=713</guid>
		<description><![CDATA[artDialog是一个轻巧且高度兼容的javascript对话框组件，可让你的网页交互拥有桌面软件般的用户体验。 演示地址:artDialog猛击前往 项目主页:http://code.google.com/p/artdialog/ artDialog2采用全新的UI 功能： 支持锁定屏幕(遮罩)、模拟alert和confirm、多窗口弹出、静止定位、支持Ese键关闭对话框、定时关闭、自定义位置、拖动、鼠标调节窗口大小、换肤…… 优点 兼容主流浏览器: 支持IE6和IE6+, Firefox, chrome, Opera, Safari 自适应内容: 无需预设高宽, 对话框自适应消息内容的大小 (包括按钮)，并且支持消息框大小拖动调节 智能消息对齐: 如果设置了对话框宽度，文本会自动居中或者居左对齐 容错: 如果定义的宽度高度小于内容大小不会出现错位, 智能定位: 使用自定义坐标的时候智能修正位置，确保其在可视范围 (适用于弹出菜单) 拖动流畅: 不会粘住鼠标也不会拖出浏览器视口导致无法控制 轻巧: js压缩后不到8KB (在js内嵌了核心兼容布局CSS的情况下) 制订皮肤: 九宫格布局, 钩子完善,制作皮肤相当简易, 内置IE6 png 32透明和定位解决方案。 IE6无抖动静止定位: 在IE6下可实现与现代浏览器一样完美静止定位效果 IE6遮盖下拉控件支持: 支持 IE6 下覆盖下拉控件 (注:半透明皮肤不支持) jQuery(function(){ artDialog({content:'欢迎使用 "artDialog" 对话框组件！', fixed:true, lock:false,style:'succeed'}, function(){artDialog({title:' ', content:'谢谢观赏,爱她就要拥有她！', lock:true})}); }); artDialog 兼容布局设计思路 [...]]]></description>
			<content:encoded><![CDATA[<p>artDialog是一个轻巧且高度兼容的javascript对话框组件，可让你的网页交互拥有桌面软件般的用户体验。</p>
<p>演示地址:<a href="/downs/artDialog/"  target="_blank">artDialog猛击前往</a></p>
<p>项目主页:<a href="http://code.google.com/p/artdialog/"  target="_blank">http://code.google.com/p/artdialog/</a></p>
<p>artDialog2采用全新的UI</p>
<div><a href="http://www.planeart.cn/downs/artDialog/"  target="_blank"><img src="blog/wp-content/uploads/2010/04/artDialog2.png" /></a></div>
<p>功能： 支持锁定屏幕(遮罩)、模拟alert和confirm、多窗口弹出、静止定位、支持Ese键关闭对话框、定时关闭、自定义位置、拖动、鼠标调节窗口大小、换肤……</p>
<h3>优点</h3>
<ol class="love">
<li><strong>兼容主流浏览器</strong>: 支持IE6和IE6+, Firefox, chrome, Opera, Safari</li>
<li><strong>自适应内容</strong>: 无需预设高宽, 对话框自适应消息内容的大小 <span class="tips">(包括按钮)</span>，并且支持消息框大小拖动调节</li>
<li><strong>智能消息对齐</strong>: 如果设置了对话框宽度，文本会自动居中或者居左对齐</li>
<li><strong>容错</strong>: 如果定义的宽度高度小于内容大小不会出现错位,</li>
<li><strong>智能定位</strong>: 使用自定义坐标的时候智能修正位置，确保其在可视范围 <span class="tips">(适用于弹出菜单)</span></li>
<li><strong>拖动流畅</strong>: 不会粘住鼠标也不会拖出浏览器视口导致无法控制</li>
<li><strong>轻巧</strong>: js压缩后不到8KB <span class="tips">(在js内嵌了核心兼容布局CSS的情况下)</span></li>
<li><strong>制订皮肤</strong>: 九宫格布局, 钩子完善,制作皮肤相当简易, 内置IE6 png 32透明和定位解决方案。</li>
<li><strong>IE6无抖动静止定位</strong>: 在IE6下可实现与现代浏览器一样完美静止定位效果</li>
<li><strong>IE6遮盖下拉控件支持</strong>: 支持 IE6 下覆盖下拉控件 <span class="tips">(注:半透明皮肤不支持)</span></li>
</ol>
<link id="artDialogSkin" href="http://www.planeart.cn/downs/artDialog/skin/aero/aero.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://www.planeart.cn/downs/artDialog/artDialog.js"></script><br />
  <span id="more-713"></span><br />
<script>
jQuery(function(){
artDialog({content:'欢迎使用 "artDialog" 对话框组件！', fixed:true, lock:false,style:'succeed'}, function(){artDialog({title:' ', content:'谢谢观赏,爱她就要拥有她！', lock:true})});
});
</script></p>
<h3>artDialog 兼容布局设计思路</h3>
<p>还是大学的时候就对对弹出层和lightBox特效的着迷，记得那个时候下载过百度贴吧的弹出层类，支持遮罩与对话框半透明投影。打开分析看到里面布满了CSS教科书上传说、且邪恶的table，于是乎我第一反应就是把里面的结构改了，改成DIV+CSS的，最后压缩成17KB大小，弄完后自然很得意。后来我发现我修改后的对话框经常出现错位等问题，而原作却不会出现。由于当时对XTHML理解不是很透彻，后来也就把这个事儿给忘记了。</p>
<p>现在由于项目需要，我得做交互相关的工作，但是一直没有找到自己满意的对话框类。网上那些对话框功能强大的就设计过度，或者要依赖于第三方框架，总之以我现在的水平是无法完全读懂其代码的，只知道其JS布满了解决浏览器兼容的条件判断，我甚至无法为它制作一个满意的风格。</p>
<p>后来我就自己写了这个对话框组件，在这里我把自己的设计思路说明下：</p>
<p>由于XHML结构是写在js里面的，XHTML完全是用于样式表现，所以我们没有必要听从WEB标准老师的教诲，尽量选择适合表现的XHTML标签。显然table（表格）的特性用于此是再好不过了：超强容错能力、高度宽度自适应内容、带有布局，浏览器对其理解得很透彻（尤其是IE）。这也说明了开头我说的百度的对话框不会错位的特性。</p>
<p>下面就是artDialog的XHTML结构图:</p>
<div><a href="http://www.planeart.cn/blog/wp-content/uploads/2010/04/artDialog-XHTML兼容结构图.png"><img src="http://www.planeart.cn/blog/wp-content/uploads/2010/04/artDialog-XHTML兼容结构图-150x150.png" alt="" title="artDialog-XHTML兼容结构图" width="150" height="150" class="alignnone size-thumbnail wp-image-819" /></a></div>
<p>对话框从div.ui_dialog_wrap开始，里面分别套用了两个table，最外层的table是九宫格布局，用来支持圆角皮肤的，里面的table.ui_dialog_main是装载消息内容的（包括标题、内容、按钮），其中js设置的高度与宽度就应用在table.ui_dialog_main里面的一个td（单元格）上面，这样外层的table就会随着table.ui_dialog_main变化而自动伸展。由于表格的特性，内容如果超出td的高度宽度，td会自动调整大小的，所以不用担消息内容被截取了。</p>
<p>artDialog支持多窗口弹出，每一个div.ui_dialog_wrap里面都带有一个用于遮罩的div.ui_overlay，而实际的遮罩层却是里面的div，我们可以在css里面设置div的颜色与透明度，外层的div.ui_overlay用于js执行透明渐变。div.ui_overlay弹出的时候高度与高度都设置为100%并且使用绝对定位，div.ui_dialog_wrap则使用了静止定位‘position: fixed’，也就是说遮罩只覆盖浏览器视口，没有像网上同类的对话框组件覆盖了整个页面（有人说页面过高会导致ie8透明滤镜失效）。IE6不支持&#8217;position: fixed&#8217;属性，下面给出CSS解决方案：</p>
<blockquote><p>width: 100%; height: 100%; position: absolute; left: expression(documentElement.scrollLeft + documentElement.clientWidth &#8211; this.offsetWidth); top: expression(documentElement.scrollTop + documentElement.clientHeight &#8211; this.offsetHeight); </p></blockquote>
<p>可以看到CSS应用了微软专属的HTA技术，div.ui_dialog_wrap 在IE6应用的是绝对定位，left与top由HTA动态改变。虽然网上很多文章说HTA不要使用，会严重消耗性能，但是我认为这个说法并不是绝对的，我在在IE6测试artDialog静止定位拖动滚动条消耗的性能几乎为零（但是在其他HTA应用确实比较消耗资源），况且静止定位只是一个表现形式而已，不是很重要。无论是css嵌入js与原生的js改变top与left同样会让div.ui_dialog_wrap抖动，因为每一次改变ie6都重新渲染一次，但是ie6却有一个有意思的特性，如果在body或者html设置一个静止定位的背景，div.ui_dialog_wrap就不会闪动了，完全模拟‘position: fixed’！考虑html标签很少用来做背景，我们可以这样写：</p>
<blockquote><p>background:url(*) fixed</p></blockquote>
<p>如果父元素拥有了定位属性，那子元素的top与left绝对定位也就相对于父元素，所以ie6 此时div.ui_dialog_wrap下的对话框——div.ui_dialog也就静止了。</p>
<p>IE6还有一个臭名昭著的bug：你如论设置多大的z-index都没有办法把select（下拉控件）无法遮盖，网上资料显示其权限比较高，同时也提到了iframe（嵌入式窗口）比select更高（iframe可以遮盖），只要在层下面放一个与其同等大小的z-index=-1的iframe就可以覆盖select了，所以我在div.ui_dialog放了一个巨大的的iframe，并且给div.ui_dialog设置了&#8217;overflow:hidden&#8217;，省得js又为了这一点点小事情去搞实地测量。当然我最后这个功能因为应用ie6的透明皮肤而妥协了（默认皮肤的css就隐藏了这个iframe），ie6应用了Png透明修复后下面却由这个iframe挡着，所谓鱼和熊掌不可兼得，要美丽就得付出代价，否则你就老实的针对IE6制作png 8位或者gif全透明的皮肤把。</p>
<p>好了，最重要的东西已经解说完毕，更细致的技巧可以查看js和_doc目录中的css文档。如果有更好的兼容方案欢迎提出。如果发现问题或者建议请给我发电子邮件。如果你对代码进行了优化，那也请您不吝给我一份吧，让它变得更好。</p>
<p>下载：<a href="http://code.google.com/p/artdialog/downloads/list">http://code.google.com/p/artdialog/downloads/list</a></p>
<p><strong>artDialog本身并不能获取内容，鉴于近日收到很多兄弟的留言询问此，不太熟悉js的朋友可以下载蓝色理想论坛讨论贴的附件看看</strong><br />
<a href="http://bbs.blueidea.com/viewthread.php?tid=2980170&#038;page=1&#038;extra=page%3D1">http://bbs.blueidea.com/viewthread.php?tid=2980170&#038;page=1&#038;extra=page%3D1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.planeart.cn/?feed=rss2&amp;p=713</wfw:commentRss>
		<slash:comments>153</slash:comments>
		</item>
		<item>
		<title>新浪微博图片放大效果[artZoom.js]</title>
		<link>http://www.planeart.cn/?p=696</link>
		<comments>http://www.planeart.cn/?p=696#comments</comments>
		<pubDate>Mon, 15 Mar 2010 17:49:23 +0000</pubDate>
		<dc:creator>唐 斌</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[原创作品]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.planeart.cn/?p=696</guid>
		<description><![CDATA[(本文示例脚本于2010-05-28更新) 如果说09年是SNS年，那10年肯定微博年，各大网站都推出或者准备推出自己的微博。我这几天都在看新浪微博，对新浪微博的用户体验很欣赏，有些细节我自己也琢磨了下，据我所知其界面是大名鼎鼎的eico设计的，其前端架构很非常不错。 步入正题。 我点击新浪微博缩略图的时候会快速的置换一张大图，并且鼠标会显示放大或者缩小的指针，新浪前端工程师吧视口的大图片都预加载了，所以点击缩略图后替换大图的过程很爽快（PS：大家都知道点击Qzone的缩略图会出现什么）。 这种简约的效果非常适合插在内容区域单幅图片显示，放大后也不会干预用户操作，难怪很多微博客都采用（如：聚友旗下的911微博）。 其中有一个令我很惊讶的功能，图片可以自由旋转，这功能如何实现？ CSS属性？貌似只有IE可以用CSS私有滤镜 javascript？还没有听说过有这个内置方法 服务端处理？极度消耗服务器资源，而且响应会很迟钝 最用用firebug查看才知道是canvas实现的，它是未来的WEB标准的新产物，目前只有IE浏览器不支持它，但IE有个私有滤镜可以实现图片旋转。 图片展示用jQuery做是最轻松不过的是事情，一个预加载图片，一个动画基本上就可以搞定，而canvas图片旋转有个jQuery插件支持，于是我的&#8221;artZoom&#8221;就踏在前人的肩膀上出来了。 写完最后检测的时候发现IE8对其私有滤镜处理与IE6，IE7不一样，图片旋转后不会替换原来高度，结果把下面的元素盖住了。而新浪微博在IE8下这个BUG也没有修复。 我尝试用js对IE8置换图片长宽处理，仍然无法实现，最后动态改变图片外包元素高度来修复了这个问题。 查看文件： artZoom [需要jQuery库支持，artZoom.js 4kb多一点]]]></description>
			<content:encoded><![CDATA[<p>(本文示例脚本于2010-05-28更新)</p>
<p>如果说09年是SNS年，那10年肯定微博年，各大网站都推出或者准备推出自己的微博。我这几天都在看新浪微博，对新浪微博的用户体验很欣赏，有些细节我自己也琢磨了下，据我所知其界面是大名鼎鼎的eico设计的，其前端架构很非常不错。</p>
<p>步入正题。<br />
我点击新浪微博缩略图的时候会快速的置换一张大图，并且鼠标会显示放大或者缩小的指针，新浪前端工程师吧视口的大图片都预加载了，所以点击缩略图后替换大图的过程很爽快（PS：大家都知道点击Qzone的缩略图会出现什么）。</p>
<p>这种简约的效果非常适合插在内容区域单幅图片显示，放大后也不会干预用户操作，难怪很多微博客都采用（如：聚友旗下的911微博）。</p>
<p>其中有一个令我很惊讶的功能，图片可以自由旋转，这功能如何实现？</p>
<ul>
<li>CSS属性？貌似只有IE可以用CSS私有滤镜</li>
<li>javascript？还没有听说过有这个内置方法</li>
<li>服务端处理？极度消耗服务器资源，而且响应会很迟钝</li>
</ul>
<p>最用用firebug查看才知道是<a href="https://developer.mozilla.org/cn/Canvas_tutorial">canvas</a>实现的，它是未来的WEB标准的新产物，目前只有IE浏览器不支持它，但IE有个私有滤镜可以实现图片旋转。</p>
<p>图片展示用jQuery做是最轻松不过的是事情，一个预加载图片，一个动画基本上就可以搞定，而canvas图片旋转有个jQuery插件支持，于是我的&#8221;artZoom&#8221;就踏在前人的肩膀上出来了。</p>
<p>写完最后检测的时候发现IE8对其私有滤镜处理与IE6，IE7不一样，图片旋转后不会替换原来高度，结果把下面的元素盖住了。而新浪微博在IE8下这个BUG也没有修复。</p>
<p>我尝试用js对IE8置换图片长宽处理，仍然无法实现，最后动态改变图片外包元素高度来修复了这个问题。</p>
<p>查看文件：<br />
<a href="http://www.planeart.cn/downs/artZoom/demo.html"><strong>artZoom</strong></a> [需要jQuery库支持，artZoom.js 4kb多一点]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.planeart.cn/?feed=rss2&amp;p=696</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>打造小于5KB的jQuery计划</title>
		<link>http://www.planeart.cn/?p=672</link>
		<comments>http://www.planeart.cn/?p=672#comments</comments>
		<pubDate>Tue, 02 Feb 2010 07:42:50 +0000</pubDate>
		<dc:creator>唐 斌</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.planeart.cn/?p=672</guid>
		<description><![CDATA[一遍学习一边记录。陆续加入常用功能，语法沿用jQuery。压缩后尽量控制在5KB之内 CSS选择器引擎部分我使用了(mini)Selector Engine，据测试效率比jQuery高一点 支持选择器： tag tag > .className tag > tag #id > tag.className .className tag tag, tag, #id tag#id.className .className span > * > b 目前功能支持（2010-02-02）: DOM Ready （文档就绪即可加载脚本，不必等待图片或iframe） 事件绑定 完全模拟jQuery语法风格： $(function(){ $('#search > input.text').focus(function(){ if(this.value == '搜索..') this.value = ''; this.style.cssText = 'background:#FFC;'; }).blur(function(){ if(this.value == '')this.value = '搜索..'; this.style.cssText = ''; }); [...]]]></description>
			<content:encoded><![CDATA[<p>一遍学习一边记录。陆续加入常用功能，语法沿用jQuery。压缩后尽量控制在5KB之内<br />
CSS选择器引擎部分我使用了(mini)Selector Engine，据测试效率比jQuery高一点<br />
<span id="more-672"></span><br />
<strong>支持选择器：</strong></p>
<ul>
<li>tag</li>
<li>tag > .className</li>
<li>tag > tag</li>
<li>#id > tag.className</li>
<li>.className tag</li>
<li>tag, tag, #id</li>
<li>tag#id.className</li>
<li>.className</li>
<li>span > * > b</li>
</ul>
<p><strong>目前功能支持</strong>（2010-02-02）:</p>
<ol>
<li>DOM Ready （文档就绪即可加载脚本，不必等待图片或iframe）</li>
<li>事件绑定 </li>
</ol>
<p><strong>完全模拟jQuery语法风格：</strong></p>
<pre>$(function(){
	$('#search > input.text').focus(function(){
		if(this.value == '搜索..') this.value = '';
		this.style.cssText = 'background:#FFC;';
	}).blur(function(){
		if(this.value == '')this.value = '搜索..';
		this.style.cssText = '';
	});
});</pre>
<style type="text/css">
.codeTextarea { width:95%; height:30em; font-size:12px; }
</style>
<p><script type="text/javascript">function runCode(obj){var newwin=window.open('','','');newwin.opener = null;newwin.document.write(obj.value);newwin.document.close();}</script></p>
<pre>
<textarea class="codeTextarea">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script type="text/javascript">
(function(){
window._$ = window.$;
var query = window.query = window.$ = function(data){
	if (typeof data == 'string') {
		var selector = selectorEngine(data);
		return new query.fn.init(selector);
	}else{
		return new query.fn.ready(data);
	};
};
query.fn = query.prototype = { 
	init: function(selector){
		if(selector) this.data = selector;
		return this;
	},

	//DOM就绪
	ready: !+'\v1' ? function(f){
		(function(){
			try{
				document.documentElement.doScroll('left');
			} catch (error){
				setTimeout(arguments.callee, 0);
				return;
			};
			f();
		})();
	} : function(f){
			document.addEventListener('DOMContentLoaded', f, false);
	},

	//绑定事件
	bind: function(type,fn){
		var i = -1, l = this.data.length;
		if (window.addEventListener){
			while (++i < l){
				this.data[i].addEventListener(type, fn, false);
			};
		} else {
			e = "on" + type;
			while (++i < l){
				var d = this.data[i];
				d.attachEvent(e, (function(d){
					return function(){
						fn.call(d);
					}
				})(d));
			};
		};
		return this;
	}, 

	//事件列表
	blur: function(f){return this.bind('blur',f)},
	focus: function(f){return this.bind('focus',f)},
	load: function(f){return this.bind('load',f)},
	resize: function(f){return this.bind('resize',f)},
	scroll: function(f){return this.bind('scroll',f)},
	unload: function(f){return this.bind('unload',f)},
	click: function(f){return this.bind('click',f)},
	dblclick: function(f){return this.bind('dblclick',f)},
	mousedown: function(f){return this.bind('mousedown',f)},
	mouseup: function(f){return this.bind('mouseup',f)},
	mousemove: function(f){return this.bind('mousemove',f)},
	mouseover: function(f){return this.bind('mouseover',f)},
	mouseout: function(f){return this.bind('mouseout',f)},
	mouseenter: function(f){return this.bind('mouseenter',f)},
	mouseleave: function(f){return this.bind('mouseleave',f)},
	change: function(f){return this.bind('change',f)},
	select: function(f){return this.bind('select',f)},
	submit: function(f){return this.bind('submit',f)},
	keydown: function(f){return this.bind('keydown',f)},
	keypress: function(f){return this.bind('keypress',f)},
	keyup: function(f){return this.bind('keyup',f)},
	error: function(f){return this.bind('error',f)}
};
query.fn.init.prototype = query.fn;
})();
(function($){ 
	$.noConflict = function(){ 
		window.$ = window._$;
	};
})(query);
//query.noConflict();

//(mini)Selector Engine
var selectorEngine=(function(){var b=/(?:[\w\-\\.#]+)+(?:\[\w+?=([\'"])?(?:\\\1|.)+?\1\])?|\*|>/ig,g=/^(?:[\w\-_]+)?\.([\w\-_]+)/,f=/^(?:[\w\-_]+)?#([\w\-_]+)/,j=/^([\w\*\-_]+)/,h=[null,null];function d(o,m){m=m||document;var k=/^[\w\-_#]+$/.test(o);if(!k&#038;&#038;m.querySelectorAll){return c(m.querySelectorAll(o))}if(o.indexOf(",")>-1){var v=o.split(/,/g),t=[],s=0,r=v.length;for(;s<r;++s){t=t.concat(d(v[s],m))}return e(t)}var p=o.match(b),n=p.pop(),l=(n.match(f)||h)[1],u=!l&#038;&#038;(n.match(g)||h)[1],w=!l&#038;&#038;(n.match(j)||h)[1],q;if(u&#038;&#038;!w&#038;&#038;m.getElementsByClassName){q=c(m.getElementsByClassName(u))}else{q=!l&#038;&#038;c(m.getElementsByTagName(w||"*"));if(u){q=i(q,"className",RegExp("(^|\\s)"+u+"(\\s|$)"))}if(l){var x=m.getElementById(l);return x?[x]:[]}}return p[0]&#038;&#038;q[0]?a(p,q):q}function c(o){try{return Array.prototype.slice.call(o)}catch(n){var l=[],m=0,k=o.length;for(;m<k;++m){l[m]=o[m]}return l}}function a(w,p,n){var q=w.pop();if(q===">"){return a(w,p,true)}var s=[],k=-1,l=(q.match(f)||h)[1],t=!l&#038;&#038;(q.match(g)||h)[1],v=!l&#038;&#038;(q.match(j)||h)[1],u=-1,m,x,o;v=v&#038;&#038;v.toLowerCase();while((m=p[++u])){x=m.parentNode;do{o=!v||v==="*"||v===x.nodeName.toLowerCase();o=o&#038;&#038;(!l||x.id===l);o=o&#038;&#038;(!t||RegExp("(^|\\s)"+t+"(\\s|$)").test(x.className));if(n||o){break}}while((x=x.parentNode));if(o){s[++k]=m}}return w[0]&#038;&#038;s[0]?a(w,s):s}var e=(function(){var k=+new Date();var l=(function(){var m=1;return function(p){var o=p[k],n=m++;if(!o){p[k]=n;return true}return false}})();return function(m){var s=m.length,n=[],q=-1,o=0,p;for(;o<s;++o){p=m[o];if(l(p)){n[++q]=p}}k+=1;return n}})();function i(q,k,p){var m=-1,o,n=-1,l=[];while((o=q[++m])){if(p.test(o[k])){l[++n]=o}}return l}return d})();
</script>

<script type="text/javascript">
//---------------------------------------------------------演示代码 //////
$(function(){ 
	$('li').mouseover(function(){
		this.style.cssText = 'background:#000; color:#FFF; cursor:pointer';
	}).click(function(){
		this.style.cssText = 'background:#F00; color:#FFF;';
	});

	$('#search > input.text').focus(function(){
		if(this.value == '搜索..') this.value = '';
		this.style.cssText = 'background:#FFC;';
	}).blur(function(){
		if(this.value == '')this.value = '搜索..';
		this.style.cssText = '';
	});

	$('#search').submit(function(){
		alert('hello world');
		return false;
	});
});
</script>
</head>
<body>
<div id="wrap" style="width:550px;">
<h3>Usage:</h3>
<pre>
$(function(){
	$('#search > input.text').focus(function(){
		if(this.value == '搜索..') this.value = '';
		this.style.cssText = 'background:#FFC;';
	}).blur(function(){
		if(this.value == '')this.value = '搜索..';
		this.style.cssText = '';
	});
});</pre>
<form id="search" action="" method="get">
<input class="text" name="" type="text" value="搜索.." />
  </form>
<h3>Supported Selectors:</h3>
<ul>
<li id="test">tag</li>
<li>tag &gt; .className</li>
<li>tag &gt; tag</li>
<li>#id &gt; tag.className</li>
<li class="this">.className tag</li>
<li>tag, tag, #id</li>
<li>tag#id.className</li>
<li>.className</li>
<li>span &gt; * &gt; b</li>
</ul>
<div id="DOMready">
<h4>DOM Ready Test</h4>
<p>    <iframe src="http://www.qq.com" style="width:300px; height:200px; overflow:hidden;"></iframe></p>
<div style="width:300px; height:200px; overflow:hidden;"> <img src="http://img9.zol.com.cn/desk_pic/big_304/303619.jpg" /> </div>
</p></div>
</div>
<p></body><br />
</html><br />
</textarea>
</pre>
<p></p>
<input onclick="runCode(this.offsetParent.getElementsByTagName('textarea')[0])" value="运行代码" type="button">
]]></content:encoded>
			<wfw:commentRss>http://www.planeart.cn/?feed=rss2&amp;p=672</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>JavaScript对象探讨</title>
		<link>http://www.planeart.cn/?p=655</link>
		<comments>http://www.planeart.cn/?p=655#comments</comments>
		<pubDate>Sun, 31 Jan 2010 12:47:41 +0000</pubDate>
		<dc:creator>唐 斌</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.planeart.cn/?p=655</guid>
		<description><![CDATA[来自：蓝色理想 由于JavaScript的灵活性,可以让每个人按照自己的习惯进行编写代码.有函数式的编程方式,也有现在用的较为广泛的对象字面量.由于面向对象的出现,JavaScript刚开始的函数编程也逐渐演化为类式编程方式.现在我对几种比较熟悉的编程习惯进行简单的说明: 1.对象字面量: var person = { name:null, setName:function(name){ this.name = name; return this.name; }, getName:function(){ alert(this.name); } } 具有JavaScript特色的一种编程方式,以类为单位含有属性name,方法setName和getName.调用方法比较简便person.setname(&#8216;R&#8217;),this由此至终均指向person,person的属性与方法均不私有,可以进行调用. 2.prototype构造器调用模式 var Person = function(){ this.name = null; } Person.prototype.setName = function(name){ this.name = name; } Person.prototype.getName = function(){ alert(this.name); } 也是很常见的编程方式,创建一个Person类,然后利用prototype对类进行扩展,添加方法.与对象字面量最大区别在于,调用该类的方法时,必须先new(跟Java调用类相似).var p = new Person();p.getName();如果不用new,而直接创建,会产生错误.而且这种错误将不会报错,难以发现.错误的产生原因来自于this指向Person.prototype,而Person并没有setName方法. 3.利用匿名函数进行函数编程 (function(){ var name; var setName = function(n){ name [...]]]></description>
			<content:encoded><![CDATA[<p><span id="more-655"></span><br />
来自：<a href="http://www.blueidea.com/">蓝色理想</a></p>
<p>由于JavaScript的灵活性,可以让每个人按照自己的习惯进行编写代码.有函数式的编程方式,也有现在用的较为广泛的对象字面量.由于面向对象的出现,JavaScript刚开始的函数编程也逐渐演化为类式编程方式.现在我对几种比较熟悉的编程习惯进行简单的说明:</p>
<p><strong>1.对象字面量:</strong></p>
<blockquote><p>var person = {<br />
    name:null,<br />
    setName:function(name){<br />
        this.name = name;<br />
        return this.name;<br />
    },<br />
    getName:function(){<br />
        alert(this.name);<br />
    }<br />
}</p></blockquote>
<p>具有JavaScript特色的一种编程方式,以类为单位含有属性name,方法setName和getName.调用方法比较简便person.setname(&#8216;R&#8217;),this由此至终均指向person,person的属性与方法均不私有,可以进行调用.</p>
<p><strong>2.prototype构造器调用模式</strong></p>
<blockquote><p>var Person = function(){<br />
    this.name = null;<br />
}<br />
Person.prototype.setName = function(name){<br />
    this.name = name;<br />
}<br />
Person.prototype.getName = function(){<br />
    alert(this.name);<br />
}</p></blockquote>
<p>也是很常见的编程方式,创建一个Person类,然后利用prototype对类进行扩展,添加方法.与对象字面量最大区别在于,调用该类的方法时,必须先new(跟Java调用类相似).var p = new Person();p.getName();如果不用new,而直接创建,会产生错误.而且这种错误将不会报错,难以发现.错误的产生原因来自于this指向Person.prototype,而Person并没有setName方法.</p>
<p><strong>3.利用匿名函数进行函数编程</strong></p>
<blockquote><p>(function(){<br />
    var name;</p>
<p>    var setName = function(n){<br />
         name = n;<br />
    }<br />
    window['person']['setName'] = setName;</p>
<p>    var getName = function(){<br />
        alert(name);<br />
    }<br />
    window['person']['getName'] = getName;<br />
})()</p></blockquote>
<p>类的出现,其中一个最大的好处就是降低了全局变量的出现,但是如果你依旧习惯于函数式编程,没关系,只要创建一个匿名函数,进行闭包,就可以再里面进行函数编程,也不需要担心全局变量的出现.如上所看到的var name;在匿名函数外部是无法调用的,然后利用外部的变量来调用内部的函数,或者是变量.可以借此创建私有变量和私有方法.</p>
<p><strong>4.类式编程(不知道取什么名)</strong></p>
<blockquote><p>var person = function(){<br />
    var name = null;<br />
    return{<br />
        setName:function(n){<br />
            name = n;<br />
        },<br />
        getName:function(){<br />
            alert(name);<br />
        }<br />
    }<br />
}</p></blockquote>
<p>与对象字面量很相似,其不同之处在于抛开了this,和可以对方法与属性进行私有.调用方法与对象字面量基本一致.</p>
<p><strong>5.方法链</strong></p>
<blockquote><p>var Person = function(){<br />
    this.name = null;<br />
}<br />
Person.prototype = {<br />
    setName:function(name){<br />
        this.name = name;<br />
        return this;<br />
    },<br />
    getName:function(){<br />
        alert(this.name);<br />
        return this;<br />
    }<br />
}</p></blockquote>
<p>jQuery就是一个最经典的方法连库,如果还不懂方法链是什么,看看这个例子:</p>
<blockquote><p>var p = new Person();<br />
    p.setName(&#8216;Tom&#8217;).getName().setName(&#8216;Ray&#8217;).getName();</p></blockquote>
<p>由于每个方法的结尾都是return this;所以产生了方法链式的类.</p>
<p>本人比较熟悉的就是这几种方式了,每个人都有每个人的特色,所以方式也是说不尽的.但是借此,我想探讨以下几个问题:</p>
<p><strong>1.有关于this指针</strong></p>
<p>在建立多种类的时候都用到this,可是this的作用究竟是什么,而其实this在重用和继承上起着很大的作用.我们先看看一个关于继承的例子:<br />
首先建立Person类:</p>
<blockquote><p>var Person = function(){<br />
    this.name = null;<br />
}<br />
Person.prototype.setName = function(name){<br />
    this.name = name;<br />
}<br />
Person.prototype.getName = function(){<br />
    alert(this.name);<br />
}<br />
Person.prototype.getAge = function(){<br />
    var age = this.age || &#8221;;<br />
    alert(age);<br />
}</p></blockquote>
<p>然后在建立一个Children类,并集成Person的所有方法和属性:</p>
<blockquote><p>var Children = function(age){<br />
    this.name = null;<br />
    this.age = age;<br />
}<br />
Children.prototype = new Person();    //继承Person的属性和方法<br />
Children.prototype.ageJudge = function(){    //另外为Children添加新方法<br />
    if(this.age > 18){<br />
        alert(&#8216;成年人~&#8217;);<br />
    } else {<br />
        alert(&#8216;未满18岁呢~&#8217;);<br />
    }<br />
}<br />
Children.prototype.getName = function(){    //重写getName方法<br />
    var about = this.name + &#8216; &#8216; + this.age;<br />
    alert(about);<br />
}<br />
var tom = new Children(12);<br />
var ages = tom.getAge();    //12<br />
var judge = tom.ageJudge();    //未满18岁呢~<br />
var setN = tom.setName(&#8216;Tom&#8217;);<br />
var get = tom.getName();    //Tom 12</p></blockquote>
<p>这就是继承,然后我们看个简单的函数重用:</p>
<blockquote><p>var SetColor = function(){<br />
    this.style.backgroundColor = &#8216;#000&#8242;;    //this指向window<br />
}<br />
document.body.onclick = SetColor;    //此时this指向body<br />
documnet.getElementById(&#8216;color&#8217;).onmouseout = SetColor;        //this指向documnet.getElementById(&#8216;color&#8217;)</p></blockquote>
<p>看了this的作用之后,想必对this有了新的认识了吧.现在就有疑问了,就是this的该用与不该用,下面在看个简单的例子:</p>
<blockquote><p>var setColor = {<br />
    init:function(obj){<br />
        this.obj = obj;        //this指向setColor<br />
        this.obj.onclick = this.color;<br />
    },<br />
    color:function(){<br />
        this.style.backgroundColor = &#8216;#000&#8242;;    //this指向obj<br />
    }<br />
}</p></blockquote>
<p>就在一个类里,this却指向2处地方,有时这样总会让人觉得困惑.刚学习的人更会被this弄的晕头转向.而稍稍改变一下写代码的方式:</p>
<blockquote><p>var setColor = {<br />
    init:function(obj){<br />
        setColor.obj = obj;<br />
        setColor.obj.onclick = setColor.color;<br />
    },<br />
    color:function(){<br />
        this.style.backgroundColor = &#8216;#000&#8242;;    //this可以方便方法的重用<br />
    }<br />
}</p></blockquote>
<p>这样一下来,代码可以更加的清晰了.所以编写代码的时候应该考虑好究竟今后的用途,还有能否重用.如果明确了不进行继承或是重用,个人觉得应该尽可能的避免使用this,更有个比较常出现的问题.如下:</p>
<blockquote><p>var Person = function(){<br />
    this.name = null;<br />
}<br />
Person.prototype.setName = function(name){<br />
    this.name = name;<br />
}<br />
Person.setName(&#8216;tom&#8217;);    //错误方式此时setName方法中的this将指向Person.prototypel,Person并没有setName方法</p></blockquote>
<p>前面讲过,若果不写成var p = new Person();p.setName(&#8216;tom&#8217;);该类里的this将会直接指向Person.prototypel.这种错误在编译时,还是运行时都不会报错.有时会造成让人很头痛的问题.所以在编写代码时,我总是很慎重的选用this.</p>
<p><strong>2.类的封装</strong></p>
<p>在Java里,对类的方法或是属性,可以设置为私有,这样就可以避免外部的调用,而JavaScript却不存在这样的设置,看看下面的代码:</p>
<blockquote><p>var person = {<br />
    name:null,<br />
    init:function(name){<br />
        this.setName(name);<br />
    }，<br />
    setName:function(name){<br />
        this.name = name;<br />
        return this.name;<br />
    }<br />
}<br />
person.init(&#8216;tom&#8217;);    //tom</p></blockquote>
<p>在这个类里,一共有2个方法,分别是init和setName,而我们只希望从init中运行setName,或是以后将会为里面添加的各种方法,而不希望出现:</p>
<blockquote><p>person.setName(&#8216;tom&#8217;);    //tom</p></blockquote>
<p>直接调用setName方法,正确的说,希望setName方法私有,还有name属性私有.避免别的程序员使用你的类时,调用了不想被调用的方法.<br />
那应该怎么对类的封装好呢?试试另一种编程方式吧,看看改版的怎么样:</p>
<blockquote><p>var person = function(){<br />
    var name = null;<br />
    var setName = function(n){<br />
        name = n;<br />
        return name;<br />
    }<br />
    return{<br />
        init:function(n){<br />
            setName(n);<br />
        }<br />
    }<br />
}</p></blockquote>
<p>这样子,就可以讲原本要私有化的方法和属性私有化了,外部无法直接调用了.这也是利用了闭包而达成所需要的方式的.可是这种编程方式不易于读,尤其是新手看到这种代码会很吃力,还有在占用内存方面也要比一般的高些.<br />
好了,暂时先介绍到这里,下次有时间在说说闭包与作用域.</p>
<p>经典论坛交流：<br />
<a href="http://bbs.blueidea.com/thread-2958015-1-1.html">http://bbs.blueidea.com/thread-2958015-1-1.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.planeart.cn/?feed=rss2&amp;p=655</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
