<?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>CSSASS</title>
	<atom:link href="http://www.cssass.com/blog/index.php/feed//" rel="self" type="application/rss+xml" />
	<link>http://www.cssass.com/blog</link>
	<description>三人行必有我师焉，择其善者而从之，其不善者而改之</description>
	<lastBuildDate>Wed, 18 Apr 2012 08:55:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>(Three.js) 页面展现3D模型</title>
		<link>http://www.cssass.com/blog/index.php/2012/1266.html</link>
		<comments>http://www.cssass.com/blog/index.php/2012/1266.html#comments</comments>
		<pubDate>Fri, 24 Feb 2012 03:29:15 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[blender]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[requestAnimationFrame]]></category>
		<category><![CDATA[threejs]]></category>
		<category><![CDATA[webgl]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=1266</guid>
		<description><![CDATA[CSS3的3d-Transform，Canvas，SVG，WebGL等等技术的出现和发展，正将网页的3D化慢慢变得简单友好，但是3D建模毕竟有其很高的专业性，所以如果拥有一个内心强大，接口简洁的库就能使我们得心应手许多。Three.js便是备受推崇的一个，尽管API的变动，简陋的文档会让我们的上手比较困难。
下面我提供一个入门Demo，及一个用Three.js展示通用的3D模型格式的Demo。（注意：确保你使用的浏览器支持了Canvas，及WebGL。拥有一个先进的浏览器，将为你带来更好的上网体验。Test）
下面是入门Demo，加了注释。详细入门教程可以到这里Getting Started with Three.js


&#60;!DOCTYPE html&#62;
&#60;html&#62;
&#60;head&#62;
&#60;meta charset=&#34;UTF-8&#34; /&#62;
&#60;title&#62;立方体&#60;/title&#62;
    &#60;script type=&#34;text/javascript&#34; charset=&#34;utf-8&#34; src=&#34;/blog/resource/threejs/three.js&#34;&#62;&#60;/script&#62;
	&#60;style&#62;body{overflow:hidden;}&#60;/style&#62;
&#60;/head&#62;
&#60;body&#62;&#60;/body&#62;
	&#60;script&#62;
	/* 场景 */
	var WIDTH = document.documentElement.offsetWidth &#124;&#124; 800,
		HEIGHT = document.documentElement.clientHeight &#124;&#124; 600;
	var scene = new THREE.Scene();
	/* 摄像头 */
	var VIEW_ANGLE = 75,
		ASPECT = WIDTH / HEIGHT,
		NEAR = 0.1,
		FAR = 10000;
	var	camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); /* 摄像机视角，视口长宽比，近切面，远切面 */
		camera.position.set(0, 0, 1000); //放置位置
		scene.add(camera);
	/* 显示对象 [...]


Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2011/976.html' rel='bookmark' title='Permanent Link: 在canvas 2D API下实现3D效果（3D版心形函数的绘制）'>在canvas 2D API下实现3D效果（3D版心形函数的绘制）</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1140.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——1.引子'>canvas的像素级操作——1.引子</a></li><li><a href='http://www.cssass.com/blog/index.php/2011/927.html' rel='bookmark' title='Permanent Link: 植树'>植树</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>CSS3的3d-Transform，Canvas，SVG，WebGL等等技术的出现和发展，正将网页的3D化慢慢变得简单友好，但是3D建模毕竟有其很高的专业性，所以如果拥有一个内心强大，接口简洁的库就能使我们得心应手许多。<a href="https://github.com/mrdoob/three.js" target="_blank">Three.js</a>便是备受推崇的一个，尽管API的变动，简陋的文档会让我们的上手比较困难。</p>
<p>下面我提供一个入门Demo，及一个用Three.js展示通用的3D模型格式的Demo。（注意：确保你使用的浏览器支持了Canvas，及WebGL。拥有一个先进的浏览器，将为你带来更好的上网体验。<a href="http://www.html5test.com/" target="_blank">Test</a>）</p>
<p>下面是入门Demo，加了注释。详细入门教程可以到这里<a href="http://www.aerotwist.com/tutorials/getting-started-with-three-js/" target="_blank">Getting Started with Three.js</a></p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_oH5wIe" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot; /&gt;
&lt;title&gt;立方体&lt;/title&gt;
    &lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot; src=&quot;/blog/resource/threejs/three.js&quot;&gt;&lt;/script&gt;
	&lt;style&gt;body{overflow:hidden;}&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;&lt;/body&gt;
	&lt;script&gt;
	/* 场景 */
	var WIDTH = document.documentElement.offsetWidth || 800,
		HEIGHT = document.documentElement.clientHeight || 600;
	var scene = new THREE.Scene();
	/* 摄像头 */
	var VIEW_ANGLE = 75,
		ASPECT = WIDTH / HEIGHT,
		NEAR = 0.1,
		FAR = 10000;
	var	camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); /* 摄像机视角，视口长宽比，近切面，远切面 */
		camera.position.set(0, 0, 1000); //放置位置
		scene.add(camera);
	/* 显示对象 */
	var geometry = new THREE.CubeGeometry( 200, 200, 200 ), //几何属性。代码位于&quot;\src\extras\geometries&quot;
		material = new THREE.MeshLambertMaterial( { color: 0xcccccc} ); //材质属性 &quot;\src\materials&quot;
	var cube = new THREE.Mesh(geometry, material);
		cube.rotation.set(10,20,10); //放置角度
		scene.add(cube);
	/* 灯光 */
	var light = new THREE.DirectionalLight(0xFFFFFF); //直线光,&quot;\src\lights&quot;
		light.position.set(0, 0, 100).normalize();
		scene.add(light);
	/* 渲染器 */
	var	renderer = new THREE.CanvasRenderer(); //有Canvas，WebGL，SVG三种模式
		renderer.setSize(WIDTH , HEIGHT);
		document.body.appendChild(renderer.domElement);
	/* 动画 */
	(function anime(){
		cube.rotation.x += 0.01; //改变立方体角度
		renderer.render(scene, camera); //开始渲染
		return requestAnimationFrame(anime);
	})()
&lt;/script&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_oH5wIe');"/> </div>
</div>
<p>上面使用了Canvas模式渲染，因为考虑到Opera还不支持WebGL，WebGL的渲染模式要比Canvas快的要多的多。</p>
<p>下面是一个展示机器人<a href="http://thedarkbanditking.deviantart.com/gallery/?q=MANGUSA+#/da621z" target="_blank">MGA-411 Mangusa</a>模型的Demo。<br />
Three.js可以调用以Json格式存储模型信息的js文件来创建模型。模型你可以自己在3D软件上建模完成，或在网上下载。至于模型格式，你可以通过three.js提供的<a href="https://github.com/mrdoob/three.js/tree/master/utils/exporters/blender">插件</a>在Blender这款开源3D制作软件中将一些3D模型格式，如3ds，obj等，转换成符合three.js标准的js格式。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_mtFs3l" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot; /&gt;
&lt;title&gt;MGA-411 Mangusa&lt;/title&gt;
    &lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot; src=&quot;/blog/resource/threejs/three.js&quot;&gt;&lt;/script&gt;
	&lt;style&gt;body{overflow:hidden;background:#000}&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id=&quot;Loading&quot; style=&quot;color:#fff&quot;&gt;Loading...&lt;/div&gt;
&lt;/body&gt;
	&lt;script&gt;
	/* 场景 */
	var WIDTH = document.documentElement.offsetWidth || 800,
		HEIGHT = document.documentElement.clientHeight || 600;
	var scene = new THREE.Scene();
	/* 摄像头 */
	var VIEW_ANGLE = 75,
		ASPECT = WIDTH / HEIGHT,
		NEAR = 0.1,
		FAR = 10000;
	var	camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
		camera.position.set(0, 0, 1000);
		scene.add(camera);
	/* 渲染器 */
	var	renderer = new THREE.WebGLRenderer();
		renderer.setSize(WIDTH , HEIGHT);
		document.body.appendChild(renderer.domElement);
	/* 灯光 */
	var light = new THREE.DirectionalLight(0xFFFFFF);
		light.position.set(0, 0, 99).normalize();
		scene.add(light);
	/* 显示对象 */
	var material = new THREE.MeshLambertMaterial({ color: 0xcccccc, wireframe: true }),
		obj;
	var loader = new THREE.JSONLoader(true);
    loader.load(&quot;/blog/resource/threejs/model/MGA.js&quot;, function ( geometry ) {
		var loading = document.getElementById(&quot;Loading&quot;);
		loading.parentNode.removeChild(loading);
		obj = new THREE.Mesh(geometry, material);
		obj.position.set(0,1,990);
		scene.add(obj);
		var start = new Date().getTime(),delta;
		(function anime(){
			delta = new Date().getTime() - start;
			obj.rotation.y =   delta / 1000;
			renderer.render(scene, camera);
			return requestAnimationFrame(anime);
		})();
	});
&lt;/script&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_mtFs3l');"/> </div>
</div>
<p><script>
function loadScript(url, callback){
	var script = document.createElement("script")
	script.type = "text/javascript";
	var callback = callback || (function(){});
	if(script.readyState){  //IE
	  script.onreadystatechange = function(){
		  if (script.readyState == "loaded" || script.readyState == "complete"){
			  script.onreadystatechange = null;
			  callback();
		}
	  };
	}else{ 
	  script.onload = function(){
		  callback();
	  };
	}
	script.src = url;
	document.getElementsByTagName("head")[0].appendChild(script);
}
window.onload = function () {
	loadScript('/blog/resource/threejs/three.js',function(){
		loadScript('/blog/resource/threejs/model/MGA.js')
	});
};
</script></p>


<p>Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2011/976.html' rel='bookmark' title='Permanent Link: 在canvas 2D API下实现3D效果（3D版心形函数的绘制）'>在canvas 2D API下实现3D效果（3D版心形函数的绘制）</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1140.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——1.引子'>canvas的像素级操作——1.引子</a></li><li><a href='http://www.cssass.com/blog/index.php/2011/927.html' rel='bookmark' title='Permanent Link: 植树'>植树</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2012/1266.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>firefox10的3D Transform</title>
		<link>http://www.cssass.com/blog/index.php/2012/1258.html</link>
		<comments>http://www.cssass.com/blog/index.php/2012/1258.html#comments</comments>
		<pubDate>Wed, 01 Feb 2012 03:48:02 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[CSS3]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[erspective]]></category>
		<category><![CDATA[preserve-3d]]></category>
		<category><![CDATA[transform]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=1258</guid>
		<description><![CDATA[之前写了一篇CSS3的崛起——体验webkit的3D-Effect。
随着firefox10正式版发布，firefox也支持3D Transform了，所以补充一篇，将上篇中的代码移植过来，支持firefox。
这里先穿插介绍下firefox10的新特性，firefox10除了支持3D Transform，还提供了Fullscreen API，令人兴奋吧。另外firefox10成为Mozila首个“长期支持版本”(Extended Support Release，简称“ESR”)，这种当然是市场考虑啦，至于是什么用意和市场反响我们就不探讨了。
下面是演示demo，只支持firefox10。 chrome浏览器的用户可以参考上一篇。


&#60;!DOCTYPE html&#62;
&#60;html&#62;
&#60;head&#62;
&#60;meta charset=&#34;utf-8&#34; /&#62;
&#60;title&#62;firefox10&#60;/title&#62;
&#60;style&#62;
*{padding:0;margin:0;}
body { background-color:#deddcd;}
#movieposters { list-style:none; margin:100px;}
#movieposters li {float:left;
	-moz-perspective: 500px;
}
/* 图片3d变换效果 */
#movieposters li img { border:10px solid #fcfafa;-moz-box-shadow:0 3px 10px #888;
	-moz-transform: rotateY(30deg);
	-moz-transition-property: -moz-transform;
	-moz-transition-duration: 0.5s;
}
#movieposters li:hover img {-moz-transform: rotateY(0deg); }
/* 文字框3d变换效果 */
.movieinfo {border:10px solid #fcfafa; padding:0 10px; width:120px; height:100px; background-color:#deddcd; margin:-125px 0 0 55px; position:absolute;-moz-box-shadow:0 10px 20px #888;
	-moz-transform: [...]


Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2010/844.html' rel='bookmark' title='Permanent Link: CSS3的崛起——体验webkit的3D-Effect'>CSS3的崛起——体验webkit的3D-Effect</a></li><li><a href='http://www.cssass.com/blog/index.php/2010/833.html' rel='bookmark' title='Permanent Link: 纯css打造投影效果——CSS3属性transform的应用'>纯css打造投影效果——CSS3属性transform的应用</a></li><li><a href='http://www.cssass.com/blog/index.php/2011/992.html' rel='bookmark' title='Permanent Link: 采用css3的语言框效果'>采用css3的语言框效果</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>之前写了一篇<a href="http://www.cssass.com/blog/index.php/2010/844.html">CSS3的崛起——体验webkit的3D-Effect</a>。<br />
随着firefox10正式版发布，firefox也支持3D Transform了，所以补充一篇，将上篇中的代码移植过来，支持firefox。</p>
<p>这里先穿插介绍下firefox10的新特性，firefox10除了支持3D Transform，还提供了Fullscreen API，令人兴奋吧。另外firefox10成为Mozila首个“长期支持版本”(Extended Support Release，简称“ESR”)，这种当然是市场考虑啦，至于是什么用意和市场反响我们就不探讨了。</p>
<p>下面是演示demo，只支持firefox10。 chrome浏览器的用户可以参考上一篇。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_7Usn1t" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot; /&gt;
&lt;title&gt;firefox10&lt;/title&gt;
&lt;style&gt;
*{padding:0;margin:0;}
body { background-color:#deddcd;}
#movieposters { list-style:none; margin:100px;}
#movieposters li {float:left;
	-moz-perspective: 500px;
}
/* 图片3d变换效果 */
#movieposters li img { border:10px solid #fcfafa;-moz-box-shadow:0 3px 10px #888;
	-moz-transform: rotateY(30deg);
	-moz-transition-property: -moz-transform;
	-moz-transition-duration: 0.5s;
}
#movieposters li:hover img {-moz-transform: rotateY(0deg); }
/* 文字框3d变换效果 */
.movieinfo {border:10px solid #fcfafa; padding:0 10px; width:120px; height:100px; background-color:#deddcd; margin:-125px 0 0 55px; position:absolute;-moz-box-shadow:0 10px 20px #888;
	-moz-transform: translateZ(30px) rotateY(30deg);
	-moz-transition-property: -moz-transform, box-shadow, margin;
	-moz-transition-duration: 0.5s; }
#movieposters li:hover .movieinfo {-moz-box-shadow:0 5px 10px #888; margin:-105px 0 0 30px;
	-moz-transform: rotateY(0deg); }
.movieinfo h3 {color:#7a3f3a;font-family:Georgia; text-align:center; }
.movieinfo p {padding:10px 0;}
.movieinfo a { display:block; background:#7a3f3a; padding:3px 0; color:#eee; text-decoration:none; text-align:center; margin:0 auto;-moz-border-radius:5px; }
.movieinfo a:hover, .movieinfo a:focus { background-color:#6a191f; color:#fff; }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;ul id=&quot;movieposters&quot;&gt;
	&lt;li&gt;
		&lt;img src='http://www.cssass.com/blog/resource/avatar/avatar_m.jpg' width='200' /&gt;
		&lt;div class=&quot;movieinfo&quot;&gt;
			&lt;h3&gt;Avatar 2&lt;/h3&gt;
			&lt;p&gt;You like a baby&lt;/p&gt;
			&lt;a href=&quot;http://www.cssass.com&quot; title=&quot;I see you&quot;&gt;More info&lt;/a&gt;
		&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;img src='http://www.cssass.com/blog/resource/avatar/avatar_m.jpg' width='200' /&gt;
		&lt;div class=&quot;movieinfo&quot;&gt;
			&lt;h3&gt;Avatar 2&lt;/h3&gt;
			&lt;p&gt;You like a baby&lt;/p&gt;
			&lt;a href=&quot;http://www.cssass.com&quot; title=&quot;I see you&quot;&gt;More info&lt;/a&gt;
		&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;img src='http://www.cssass.com/blog/resource/avatar/avatar_m.jpg' width='200' /&gt;
		&lt;div class=&quot;movieinfo&quot;&gt;
			&lt;h3&gt;Avatar 2&lt;/h3&gt;
			&lt;p&gt;You like a baby&lt;/p&gt;
			&lt;a href=&quot;http://www.cssass.com&quot; title=&quot;I see you&quot;&gt;More info&lt;/a&gt;
		&lt;/div&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_7Usn1t');"/> </div>
</div>
<p>去除一些效果</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_3TGbmV" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot; /&gt;
&lt;title&gt;firefox10&lt;/title&gt;
&lt;style&gt;
*{padding:0;margin:0;list-style:none; }
body { background:#deddcd;margin:100px;}
#movieposters li {float:left;
	-moz-perspective: 500px;
}
#movieposters li img {
	-moz-transform: rotateY(30deg);
	-moz-transition-property: -moz-transform;
	-moz-transition-duration: 0.5s;
}
#movieposters li:hover img {
	-moz-transform: rotateY(0deg);
}
.movieinfo {
	position:absolute; width:120px; height:100px; background:#fff; margin:-125px 0 0 55px;
	-moz-transform: translateZ(30px) rotateY(30deg);
	-moz-transition-property: -moz-transform, margin;
	-moz-transition-duration: 0.5s;
}
#movieposters li:hover .movieinfo {
	margin:-105px 0 0 40px;
	-moz-transform: rotateY(0deg);
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;ul id=&quot;movieposters&quot;&gt;
	&lt;li&gt;
		&lt;img src='http://www.cssass.com/blog/resource/avatar/avatar_m.jpg' width='200' /&gt;
		&lt;div class=&quot;movieinfo&quot;&gt;
			(未设置transform-style，默认为plat)
		&lt;/div&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_3TGbmV');"/> </div>
</div>
<p>使用preserve-3d，实现全方位3D</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_I3RjUt" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot; /&gt;
&lt;title&gt;firefox10&lt;/title&gt;
&lt;style&gt;
*{padding:0;margin:0;list-style:none; }
body { background:#deddcd;margin:100px;}
#movieposters{
	-moz-perspective: 1000px;
}
#movieposters li {float:left;
	-moz-animation: spin 10s infinite linear;
}
#movieposters li.first{
	-moz-transform-style: preserve-3d;
}
#movieposters li.second{
	-moz-transform-style: plat;
}
 @-moz-keyframes spin {
      from { -moz-transform: rotateY(0); }
      to   { -moz-transform: rotateY(360deg); }
    }
#movieposters li img {
	-moz-transform: rotateY(30deg);
	-moz-transition-property: -moz-transform;
	-moz-transition-duration: 0.5s;
}
#movieposters li:hover img {
	-moz-transform: rotateY(0deg);
}
.movieinfo {
	position:absolute; width:120px; height:100px; background:#fff; margin:-125px 0 0 55px;
	-moz-transform: translateZ(30px) rotateY(30deg);
	-moz-transition-property: -moz-transform, margin;
	-moz-transition-duration: 0.5s;
}
#movieposters li:hover .movieinfo {
	margin:-105px 0 0 40px;
	-moz-transform: rotateY(0deg);
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;ul id=&quot;movieposters&quot;&gt;
	&lt;li class='first'&gt;
		&lt;img src='http://www.cssass.com/blog/resource/avatar/avatar_m.jpg' width='200' /&gt;
		&lt;div class=&quot;movieinfo&quot;&gt;
			Avatar 2 (preserve-3d)
		&lt;/div&gt;
	&lt;/li&gt;
	&lt;li class='second'&gt;
		&lt;img src='http://www.cssass.com/blog/resource/avatar/avatar_m.jpg' width='200' /&gt;
		&lt;div class=&quot;movieinfo&quot;&gt;
			Avatar 2 (plat)
		&lt;/div&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_I3RjUt');"/> </div>
</div>
<p>最后说明一下firefox和webkit间使用的一点差别：<br />
火狐10下的3D Transforms在设置perspective属性值时必须带单位px，webkit可以省略；<br />
另外，webkit在用transition-property设置transform这个值时，可以不用前缀，而firefox需要写上-moz-transform;</p>


<p>Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2010/844.html' rel='bookmark' title='Permanent Link: CSS3的崛起——体验webkit的3D-Effect'>CSS3的崛起——体验webkit的3D-Effect</a></li><li><a href='http://www.cssass.com/blog/index.php/2010/833.html' rel='bookmark' title='Permanent Link: 纯css打造投影效果——CSS3属性transform的应用'>纯css打造投影效果——CSS3属性transform的应用</a></li><li><a href='http://www.cssass.com/blog/index.php/2011/992.html' rel='bookmark' title='Permanent Link: 采用css3的语言框效果'>采用css3的语言框效果</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2012/1258.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>canvas的像素级操作——4.关注性能</title>
		<link>http://www.cssass.com/blog/index.php/2012/1179.html</link>
		<comments>http://www.cssass.com/blog/index.php/2012/1179.html#comments</comments>
		<pubDate>Tue, 17 Jan 2012 04:07:16 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[imageData]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=1179</guid>
		<description><![CDATA[我们开篇就提过，canvas的像素级操作相对来说是很低效的。
我们试着写一个图片切割效果。


&#60;!DOCTYPE html&#62;
&#60;html&#62;
&#60;head&#62;
	&#60;meta charset=&#34;utf-8&#34;&#62;
	&#60;title&#62;效率相关&#60;/title&#62;
&#60;/head&#62;
&#60;body&#62;
&#60;canvas id=&#34;board&#34; width=&#34;100&#34; height=&#34;110&#34;&#62;&#60;/canvas&#62;
&#60;script type=&#34;text/javascript&#34;&#62;
function splinter(ctx,imgPixels){
	var round = 0; //统计循环次数
	for(var y = 0; y &#60; imgPixels.height; y++){
		for(var x = 0; x &#60; imgPixels.width; x++){
			/* 虽然只调用了putImageData一个方法，但是操作的data非常多 */
			ctx.putImageData(imgPixels, x, y, x, y, 1 ,1); //后四个参数控制显示区域
			round ++ ;
		}
	}
	return round;
}
function demo(img){
	var w = img.width,
		h = img.height;
	var temp = document.createElement('canvas');
		temp.width = w;
		temp.height = h;
	var tempCtx = temp.getContext('2d');
		tempCtx.drawImage(img, 0, [...]


Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2012/1158.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——2.RGBA通道调色'>canvas的像素级操作——2.RGBA通道调色</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1165.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——3.使用卷积矩阵'>canvas的像素级操作——3.使用卷积矩阵</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1140.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——1.引子'>canvas的像素级操作——1.引子</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>我们开篇就提过，canvas的像素级操作相对来说是很低效的。</p>
<p>我们试着写一个图片切割效果。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_SpqwV1" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;title&gt;效率相关&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;canvas id=&quot;board&quot; width=&quot;100&quot; height=&quot;110&quot;&gt;&lt;/canvas&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function splinter(ctx,imgPixels){
	var round = 0; //统计循环次数
	for(var y = 0; y &lt; imgPixels.height; y++){
		for(var x = 0; x &lt; imgPixels.width; x++){
			/* 虽然只调用了putImageData一个方法，但是操作的data非常多 */
			ctx.putImageData(imgPixels, x, y, x, y, 1 ,1); //后四个参数控制显示区域
			round ++ ;
		}
	}
	return round;
}
function demo(img){
	var w = img.width,
		h = img.height;
	var temp = document.createElement('canvas');
		temp.width = w;
		temp.height = h;
	var tempCtx = temp.getContext('2d');
		tempCtx.drawImage(img, 0, 0, w, h);
	var ctx = document.getElementById('board').getContext('2d');
	var imgPixels = tempCtx.getImageData(0, 0, w, h);
	return splinter(ctx,imgPixels);
}
(function(){
	var img = new Image();
		img.src = &quot;/blog/resource/avatar/avatar_s.jpg&quot;;
		img.width = 50;
		img.height = 55;
		img.onload = function(){
			var d = new Date();
			var func = demo(img);
			alert(&quot;耗时：&quot; + (new Date() - d) + &quot;(ms)，\n共执行了&quot; + func + &quot;次的putImageData&quot;);
		}
})()
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_SpqwV1');"/> </div>
</div>
<p>对于这个效果，因为我们并不需要操作图像的rgba数据，而只是把图像进行分割，所以利用putImageData的后四个可见区参数进行了设置就行了。<br />
但是，这样做的性能却非常不理想。因为我们操作的ImageData数据实在太多了，循环执行了2750遍，相当于我们对整幅图像进行了2750次的像素级复制，而其实在可见区之外的ImageData数据并不是我们所需要的。</p>
<p>那么，我们在对源图getImageData的时候，可以只获取我们需要的ImageData。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_7miJWF" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;title&gt;效率相关&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;canvas id=&quot;board&quot; width=&quot;100&quot; height=&quot;110&quot;&gt;&lt;/canvas&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function splinter(ctx,tempCtx, w, h){
	var newData = [];
	var round = 0; //统计循环次数
	for(var y = 0; y &lt; h; y++){
		newData[y] = [];
		for(var x = 0; x &lt; w; x++){
			newData[y][x] = tempCtx.getImageData(x, y, 1, 1); //分开获取所需要的ImageData
			ctx.putImageData(newData[y][x], x*2, y*2);
			round ++ ;
		}
	}
	return round;
}
function demo(img){
	var w = img.width,
		h = img.height;
	var temp = document.createElement('canvas');
		temp.width = w;
		temp.height = h;
	var tempCtx = temp.getContext('2d');
		tempCtx.drawImage(img, 0, 0, w, h);
	var ctx =  document.getElementById('board').getContext('2d');
	return round = splinter(ctx,tempCtx, w, h);
}
(function(){
	var img = new Image();
		img.src = &quot;/blog/resource/avatar/avatar_s.jpg&quot;;
		img.width = 50;
		img.height = 55;
		img.onload = function(){
			var d = new Date();
			var func = demo(img);
			alert(&quot;耗时：&quot; + (new Date() - d) + &quot;(ms)，\n共执行了&quot; + func + &quot;次的getImageData和putImageData&quot;);
		}
})()
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_7miJWF');"/> </div>
</div>
<p>第二种做法虽然在循环的时候多运行了一个方法（共执行2750次的getImageData和putImageData方法），但因为操作的ImageData少了2750倍，所以在效率上比第一种方式高了很多。</p>
<p>但从流程上来讲，我们只需要在刚开始的时候获取一次源图的ImageData（执行getImageData），对数据进行再排列后，最后再输出一次新的ImageData（执行putImageData）就可以了。<br />
根本不需要在循环中反复调用getImageData和putImageData。所以现在的关键点是get和put之间的如何对数据进行重排列。</p>
<p>ImageData.data可以看做一个矩形矩阵，我们已知，它的序列号（n）与ImageData.width(w),及x轴序列号(x),y轴序列号（y）的关系是：n = ((y * w) + x) * 4;  （其中的4表示了RGBA四个数据）。我们要的新的输出ImageData，其实是x加倍，y加倍，w加倍的一个新矩阵。那么新矩阵序号与原x,y,w的关系式应该是：t = ((y * 2 * w * 2) + x * 2) * 4;</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_W7V5qU" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;title&gt;效率相关&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;canvas id=&quot;board&quot; width=&quot;100&quot; height=&quot;110&quot;&gt;&lt;/canvas&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function splinter(ctx,imgPixels){
	var round = 0; //统计循环次数
	var n = 0,
		w = imgPixels.width,
		h = imgPixels.height,
		newdata = ctx.createImageData(w*2, h*2);
	for(var y = 0; y &lt; h; y++){
		for(var x = 0; x &lt; w; x++){
			n = ((y * w) + x) * 4; /* data序号n与x,y,w的关系 */
			t = ((y * 2 * w * 2) + x * 2) * 4; /* 分割后，y,x,w都变大了一倍 */
			newdata.data[t] =  imgPixels.data[n];
			newdata.data[t + 1] =  imgPixels.data[n + 1];
			newdata.data[t + 2] =  imgPixels.data[n + 2];
			newdata.data[t + 3] =  imgPixels.data[n + 3];
			round ++ ;
		}
	}
	ctx.putImageData(newdata, 0, 0);
	return round;
}
function demo(img){
	var w = img.width,
		h = img.height;
	var temp = document.createElement('canvas');
		temp.width = w;
		temp.height = h;
	var tempCtx = temp.getContext('2d');
		tempCtx.drawImage(img, 0, 0, w, h);
	var ctx = document.getElementById('board').getContext('2d');
	var imgPixels = tempCtx.getImageData(0, 0, w, h);
	return splinter(ctx,imgPixels);
}
(function(){
	var img = new Image();
		img.src = &quot;/blog/resource/avatar/avatar_s.jpg&quot;;
		img.width = 50;
		img.height = 55;
		img.onload = function(){
			var d = new Date();
			var func = demo(img);
			alert(&quot;耗时：&quot; + (new Date() - d) + &quot;(ms)，\n共循环了&quot; + func + &quot;次,循环内不执行getImageData和putImageData方法&quot;);
		}
})()
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_W7V5qU');"/> </div>
</div>
<p>第三种方法相对于第二种方法的效率提高了十几倍。第三种方法的关键点是找出新旧矩阵之间的关系，对于我们这一例来说还比较容易，复杂一点的，算法可就没这么简单了。</p>
<p>——————————————<br />
重要补充：</p>
<p>我们先总结下三种方法：第一种：效率低差，但理解起来最简单。第三种，算法复杂，但效率最高。第二种，折中。<br />
然而，如果使用的是webkit，opera浏览器，我们会发现第一种方法的效率比之第三种方法居然差不了多少！<br />
可以看出webkit,opera对putImageData做过优化。对于putImageData(imgdata, x, y, x, y, 1 ,1)方法，webkit,opera只对（x,y,1,1）这个1平方px区域内的数据进行了put操作，区域外的数据并没有进行操作，这样在效率上会有很大的提高。<br />
可惜的是firefox(9)就没有做过优化。要加油啊，Mozila！<br />
最新测试了下ie9，结果显示第一种方法的效率的确很低，而第二种方法比第一种方法的效率还要低一倍。看来ie9果然也没用对putImageData进行优化，而且ie9下的getImageData也没用像其他浏览器下那么优化。对于getImageData(x,y,1,1)的获取，它操作的整个图像的像素数据的，而不是那个1平方px内的数据。</p>
<p>目前来说，考虑到各个浏览器原生方法的效率问题，第三种方法是最优的，即不要反复调用getImageData和putmageData，因为某些浏览器下一旦调用就是操作全部imageData的，而不会看你的参数。不过在未来，各个浏览器肯定会对原生方法进行优化的，在考虑第一种方法的时候就不用有所顾忌了！</p>


<p>Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2012/1158.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——2.RGBA通道调色'>canvas的像素级操作——2.RGBA通道调色</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1165.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——3.使用卷积矩阵'>canvas的像素级操作——3.使用卷积矩阵</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1140.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——1.引子'>canvas的像素级操作——1.引子</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2012/1179.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>canvas的像素级操作——3.使用卷积矩阵</title>
		<link>http://www.cssass.com/blog/index.php/2012/1165.html</link>
		<comments>http://www.cssass.com/blog/index.php/2012/1165.html#comments</comments>
		<pubDate>Thu, 12 Jan 2012 07:17:55 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[blur]]></category>
		<category><![CDATA[Convolution]]></category>
		<category><![CDATA[imageData]]></category>
		<category><![CDATA[Matrix]]></category>
		<category><![CDATA[sharpening]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=1165</guid>
		<description><![CDATA[利用卷积矩阵(Convolution Matrix)操作像素，我们可以很方便的得到诸如模糊、边缘检测、锐化、浮雕和斜角这样的效果。
常用的矩阵类型是 3 x 3 矩阵，另外还有5 x 5的矩阵。
工作原理：http://flex4jiaocheng.com/blog/280
点阵图中的每一个像素被称为“初步像素”，用与卷积矩阵同样面积的“初步像素”从左到右从上到下与卷积矩阵中相应位置的值相乘，再将得到的9个或25个中间值相加，就得到了“初步像素”矩阵中央的一个值的结果值再与Divisor（因子）相除，与Offset（偏移量）相加，最后得到终值。如下图所示：

应用卷积矩阵实现特效:


&#60;!DOCTYPE html&#62;
&#60;html&#62;
&#60;head&#62;
	&#60;meta charset=&#34;utf-8&#34;&#62;
	&#60;title&#62;利用卷积矩阵实现特效&#60;/title&#62;
&#60;/head&#62;
&#60;body&#62;
&#60;canvas id=&#34;canvas1&#34; width=&#34;200&#34; height=&#34;200&#34; title=&#34;浮雕效果&#34;&#62;&#60;/canvas&#62;
&#60;canvas id=&#34;canvas2&#34; width=&#34;200&#34; height=&#34;200&#34; title=&#34;边缘检测&#34;&#62;&#60;/canvas&#62;
&#60;canvas id=&#34;canvas3&#34; width=&#34;200&#34; height=&#34;200&#34; title=&#34;锐化&#34;&#62;&#60;/canvas&#62;
&#60;canvas id=&#34;canvas4&#34; width=&#34;200&#34; height=&#34;200&#34; title=&#34;基本模糊&#34;&#62;&#60;/canvas&#62;
&#60;canvas id=&#34;canvas5&#34; width=&#34;200&#34; height=&#34;200&#34; &#62;&#60;/canvas&#62;
&#60;script type=&#34;text/javascript&#34;&#62;
function convolution(imgPixels, matrix, divisor, offset){
	/* 卷积矩阵应用函数 */
    var w = imgPixels.width,
		h = imgPixels.height,
		d = imgPixels.data;
	var canvas = document.createElement('canvas'),
		ctx = canvas.getContext('2d'),
		newImgPixels = ctx.createImageData(w,h);
	for [...]


Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2012/1140.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——1.引子'>canvas的像素级操作——1.引子</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1158.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——2.RGBA通道调色'>canvas的像素级操作——2.RGBA通道调色</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1179.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——4.关注性能'>canvas的像素级操作——4.关注性能</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>利用卷积矩阵(Convolution Matrix)操作像素，我们可以很方便的得到诸如模糊、边缘检测、锐化、浮雕和斜角这样的效果。</p>
<p>常用的矩阵类型是 3 x 3 矩阵，另外还有5 x 5的矩阵。</p>
<p>工作原理：<a href="http://flex4jiaocheng.com/blog/280">http://flex4jiaocheng.com/blog/280</a></p>
<p>点阵图中的每一个像素被称为“初步像素”，用与卷积矩阵同样面积的“初步像素”从左到右从上到下与卷积矩阵中相应位置的值相乘，再将得到的9个或25个中间值相加，就得到了“初步像素”矩阵中央的一个值的结果值再与Divisor（因子）相除，与Offset（偏移量）相加，最后得到终值。如下图所示：<br />
<img src="http://flex4jiaocheng.com/sites/rhythmtechnology.com/files/diagrams/convolution-calculate.png" /></p>
<p>应用卷积矩阵实现特效:</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_l_Cz3V" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;title&gt;利用卷积矩阵实现特效&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;canvas id=&quot;canvas1&quot; width=&quot;200&quot; height=&quot;200&quot; title=&quot;浮雕效果&quot;&gt;&lt;/canvas&gt;
&lt;canvas id=&quot;canvas2&quot; width=&quot;200&quot; height=&quot;200&quot; title=&quot;边缘检测&quot;&gt;&lt;/canvas&gt;
&lt;canvas id=&quot;canvas3&quot; width=&quot;200&quot; height=&quot;200&quot; title=&quot;锐化&quot;&gt;&lt;/canvas&gt;
&lt;canvas id=&quot;canvas4&quot; width=&quot;200&quot; height=&quot;200&quot; title=&quot;基本模糊&quot;&gt;&lt;/canvas&gt;
&lt;canvas id=&quot;canvas5&quot; width=&quot;200&quot; height=&quot;200&quot; &gt;&lt;/canvas&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function convolution(imgPixels, matrix, divisor, offset){
	/* 卷积矩阵应用函数 */
    var w = imgPixels.width,
		h = imgPixels.height,
		d = imgPixels.data;
	var canvas = document.createElement('canvas'),
		ctx = canvas.getContext('2d'),
		newImgPixels = ctx.createImageData(w,h);
	for (var y = 1; y &lt; h-1; y++) {
			for (var x = 1; x &lt; w-1; x++) {
				for (var c = 0; c &lt; 3; c++) {
					/* RGB通道 */
					var i = (y*w + x)*4 + c;
					newImgPixels.data[i]=(matrix[0]*d[i-(w+1)*4] + matrix[1]*d[i-w*4] + matrix[2]*d[i-(w-1)*4]
										+ matrix[3]*d[i-4]       + matrix[4]*d[i]     + matrix[5]*d[i+4]
										+ matrix[6]*d[i+(w-1)*4] + matrix[7]*d[i+w*4] + matrix[8]*d[i+(w+1)*4])
										/ divisor + offset;
				}
				newImgPixels.data[(y*w + x)*4 + 3] = 255;
			}
		}
    return newImgPixels;
}
(function(){
	/* demo */
	var imgObj = new Image();
		imgObj.src = '/blog/resource/avatar/avatar_s.jpg';
	var embossing = {
		/* 浮雕效果 */
			matrix : [-2, -1, 0,
					  -1,  1, 1,
					   0,  1, 2],
			divisor: 1,
			offset : 0
		},
		edge = {
		/* 边缘检测 */
			matrix : [0, -1, 0,
					 -1,  4, -1,
					  0, -1, 0],
			divisor: 1,
			offset : 0
		},
		sharpening = {
		/* 锐化 */
			matrix : [ 0, -1, 0,
					  -1,  5, -1,
					  0,  -1, 0],
			divisor: 1,
			offset : 0
		},
		blur = {
		/* 基本模糊 */
			matrix : [0, 1, 0,
					  1, 1, 1,
					  0, 1, 0],
			divisor: 5,
			offset : 0
		},
		oneboys = {
		/* 胡诌的一个矩阵 */
			matrix : [ 0, 1, 4,
					  -1,  5, -1,
					  3,  -1, 2],
			divisor: 5,
			offset : 0
		};
	function process(obj,effect){
		var context = document.getElementById(obj).getContext('2d');
			context.drawImage(imgObj, 0, 0);
		var imgPixels = context.getImageData(0, 0, imgObj.width, imgObj.height);
		imgPixels = convolution(imgPixels, effect.matrix, effect.divisor, effect.offset)
		context.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
	}
	var canvas = document.getElementsByTagName('canvas');
	for(var i = 0, l = canvas.length; i &lt; l; i++ ){
		var loadObj = new Load(canvas[i]);
		(function(obj){
			obj.loading();
			imgObj.addEventListener('load',obj.loaded,false);
		})(loadObj);
	};
	imgObj.addEventListener('load',function(){
		process('canvas1',embossing);
		process('canvas2',edge);
		process('canvas3',sharpening);
		process('canvas4',blur);
		process('canvas5',oneboys);
	},false);
})()
/* 以下与示例代码无关 */
function Load(canvas){
	/* canvas Loading 效果 */
	var backCtx = canvas.getContext('2d');
		backWidth = canvas.width;
		backHeight = canvas.height;
	var drawIntervalID,
		spokes = 7;
	var	drawPad = document.createElement('canvas');
		drawPad.width = 30;
		drawPad.height = 30;
	var	drawCtx = drawPad.getContext('2d');
		drawCtx.translate(drawPad.width/2, drawPad.height/2);
		drawCtx.lineWidth = 5;
		drawCtx.lineCap = &quot;round&quot;;
		drawCtx.strokeStyle = &quot;rgba(0,0,0,0.1)&quot;;
		drawCtx.fillStyle = &quot;#fff&quot;;
	var draw = function(){
		drawCtx.fillRect(0,0, drawPad.width ,drawPad.height);
		drawCtx.rotate(Math.PI*2/spokes);
		for (var i=0; i&lt;spokes; i++) {
			drawCtx.rotate(Math.PI*2/spokes);
			drawCtx.beginPath();
			drawCtx.moveTo(0,8);
			drawCtx.lineTo(0,10);
			drawCtx.stroke();
		}
		backCtx.drawImage(drawPad,(backWidth - drawPad.width)/2, (backHeight - drawPad.height)/2);
	}
	this.loading = function(){
		 drawIntervalID = setInterval(draw,200);
	}
	this.loaded = function(){
		clearInterval(drawIntervalID);
		backCtx.clearRect((backWidth - drawPad.width)/2, (backHeight - drawPad.height)/2, drawPad.width ,drawPad.height);
	}
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_l_Cz3V');"/> </div>
</div>
<p>上面demo中卷积的实现函数来自于<a href="http://shawphy.com/2011/08/convolution-matrix-in-canvas.html">在HTML 5 的 Canvas 中应用卷积矩阵对图像处理</a></p>
<p>推荐一篇有趣的文章：<a href="http://www.douban.com/group/topic/15957958/">卷积的物理意义</a></p>


<p>Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2012/1140.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——1.引子'>canvas的像素级操作——1.引子</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1158.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——2.RGBA通道调色'>canvas的像素级操作——2.RGBA通道调色</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1179.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——4.关注性能'>canvas的像素级操作——4.关注性能</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2012/1165.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>canvas的像素级操作——2.RGBA通道调色</title>
		<link>http://www.cssass.com/blog/index.php/2012/1158.html</link>
		<comments>http://www.cssass.com/blog/index.php/2012/1158.html#comments</comments>
		<pubDate>Thu, 12 Jan 2012 06:08:50 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[data_URIs]]></category>
		<category><![CDATA[gray]]></category>
		<category><![CDATA[grayscale]]></category>
		<category><![CDATA[imageData]]></category>
		<category><![CDATA[rgba]]></category>
		<category><![CDATA[toDataURL]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=1158</guid>
		<description><![CDATA[在前文里我们已经提到了ImageData，它包含了三条数据{width,height,CanvasPixelArray}，而其中CanvasPixelArray存储了所有像素点的RGBA数据,第一个像素的red,green,blue,alpha通道值对应的就是CanvasPixelArray[0]-CanvasPixelArray[3]，如此按从左往右，由上往下依次存储。
我们通过修改像素点的rgb值就能改变像素的色相，修改alpha值就能改变像素的不透明度。


&#60;!DOCTYPE html&#62;
&#60;html&#62;
&#60;head&#62;
	&#60;meta charset=&#34;utf-8&#34;&#62;
	&#60;title&#62;ImageData通道操作&#60;/title&#62;
&#60;/head&#62;
&#60;body&#62;
&#60;canvas id=&#34;board&#34; width=&#34;1000&#34; height=&#34;500&#34;&#62;&#60;/canvas&#62;
&#60;script type=&#34;text/javascript&#34;&#62;
(function draw(){
	var canvas = document.getElementById('board');
	var context = canvas.getContext('2d');
	var imgPixels = false,
	w = 1000, h = 500,
	x = 0,  y = 0;
	imgPixels = context.createImageData(w, h);
	//imgPixels = context.getImageData(0, 0, w, h);
	var pix = imgPixels.data;
	for (var i = 0,n = pix.length; i &#60; n;) {
		/* 设置点的rgba值。ImageData.data数据是每4个值(分别是rgba)对应1个像素点 */
		pix[i  ] = i [...]


Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2012/1165.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——3.使用卷积矩阵'>canvas的像素级操作——3.使用卷积矩阵</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1179.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——4.关注性能'>canvas的像素级操作——4.关注性能</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1140.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——1.引子'>canvas的像素级操作——1.引子</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>在前文里我们已经提到了ImageData，它包含了三条数据{width,height,CanvasPixelArray}，而其中CanvasPixelArray存储了所有像素点的RGBA数据,第一个像素的red,green,blue,alpha通道值对应的就是CanvasPixelArray[0]-CanvasPixelArray[3]，如此按从左往右，由上往下依次存储。</p>
<p>我们通过修改像素点的rgb值就能改变像素的色相，修改alpha值就能改变像素的不透明度。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_481Btp" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;title&gt;ImageData通道操作&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;canvas id=&quot;board&quot; width=&quot;1000&quot; height=&quot;500&quot;&gt;&lt;/canvas&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
(function draw(){
	var canvas = document.getElementById('board');
	var context = canvas.getContext('2d');
	var imgPixels = false,
	w = 1000, h = 500,
	x = 0,  y = 0;
	imgPixels = context.createImageData(w, h);
	//imgPixels = context.getImageData(0, 0, w, h);
	var pix = imgPixels.data;
	for (var i = 0,n = pix.length; i &lt; n;) {
		/* 设置点的rgba值。ImageData.data数据是每4个值(分别是rgba)对应1个像素点 */
		pix[i  ] = i &amp; 0xff;
		pix[++i] = i &amp; 0xff;
		pix[++i] = i &amp; 0xff;
		pix[++i] = 255;
	}
	context.putImageData(imgPixels, x, y);
})()
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_481Btp');"/> </div>
</div>
<p>上面的demo中，我们创建了一个50*50像素点的ImageData，那么ImageData.data包含的数据应该是有 50 x 50 x 4 条。<br />
每12条一循环（即每隔两个像素），像素点的rgba值，没有经过设置的像素点，它们的缺省值是：[255,255,255,255]。</p>
<p>上例是，创建新的ImageData，相当于所有ImageData的初始值都是255。<br />
下面针对图像的ImageData进行计算设值，以此改变图像的色相。这是一个RGB彩色转gray的效果。（效果同ie的滤镜：filter:gray();已经最新出现的webkit滤镜：-webkit-filter: grayscale(1);）</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_VrAurl" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;title&gt;彩色图转灰度处理&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
鼠标过来&lt;br /&gt;
&lt;img id=&quot;imgObj&quot; src=&quot;/blog/resource/avatar/avatar_s.jpg&quot; width=&quot;200&quot; onmouseover=&quot;this.src=grayscale(this)&quot; /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function grayscale(img){
	/* 图像Grayscale处理函数 */
	var canvas = document.createElement('canvas');
	var ctx = canvas.getContext('2d');
	canvas.width = img.width;
	canvas.height = img.height;
	ctx.drawImage(img,0,0);
	var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
	for(var y = 0, h = imgPixels.height; y &lt; h; y++){
		for(var x = 0, w = imgPixels.width; x &lt; w; x++){
			var i = (y * 4) * w + x * 4;
			/* Gray = R*0.299 + G*0.587 + B*0.114 */
			var gray = 0.299*imgPixels.data[i] + 0.587*imgPixels.data[i + 1] + 0.114*imgPixels.data[i + 2];
			imgPixels.data[i] = gray;
			imgPixels.data[i + 1] = gray;
			imgPixels.data[i + 2] = gray;
		}
	}
	ctx.putImageData(imgPixels, 0, 0, 0, 0, canvas.width, canvas.height);
	return canvas.toDataURL();
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_VrAurl');"/> </div>
</div>
<p>上面没有对ImageData.data做一次循环，而是对ImageData.width,ImageData.height做了两次循环。<br />
两种循环其实是一样的。可以看下关系：ImageData.data.length = ImageData.width x ImageData.heigh x 4;<br />
data的序号 n = ( (y * ImageData.width) + x)  x 4 ;</p>
<p>而关于RGB转gray运算算法的知识，还可以参见这两篇文章：<a href="http://www.cnblogs.com/zyl910/archive/2006/05/22/2186658.html">彩色转灰度算法</a>，<a href="http://hi.baidu.com/rucio/blog/item/4e44d04f7149c83aafc3ab83.html">RGB向灰度转换的原理</a></p>
<p>在上例中，出现了一个canvas对象的新方法<a href="https://developer.mozilla.org/en/DOM/HTMLCanvasElement">toDataURL</a>,这个方法会将canvas对象转换成<a href="">data_URIs</a>,一个base64 strings。这样就能出现在image标签下中的src中了。</p>
<p>canvas提供像素级数据，为很多算法的应用提供了平台，实现photoshop中的众多神奇图像效果在前端都已成为可能。<br />
甚至于我们还能实现电影的蓝幕效果——针对video的帧,通过drawImage绘进canvas，再做rgba处理，将规定颜色的像素的alpha值设为0，就能使特定部分变成透明，进而实现视频合成。<a href="https://developer.mozilla.org/samples/video/chroma-key/index.xhtml">查看演示</a></p>


<p>Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2012/1165.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——3.使用卷积矩阵'>canvas的像素级操作——3.使用卷积矩阵</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1179.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——4.关注性能'>canvas的像素级操作——4.关注性能</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1140.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——1.引子'>canvas的像素级操作——1.引子</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2012/1158.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>canvas的像素级操作——1.引子</title>
		<link>http://www.cssass.com/blog/index.php/2012/1140.html</link>
		<comments>http://www.cssass.com/blog/index.php/2012/1140.html#comments</comments>
		<pubDate>Fri, 06 Jan 2012 06:31:36 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[CanvasPixelArray]]></category>
		<category><![CDATA[drawImage]]></category>
		<category><![CDATA[imageData]]></category>
		<category><![CDATA[Uint8ClampedArray]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=1140</guid>
		<description><![CDATA[本文是对《MDC的canvas经典教程辑和个人学习笔记》的补遗，也是canvas像素级操作系列文章的一个引子。
后面我会陆续发一些canvas素级操作的应用，特效方面的文章。
既然是引子，那就不能开门见山的介绍了，我们先讲讲如何复制canvas.
已知一个image对象，我们将其绘制进canvas的方法是什么？drawImage。（当然使用createPattern模板填充也是一个方法）。
那已知一个canvas对象，我们将其绘制进另一个canvas的方法呢？
答案还是drawImage，drawImage算是一个很辽阔的方法了，不仅可以绘image，也可以绘canvas对象，甚至还可以绘video的帧。
并且他拥有大量参数：(Image [, vXSrc] [, vYSrc] [, vWSrc] [, vHSrc], vXDest, vYDest [, vWDest] [, vHDest])，这个读者可以先不管，往下看。
那么，除了drawImage这个方法，还有没有其他方法呢——有，putImageData方法隆重登场。


&#60;!DOCTYPE html&#62;
&#60;html&#62;
&#60;head&#62;
&#60;title&#62;canvas绘制与复制及像素级复制&#60;/title&#62;
&#60;/head&#62;
&#60;body&#62;
&#60;p&#62;原图：imgObj&#60;br /&#62;
&#60;img id=&#34;imgObj&#34; src=&#34;/blog/resource/avatar/avatar_s.jpg&#34; width=&#34;200&#34; /&#62;
&#60;p&#62;canvas中绘制的图：MyCanvas&#60;br /&#62;
&#60;canvas id=&#34;MyCanvas&#34; width=&#34;200&#34; height=&#34;220&#34; &#62; &#60;/canvas&#62;
&#60;p&#62;从MyCanvas复制过来的图：YourCanvas&#60;br /&#62;
&#60;canvas id=&#34;YourCanvas&#34; width=&#34;200&#34; height=&#34;220&#34;&#62; &#60;/canvas&#62;
&#60;p&#62;从MyCanvas的ImageData复制来的图：GodCanvas （注意，这里只是为了引出canvas的像素级操作，通常像素级操作是很低效的）&#60;br /&#62;
&#60;canvas id=&#34;GodCanvas&#34; width=&#34;200&#34; height=&#34;220&#34;&#62; &#60;/canvas&#62;
&#60;/body&#62;
&#60;/html&#62;
&#60;script type=&#34;text/javascript&#34;&#62;
function draw(){
	/* 在canvas中绘制image */
	var canvas1 = document.getElementById(&#34;MyCanvas&#34;);
	var ctx1 = canvas1.getContext(&#34;2d&#34;);
		ctx1.drawImage(imgObj,0,0);
}
function clone(){
	/* 在canvas2中绘制canvas1 ——普通复制 */
	var origin = document.getElementById(&#34;MyCanvas&#34;);
	var [...]


Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2012/1165.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——3.使用卷积矩阵'>canvas的像素级操作——3.使用卷积矩阵</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1158.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——2.RGBA通道调色'>canvas的像素级操作——2.RGBA通道调色</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1179.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——4.关注性能'>canvas的像素级操作——4.关注性能</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>本文是对《<a href="http://www.cssass.com/blog/index.php/2010/772.html" target="_blank">MDC的canvas经典教程辑和个人学习笔记</a>》的补遗，也是canvas像素级操作系列文章的一个引子。<br />
后面我会陆续发一些canvas素级操作的应用，特效方面的文章。</p>
<p>既然是引子，那就不能开门见山的介绍了，我们先讲讲如何复制canvas.<br />
已知一个image对象，我们将其绘制进canvas的方法是什么？drawImage。（当然使用createPattern模板填充也是一个方法）。<br />
那已知一个canvas对象，我们将其绘制进另一个canvas的方法呢？<br />
答案还是drawImage，drawImage算是一个很辽阔的方法了，不仅可以绘image，也可以绘canvas对象，甚至还可以绘video的帧。</p>
<blockquote><p>并且他拥有大量参数：(Image [, vXSrc] [, vYSrc] [, vWSrc] [, vHSrc], vXDest, vYDest [, vWDest] [, vHDest])，这个读者可以先不管，往下看。</p></blockquote>
<p>那么，除了drawImage这个方法，还有没有其他方法呢——有，putImageData方法隆重登场。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_5KpCuk" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;canvas绘制与复制及像素级复制&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;原图：imgObj&lt;br /&gt;
&lt;img id=&quot;imgObj&quot; src=&quot;/blog/resource/avatar/avatar_s.jpg&quot; width=&quot;200&quot; /&gt;
&lt;p&gt;canvas中绘制的图：MyCanvas&lt;br /&gt;
&lt;canvas id=&quot;MyCanvas&quot; width=&quot;200&quot; height=&quot;220&quot; &gt; &lt;/canvas&gt;
&lt;p&gt;从MyCanvas复制过来的图：YourCanvas&lt;br /&gt;
&lt;canvas id=&quot;YourCanvas&quot; width=&quot;200&quot; height=&quot;220&quot;&gt; &lt;/canvas&gt;
&lt;p&gt;从MyCanvas的ImageData复制来的图：GodCanvas （注意，这里只是为了引出canvas的像素级操作，通常像素级操作是很低效的）&lt;br /&gt;
&lt;canvas id=&quot;GodCanvas&quot; width=&quot;200&quot; height=&quot;220&quot;&gt; &lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function draw(){
	/* 在canvas中绘制image */
	var canvas1 = document.getElementById(&quot;MyCanvas&quot;);
	var ctx1 = canvas1.getContext(&quot;2d&quot;);
		ctx1.drawImage(imgObj,0,0);
}
function clone(){
	/* 在canvas2中绘制canvas1 ——普通复制 */
	var origin = document.getElementById(&quot;MyCanvas&quot;);
	var canvas2 = document.getElementById(&quot;YourCanvas&quot;);
	var ctx2 = canvas2.getContext(&quot;2d&quot;);
		ctx2.drawImage(origin,0,0); //drawImage不仅可以绘image，也可以绘canvas对象，甚至还可以绘video的帧
}
function cloneData(canvasObj){
	/* 获取canvas1中的ImageData，在canvas3中输出 ——像素级复制 */
	var origin = document.getElementById(&quot;MyCanvas&quot;);
	var canvas3 = document.getElementById(&quot;GodCanvas&quot;);
	var ctx3 = canvas3.getContext(&quot;2d&quot;);
	var canvasCtx = origin.getContext(&quot;2d&quot;);
	var imagePix = canvasCtx.getImageData(0,0,origin.width,origin.height); // 获取canvas1绘图环境下的参数范围内的imageData。
		ctx3.putImageData(imagePix,0,0);    //putImageData输出图像
}
/* 以下与示例代码无关 */
function Load(canvas){
	/* canvas Loading 效果 */
	var backCtx = canvas.getContext('2d');
		backWidth = canvas.width;
		backHeight = canvas.height;
	var drawIntervalID,
		spokes = 7;
	var	drawPad = document.createElement('canvas');
		drawPad.width = 30;
		drawPad.height = 30;
	var	drawCtx = drawPad.getContext('2d');
		drawCtx.translate(drawPad.width/2, drawPad.height/2);
		drawCtx.lineWidth = 5;
		drawCtx.lineCap = &quot;round&quot;;
		drawCtx.strokeStyle = &quot;rgba(0,0,0,0.1)&quot;;
		drawCtx.fillStyle = &quot;#fff&quot;;
	var draw = function(){
		drawCtx.fillRect(0,0, drawPad.width ,drawPad.height);
		drawCtx.rotate(Math.PI*2/spokes);
		for (var i=0; i&lt;spokes; i++) {
			drawCtx.rotate(Math.PI*2/spokes);
			drawCtx.beginPath();
			drawCtx.moveTo(0,8);
			drawCtx.lineTo(0,10);
			drawCtx.stroke();
		}
		backCtx.drawImage(drawPad,(backWidth - drawPad.width)/2, (backHeight - drawPad.height)/2);
	}
	this.loading = function(){
		 drawIntervalID = setInterval(draw,200);
	}
	this.loaded = function(){
		clearInterval(drawIntervalID);
		backCtx.clearRect((backWidth - drawPad.width)/2, (backHeight - drawPad.height)/2, drawPad.width ,drawPad.height);
	}
}
var imgObj = document.getElementById(&quot;imgObj&quot;);
var canvas = document.getElementsByTagName('canvas');
for(var i = 0, l = canvas.length; i &lt; l; i++ ){
	var loadObj = new Load(canvas[i]);
	(function(obj){
		obj.loading();
		imgObj.addEventListener('load',obj.loaded,false);
	})(loadObj);
}
imgObj.addEventListener('load',function(){
	draw();
	clone();
	cloneData();
},false);
&lt;/script&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_5KpCuk');"/> </div>
</div>
<p>上面的cloneData方法就是通过将源canvas中像素数据ImageData，输出(putImageData)到新的canvas中，达到复制作用。</p>
<p>不过，我们在获取和输出ImageData的过程中，并没有对ImageData做过任何处理，而这个<a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata">ImageData</a>数据是包含{width,height,CanvasPixelArray},其中CanvasPixelArray包含了图像(canvas也可看做图像)的每一个像素的RGBA数据，可见中间的操作空间是很大的，以后我们会做重点讨论。</p>
<blockquote><p>
插注：CanvasPixelArray——在最新标准中已引入一个<dfn title="8-bit unsigned integer (clamped)"><code>Uint8ClampedArray</code></dfn>的<a href="http://www.khronos.org/registry/typedarray/specs/latest/">Typed Array</a>来替代 ，在各浏览器实现之后，将使得对ImageData的操作更快速更便捷。参考例子：<a href="http://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/">http://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/</a>
</p></blockquote>
<p>下面介绍一下像素操作的三个方法：</p>
<blockquote><p>createImageData();<br />
getImageData();<br />
putImageData();</p></blockquote>
<p>createImageData的参数是(w,h)可以新建一个W*H尺寸的新的ImageData【firefox3.5开始支持】，不过也可以使用参数(anotherImageData)来创建【firefox5开始支持】。</p>
<p>getImageData的参数（x,y,w,h）表示起点x,y,尺寸w,h。可以获取canvas.context中在参数范围内的ImageData。</p>
<p>putImageData的参数使用要着重要介绍下（和drawImage的参数可以触类旁通）：</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_C37r1c" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;putImageData的参数&lt;/title&gt;
&lt;style&gt;
	canvas{border:1px solid #ccc;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;canvas id=&quot;canvas1&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;&lt;/canvas&gt;
&lt;canvas id=&quot;canvas2&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;&lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
(function draw(){
	var canvas0 = document.createElement(&quot;canvas&quot;),
		ctx = canvas0.getContext(&quot;2d&quot;);
	var canvas1 = document.getElementById(&quot;canvas1&quot;),
		ctx1 = canvas1.getContext(&quot;2d&quot;);
	var canvas2 = document.getElementById(&quot;canvas2&quot;),
		ctx2 = canvas2.getContext(&quot;2d&quot;);
	var img = new Image();
	img.src=&quot;/blog/resource/avatar/avatar_s.jpg&quot;;
	img.onload=function(){
		canvas0.width = img.width;
		canvas0.height = img.height;
		ctx.drawImage(img,0,0);
		var imagePix = ctx.getImageData(0,0,canvas0.width,canvas0.height);
		/* putImageData参数(ImageData, dx, dy [, DirtyX] [, DirtyX] [, DirtyWidth] [, DirtyHeight]) */
		ctx1.putImageData(imagePix,30,30);  //imageData（包含了width,height,还有一个CanvasPixelArray）；dx, dy表示绘图起始位置
		ctx2.putImageData(imagePix,0,0,100,100,50,50); //后面四个可选参数表示可见区范围。缺省为：0,0,ImageData.width,ImageData.height
	}
})()
&lt;/script&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_C37r1c');"/> </div>
</div>
<p>putImageData参数有(ImageData, dx, dy [, DirtyX] [, DirtyX] [, DirtyWidth] [, DirtyHeight])</p>
<blockquote><p>imageData：包含了图像的width,height,还有一个CanvasPixelArray，前面已经提了。<br />
dx, dy：表示绘图起始位置。相对于canvas区域左上角。<br />
后面四个可选参数：表示可见区范围。相对于起绘点，即上面的参数dx,dy表示的点。缺省为0,0,ImageData.width,ImageData.height。
</p></blockquote>


<p>Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2012/1165.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——3.使用卷积矩阵'>canvas的像素级操作——3.使用卷积矩阵</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1158.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——2.RGBA通道调色'>canvas的像素级操作——2.RGBA通道调色</a></li><li><a href='http://www.cssass.com/blog/index.php/2012/1179.html' rel='bookmark' title='Permanent Link: canvas的像素级操作——4.关注性能'>canvas的像素级操作——4.关注性能</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2012/1140.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>获取元素尺寸和位置的两个冷门方法</title>
		<link>http://www.cssass.com/blog/index.php/2012/1136.html</link>
		<comments>http://www.cssass.com/blog/index.php/2012/1136.html#comments</comments>
		<pubDate>Wed, 04 Jan 2012 08:38:44 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[DOM]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[getBoundingClientRect]]></category>
		<category><![CDATA[offsetHeight]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=1136</guid>
		<description><![CDATA[获取元素的尺寸，似乎offsetWidth/Height就可以了，还需要什么方法吗？
的确，一般情况下，获取元素尺寸，用offsetWidth/Height就搞定了，但如果这个元素是display:none的呢？
试验一下就知道，none元素的尺寸是0。
所以需要我们下面的这个方法来获取。


&#60;!doctype html&#62;
&#60;html&#62;
&#60;head&#62;
&#60;meta charset=&#34;utf-8&#34; /&#62;
&#60;title&#62;获取display:none元素的size&#60;/title&#62;
&#60;style&#62;
body{color:#ccc;}
&#60;/style&#62;
&#60;/head&#62;
&#60;body&#62;
	&#60;div id=&#34;box&#34; style=&#34;width:100px;height:100px;padding:20px;border:10px solid #ccc;display:none;&#34;&#62;asdd&#60;/div&#62;
&#60;/body&#62;
&#60;script type=&#34;text/javascript&#34;&#62;
function $id(o){
	return document.getElementById(o);
}
var getSize = function(elem){
	if(elem.offsetWidth !== 0){
		/* 元素不是display:none的情况，这个时候是能得到尺寸的 */
		return {'width':elem.offsetWidth,
				'height':elem.offsetHeight
		};
	}
	var old = {};
	/* 将display:none元素设成visibility:hidden */
	var options = { position: &#34;absolute&#34;, visibility: &#34;hidden&#34;, display:&#34;block&#34; }
	for ( var name in options ) {
		old[ name ] = elem.style[ name ];
		elem.style[ name ] = options[ name ];
	}
	var temp = {'width':elem.offsetWidth,
				'height':elem.offsetHeight};
	for [...]


Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2011/1048.html' rel='bookmark' title='Permanent Link: 如何获取窗口高度、页面高度——解读各浏览器盒模型下的窗口、页面文档尺寸'>如何获取窗口高度、页面高度——解读各浏览器盒模型下的窗口、页面文档尺寸</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>获取元素的尺寸，似乎offsetWidth/Height就可以了，还需要什么方法吗？<br />
的确，一般情况下，获取元素尺寸，用offsetWidth/Height就搞定了，但如果这个元素是display:none的呢？<br />
试验一下就知道，none元素的尺寸是0。</p>
<p>所以需要我们下面的这个方法来获取。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_Qca8ik" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot; /&gt;
&lt;title&gt;获取display:none元素的size&lt;/title&gt;
&lt;style&gt;
body{color:#ccc;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id=&quot;box&quot; style=&quot;width:100px;height:100px;padding:20px;border:10px solid #ccc;display:none;&quot;&gt;asdd&lt;/div&gt;
&lt;/body&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function $id(o){
	return document.getElementById(o);
}
var getSize = function(elem){
	if(elem.offsetWidth !== 0){
		/* 元素不是display:none的情况，这个时候是能得到尺寸的 */
		return {'width':elem.offsetWidth,
				'height':elem.offsetHeight
		};
	}
	var old = {};
	/* 将display:none元素设成visibility:hidden */
	var options = { position: &quot;absolute&quot;, visibility: &quot;hidden&quot;, display:&quot;block&quot; }
	for ( var name in options ) {
		old[ name ] = elem.style[ name ];
		elem.style[ name ] = options[ name ];
	}
	var temp = {'width':elem.offsetWidth,
				'height':elem.offsetHeight};
	for ( var name in options ) {
		elem.style[ name ] = old[ name ];
	}
	return temp;
};
alert(getSize($id(&quot;box&quot;)).height)
&lt;/script&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_Qca8ik');"/> </div>
</div>
<p>第二个，获取元素的位置。<br />
或许你经常使用offsetLeft/Top来获取位置，不过offsetLeft/Top是相对 offsetParent的位置（在ie6，7下是相对直接父级的),并且在firefox下还有些<a href="http://www.cssass.com/blog/index.php/2011/917.html">小bug</a></p>
<p>下面这个方法提供获取元素相对于窗口（页面可视区）的距离。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_B8tkNo" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot; /&gt;
&lt;title&gt;元素相对窗口左上角的值（ie下没有width，height值）&lt;/title&gt;
&lt;style&gt;
*{padding:0;margin:0;}
#box{position:absolute;left:200px;width:100px;height:200px;border:5px solid #ccc;background:#eee;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id=&quot;box&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
	var box = document.getElementById(&quot;box&quot;);
	var pos = box.getBoundingClientRect();
	box.innerHTML = &quot;top:&quot;+pos.top +
					&quot;&lt;br /&gt;left:&quot;+pos.left +
					&quot;&lt;br /&gt;bottom:&quot;+pos.bottom +
					&quot;&lt;br /&gt;right:&quot;+pos.right +
					&quot;&lt;br /&gt;width:&quot;+pos.width +
					&quot;&lt;br /&gt;height:&quot;+pos.height
&lt;/script&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_B8tkNo');"/> </div>
</div>
<p>这个方法是由ie提出的，不过在其他浏览器吸收之后，还加了width，height两个值。</p>
<p>重复一下，这个方法是相对于页面窗口的，至于相对于整个页面文档的距离，那只需加上scrollTop这些值就行了，不做赘述。</p>


<p>Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2011/1048.html' rel='bookmark' title='Permanent Link: 如何获取窗口高度、页面高度——解读各浏览器盒模型下的窗口、页面文档尺寸'>如何获取窗口高度、页面高度——解读各浏览器盒模型下的窗口、页面文档尺寸</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2012/1136.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mouseenter/mouseleave事件和delegate方法的实现</title>
		<link>http://www.cssass.com/blog/index.php/2011/1127.html</link>
		<comments>http://www.cssass.com/blog/index.php/2011/1127.html#comments</comments>
		<pubDate>Sun, 18 Dec 2011 03:57:35 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[delegate]]></category>
		<category><![CDATA[mouseenter]]></category>
		<category><![CDATA[mouseleave]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=1127</guid>
		<description><![CDATA[众所周知，事件onmouseover和onmouseout有一个极其不好的问题，就是在绑定元素内部的子元素上滑动会反复触发事件，及执行绑定的方法。
而ie在很早的时候有提供了另一对事件：mouseenter和mouseleaver。顾名思义，就是只有当mouse滑进滑出绑定元素的时候，才会触发。
但是，这本来只是ie的私有属性，虽然已属于DOM3 Event草案当中，其他浏览器的支持率并不是很高，目前看来，Opera11.10已提供支持，而Firefox到10.0会提供支持，Webkit的暂无消息。
所以，如果想要用，我们得自己动手。
先搞一个通用的事件绑定函数：
var addEvent = function( target,type,fn ) {
&#160; &#160; if(target.addEventListener)
&#160; &#160; {
&#160; &#160; &#160; &#160; target.addEventListener(type,fn,false);
&#160; &#160; }
&#160; &#160; else&#160;if(target.attachEvent)
&#160; &#160; {
&#160; &#160; &#160; &#160; target.attachEvent(&#34;on&#34; + type,fn);
&#160; &#160; }
};
var&#160;removeEvent = function(target,type,fn ) {
&#160; &#160; if(target.addEventListener)
&#160; &#160; {
&#160; &#160; &#160; &#160; target.removeEventListener(type,fn,false);
&#160; &#160; }
&#160; &#160; else&#160;if(target.attachEvent)
&#160; &#160; {
&#160; &#160; &#160; &#160; target.detachEvent(&#34;on&#34; + type,fn);
&#160; &#160; [...]


No related posts. From:<a href=\]]></description>
			<content:encoded><![CDATA[<p>众所周知，事件onmouseover和onmouseout有一个极其不好的问题，就是在绑定元素内部的子元素上滑动会反复触发事件，及执行绑定的方法。</p>
<p>而ie在很早的时候有提供了另一对事件：mouseenter和mouseleaver。顾名思义，就是只有当mouse滑进滑出绑定元素的时候，才会触发。</p>
<p>但是，这本来只是ie的私有属性，虽然已属于DOM3 Event草案当中，其他浏览器的支持率并不是很高，目前看来，Opera11.10已提供支持，而Firefox到10.0会提供支持，Webkit的暂无消息。<br />
所以，如果想要用，我们得自己动手。</p>
<p>先搞一个通用的事件绑定函数：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #9c3;">var</span><span style="color: Gray;"> </span><span style="color: #39c;">addEvent</span><span style="color: Gray;"> = </span><span style="color: #9c3;">function</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: #39c;">target</span><span style="color: Gray;">,</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">target</span><span style="color: Gray;">.</span><span style="color: #39c;">addEventListener</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">target</span><span style="color: Gray;">.</span><span style="color: #39c;">addEventListener</span><span style="color: Olive;">(</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Gray;">,</span><span style="color: #9c3;">false</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">else</span><span style="color: Gray;">&nbsp;</span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">target</span><span style="color: Gray;">.</span><span style="color: #39c;">attachEvent</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">target</span><span style="color: Gray;">.</span><span style="color: #39c;">attachEvent</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">on</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> + </span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">removeEvent</span><span style="color: Gray;"> = </span><span style="color: #9c3;">function</span><span style="color: Olive;">(</span><span style="color: #39c;">target</span><span style="color: Gray;">,</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">target</span><span style="color: Gray;">.</span><span style="color: #39c;">addEventListener</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">target</span><span style="color: Gray;">.</span><span style="color: #39c;">removeEventListener</span><span style="color: Olive;">(</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Gray;">,</span><span style="color: #9c3;">false</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">else</span><span style="color: Gray;">&nbsp;</span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">target</span><span style="color: Gray;">.</span><span style="color: #39c;">attachEvent</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">target</span><span style="color: Gray;">.</span><span style="color: #39c;">detachEvent</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">on</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> + </span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li></ol></div>
<p>我们的mouseenter/leave是通过mouseover/out来实现的，只需屏蔽mouseover/out在元素内部触发时的事件传播即可。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_MIs4Gc" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot; /&gt;
&lt;title&gt;实现mouseenter、mouseleave事件&lt;/title&gt;
&lt;style&gt;
.outer{padding:50px;background:#aaa;}
.inner{height:100px;background:#eee;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;outer&quot; class=&quot;outer&quot;&gt;
	只有移进移出外框的时候才执行方法。对内框操作不执行。click点击解除绑定。
	&lt;div id=&quot;inner&quot; class=&quot;inner&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;script&gt;
var $id=function(o){return document.getElementById(o) || o;}
var events = {}
events._mouseFn ={}; //保存“onmouseenter”和“onmouseleave”所绑定的方法
events._mouseHandle = function(fn){
	/* 转换方法，符合条件时才会执行 */
	var func = function(event){
		var target = event.target;
		var parent = event.relatedTarget; //在onmouseover/out操作中，相关的另一个节点
		while( parent &amp;&amp; parent != this ){
			try{ parent = parent.parentNode; }
			catch(e){break;}
		}
		/* 只有当相关节点的父级不会是绑定的节点时（即二者不是父子的包含关系），才调用fn，否则不做处理 */
		( parent != this ) &amp;&amp; (fn.call(target,event));
	};
	return func;
}
events.addEvent = function( obj,type,fn ) {
	if(obj.addEventListener)
    {
		if(obj.onmouseenter !== undefined){
			//for opera11，firefox10。他们也支持“onmouseenter”和“onmouseleave”，可以直接绑定
			obj.addEventListener(type,fn,false);
			return ;
		}
		if(type==&quot;mouseenter&quot; || type==&quot;mouseleave&quot; ){
			var eType = (type==&quot;mouseenter&quot;) ? &quot;mouseover&quot; : &quot;mouseout&quot;;
			var fnNew = events._mouseHandle(fn);
			obj.addEventListener(eType,fnNew,false);
			 /* 将方法存入events._mouseFn，以便以后remove */
			if(!events._mouseFn[obj]) events._mouseFn[obj] = {};
			if(!events._mouseFn[obj][eType]) events._mouseFn[obj][eType] = {};
				events._mouseFn[obj][eType][fn] = fnNew;
		}else{
			obj.addEventListener(type,fn,false);
		}
    }else if(obj.attachEvent)
    {
		// for ie
        obj.attachEvent(&quot;on&quot; + type,fn);
    }
};
events.removeEvent = function(obj,type,fn ) {
    if(obj.addEventListener)
    {
		if(obj.onmouseenter !== undefined){
			obj.removeEventListener(type,fn,false);
			return ;
		}
		if(type==&quot;mouseenter&quot; || type==&quot;mouseleave&quot; ){
			var eType = (type==&quot;mouseenter&quot;) ? &quot;mouseover&quot; : &quot;mouseout&quot;;
			if(!events._mouseFn[obj][eType][fn]) return;
			obj.removeEventListener(eType,events._mouseFn[obj][eType][fn],false);
			events._mouseFn[obj][eType][fn] = null;
		}else{
			obj.removeEventListener(type,fn,false);
		}
    }
    else if(obj.attachEvent)
    {
        obj.detachEvent(&quot;on&quot; + type,fn);
    }
};
(function(){
	/* 这里是演示demo 绑定解除事件 */
	var outer = $id(&quot;outer&quot;),
		inner = $id(&quot;inner&quot;);
	events.addEvent(outer,&quot;mouseenter&quot;,add);
	events.addEvent(outer,&quot;mouseleave&quot;,add);
	events.addEvent(outer,&quot;click&quot;,remove);
	function add(){
		var e = arguments[0] || window.event;
		var target = e.srcElement || e.target;
		inner.innerHTML = target.id + ' ' + e.type;
	}
	function remove(){
		events.removeEvent(outer,&quot;mouseenter&quot;,add);
		events.removeEvent(outer,&quot;mouseleave&quot;,add)
		inner.innerHTML = &quot;click&quot;;
	}
})()
&lt;/script&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_MIs4Gc');"/> </div>
</div>
<p>为了解除绑定，我们设计了一个events._mouseFn来保存绑定的方法，在解除操作时读取对应的方法进行解绑。因为事件可以绑定多个方法，我们需要保存对应的方法，以便之后对应解除。<br />
当然如果这里如果按面向对象的思路实现，就可以各自保存，而不需要保持在同一个events._mouseFn对象下。但每绑定一个事件，都需实例化一个对象，显得很多余，所以不采用面向对象的模式。</p>
<p>接下来是文章的第二部分，我们来实现下jquery中提供的delegate方法。<br />
（delegate是live方法的扩展版。delegate是基于live的，live是基于bind的。在jquery1.7中又被封装进了on方法。1.7中的on方法是一个很辽阔的方法。其实封装的越厉害，效率就越差了，这也是为什么我们选择自己做简单封装的原因，而不是使用jquery已封装好的）。<br />
这个方法可以将想要绑定在子级元素上的事件方法，委托绑定在其父级上，用事件传播机制来触发执行。<br />
这么做的好处有：<br />
1：如果子级有n个并列元素需要绑定，绑子级需要绑n次，而将其绑定在父级上则只需绑定一次，这是很高效的。<br />
2：如果子级元素有动态增加的话，新增元素是没有绑定过任何事件方法的。而如果之前选择的是绑定其父级，就不会有这个问题。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_d4w8NU" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot; /&gt;
&lt;title&gt;delegate委托绑定事件方法的实现&lt;/title&gt;
&lt;style&gt;
.outer{padding:50px;background:#aaa;zoom:1;}
.inner{display:block;height:50px;margin:5px;background:#eee;border:1px solid #ccc;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;outer&quot; class=&quot;outer&quot;&gt;
	&lt;div id=&quot;message&quot;&gt;点击下面框体&lt;/div&gt;
	&lt;span class=&quot;inner&quot;&gt;1:&lt;/span&gt;
	&lt;span class=&quot;inner&quot;&gt;2:&lt;/span&gt;
	&lt;span class=&quot;inner&quot;&gt;3:&lt;/span&gt;
	&lt;span class=&quot;inner&quot;&gt;4:&lt;/span&gt;
	&lt;span class=&quot;inner&quot;&gt;5:&lt;/span&gt;
	&lt;div id=&quot;unbind&quot;&gt;点击解除绑定&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;script&gt;
var $id=function(o){return document.getElementById(o) || o;}
var events = {}
events._deleFn = {};
events._delegateHandle = function(obj,elm,fn){
	var func = function(event){
		var event = event || window.event;
		var target = event.srcElement || event.target;
		var parent = target;
		function contain(item,list){
			/* item对象是否就是list对象 */
			if(list.length == undefined ) return (item === list);
			/* item对象是否是list对象数组中的一个 */
			for(var i=0 ; i&lt;list.length; i++){
				if(item === list[i]) return true;
			}
			return false;
		}
		while(parent){
			/* 如果触发的元素，属于绑定元素(elm)的子级。才执行方法 */
			if(contain(parent,elm)){
				fn.call(obj,event);
				return;
			}
			parent = parent.parentNode;
		}
	};
	return func;
};
events.delegate = function(obj,elm,type,fn){
	/* 将绑定的方法存入events._deleFn，以便之后解绑操作 */
	var fnNew = events._delegateHandle(obj,elm,fn);
	if(!events._deleFn[elm]) events._deleFn[elm] = {};
	if(!events._deleFn[elm][type]) events._deleFn[elm][type] = {};
	events._deleFn[elm][type][fn] = fnNew;
	if(obj.addEventListener)
    {
		obj.addEventListener(type,fnNew,false);
    }else if(obj.attachEvent)
    {
        obj.attachEvent(&quot;on&quot; + type,fnNew);
    }
};
events.undelegate = function(obj,elm,type,fn){
	var fnNew = events._deleFn[elm][type][fn];
	if(!fnNew) return;
	if(obj.removeEventListener)
    {
		obj.removeEventListener(type,fnNew,false);
    }else if(obj.detachEvent)
    {
        obj.detachEvent(&quot;on&quot; + type,fnNew);
    }
	events._deleFn[elm][type][fn] = null;
};
(function(){
	/* 这里是演示demo*/
	var outer = $id(&quot;outer&quot;),
		inner = outer.getElementsByTagName(&quot;span&quot;),
		msg = $id(&quot;message&quot;),
		unbind = $id(&quot;unbind&quot;);
	var add = function(){
		var e = arguments[0] || window.event;
		var target = e.srcElement || e.target;
		msg.innerHTML =  target.innerHTML + ' ' + e.type;
	}
	function color(){
		msg.style.color = &quot;#c00&quot;
	}
	function remove(){
		events.undelegate(outer,inner,&quot;click&quot;,color);
		events.undelegate(outer,unbind,&quot;click&quot;,remove);
		msg.style.color = &quot;#000&quot;
		msg.innerHTML = &quot;已解除绑定color方法.add方法仍在&quot;;
	}
	events.delegate(outer,inner,&quot;click&quot;,add);
	events.delegate(outer,inner,&quot;click&quot;,color);
	events.delegate(outer,unbind,&quot;click&quot;,remove);
})()
&lt;/script&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_d4w8NU');"/> </div>
</div>
<p>这里的实现思路是这样的：如果触发事件的元素，是你想要绑定的元素的子级（当然他肯定已是委托实际绑定元素的子级），就执行绑定的事件方法，否则方法就不执行，看上去就像方法没绑定过一样。<br />
同实现onmouseenter一样，我们也设计了一个events._deleFn来用于后面的解绑方法undelegate的实现。</p>
<p>在使用delegate时，我们同样遇到了mouseover/out的问题。<br />
我们的解决方案是：不罗嗦，直接将mouseover/out处理成mouseenter/leave</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_YhWm0q" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot; /&gt;
&lt;title&gt;delegate委托绑定事件方法的实现&lt;/title&gt;
&lt;style&gt;
.outer{padding:50px;background:#aaa;zoom:1;}
.inner{display:block;height:50px;background:#eee;border:1px solid #ccc;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;outer&quot; class=&quot;outer&quot;&gt;
	&lt;div id=&quot;message&quot;&gt;划过下面框体&lt;/div&gt;
	&lt;span class=&quot;inner&quot;&gt;1:&lt;/span&gt;
	&lt;span class=&quot;inner&quot;&gt;2:&lt;/span&gt;
	&lt;span class=&quot;inner&quot;&gt;3:&lt;/span&gt;
	&lt;span class=&quot;inner&quot;&gt;4:&lt;/span&gt;
	&lt;span class=&quot;inner&quot;&gt;5:&lt;/span&gt;
	&lt;div id=&quot;unbind&quot;&gt;点击解除绑定&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;script&gt;
var $id=function(o){return document.getElementById(o) || o;}
var events = {}
events._deleFn = {};
events._delegateHandle = function(obj,elm,fn){
	var func = function(event){
		var event = event || window.event;
		var target = event.srcElement || event.target;
		var parent = target;
		function contain(item,list){
			/* item对象是否就是list对象 */
			if(list.length == undefined ) return (item === list);
			/* item对象是否是list对象数组中的一个 */
			for(var i=0 ; i&lt;list.length; i++){
				if(item === list[i]) return true;
			}
			return false;
		}
		while(parent){
			/* 如果触发的元素，属于绑定元素(elm)的子级。 */
			if(contain(parent,elm)){
				if(event.type == 'mouseover' || event.type == 'mouseout'){
					/*
					* 将mouseover/out直接处理成mouseenter/leave: 事件相关元素不属于绑定元素的子级，才绑定方法
					*/
					//事件相关元素。ie下使用toElement和fromElement，其他用relatedTarget。
					var related = event.relatedTarget || ((event.type == 'mouseout') ? event.toElement : event.fromElement);
					if(contain(target,elm) &amp;&amp; contain(related,elm)) {
						/* 如果，触发元素和相关元素都属于绑定元素(elm)。执行方法 */
						fn.call(obj,event);
						return;
					}
					while( related &amp;&amp; !contain(related,elm)){
						  related = related.parentNode;
					}
					/* 事件相关元素，不属于绑定元素(elm)的子级，执行方法  */
					!contain(related,elm) &amp;&amp; (fn.call(obj,event));
				}else{
					fn.call(obj,event);
				}
				return;
			}
			parent = parent.parentNode;
		}
	};
	return func;
};
events.delegate = function(obj,elm,type,fn){
	/* 将绑定的方法存入events._deleFn，以便之后解绑操作 */
	var fnNew = events._delegateHandle(obj,elm,fn);
	if(!events._deleFn[elm]) events._deleFn[elm] = {};
	if(!events._deleFn[elm][type]) events._deleFn[elm][type] = {};
	events._deleFn[elm][type][fn] = fnNew;
	if(obj.addEventListener)
    {
		obj.addEventListener(type,fnNew,false);
    }else if(obj.attachEvent)
    {
        obj.attachEvent(&quot;on&quot; + type,fnNew);
    }
};
events.undelegate = function(obj,elm,type,fn){
	var fnNew = events._deleFn[elm][type][fn];
	if(!fnNew) return;
	if(obj.removeEventListener)
    {
		obj.removeEventListener(type,fnNew,false);
    }else if(obj.detachEvent)
    {
        obj.detachEvent(&quot;on&quot; + type,fnNew);
    }
events._deleFn[elm][type][fn] = null;
};
(function(){
	/* 这里是演示demo*/
	var outer = $id(&quot;outer&quot;),
		inner = outer.getElementsByTagName(&quot;span&quot;),
		msg = $id(&quot;message&quot;),
		unbind = $id(&quot;unbind&quot;);
	events.delegate(outer,inner,&quot;mouseover&quot;,add);
	events.delegate(outer,inner,&quot;mouseout&quot;,add);
	events.delegate(outer,unbind,&quot;click&quot;,remove);
	function add(){
		var e = arguments[0] || window.event;
		var target = e.srcElement || e.target;
		msg.innerHTML =  target.innerHTML + ' ' + e.type;
	}
	function remove(){
		events.undelegate(outer,inner,&quot;mouseover&quot;,add);
		events.undelegate(outer,inner,&quot;mouseout&quot;,add);
		events.undelegate(outer,unbind,&quot;click&quot;,remove);
	}
})()
&lt;/script&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_YhWm0q');"/> </div>
</div>
<p>最后，整理一下，封装一个支持mouseenter 和 mouseleave事件，delegate方法 及其他们的解除绑定的方法的 功能函数库。</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #9c3;">var</span><span style="color: Gray;"> </span><span style="color: #39c;">events</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span></li>
<li><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_deleFn</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span><span style="color: Gray;">; </span><span style="color: #aaa;">//保存delegate所绑定的方法&nbsp; &nbsp; </span></li>
<li><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseFn</span><span style="color: Gray;"> =</span><span style="color: Olive;">{}</span><span style="color: Gray;">; </span><span style="color: #aaa;">//保存“onmouseenter”和“onmouseleave”所绑定的方法</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseHandle</span><span style="color: Gray;"> = </span><span style="color: #9c3;">function</span><span style="color: Olive;">(</span><span style="color: #39c;">fn</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #aaa;">/* 实现mouseenter/leave 的转换方法，符合条件时才会执行 */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">func</span><span style="color: Gray;"> = </span><span style="color: #9c3;">function</span><span style="color: Olive;">(</span><span style="color: #39c;">event</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">target</span><span style="color: Gray;"> = </span><span style="color: #39c;">event</span><span style="color: Gray;">.</span><span style="color: #39c;">target</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">parent</span><span style="color: Gray;"> = </span><span style="color: #39c;">event</span><span style="color: Gray;">.</span><span style="color: #39c;">relatedTarget</span><span style="color: Gray;">; </span><span style="color: #aaa;">//在onmouseover/out操作中，相关的另一个节点</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">while</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">parent</span><span style="color: Gray;"> &amp;&amp; </span><span style="color: #39c;">parent</span><span style="color: Gray;"> != </span><span style="color: #9c3;">this</span><span style="color: Gray;"> </span><span style="color: Olive;">){</span><span style="color: Gray;">&nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">try</span><span style="color: Olive;">{</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">parent</span><span style="color: Gray;"> = </span><span style="color: #39c;">parent</span><span style="color: Gray;">.</span><span style="color: #39c;">parentNode</span><span style="color: Gray;">; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">catch</span><span style="color: Olive;">(</span><span style="color: #39c;">e</span><span style="color: Olive;">){</span><span style="color: #9c3;">break</span><span style="color: Gray;">;</span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #aaa;">/* 只有当相关节点的父级不会是绑定的节点时（即二者不是父子的包含关系），才调用fn，否则不做处理 */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">parent</span><span style="color: Gray;"> != </span><span style="color: #9c3;">this</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> &amp;&amp; </span><span style="color: Olive;">(</span><span style="color: #39c;">fn</span><span style="color: Gray;">.</span><span style="color: #39c;">call</span><span style="color: Olive;">(</span><span style="color: #39c;">target</span><span style="color: Gray;">,</span><span style="color: #39c;">event</span><span style="color: Olive;">))</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">func</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_delegateHandle</span><span style="color: Gray;"> = </span><span style="color: #9c3;">function</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">elm</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #aaa;">/* 实现delegate 的转换方法，符合条件时才会执行 */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">func</span><span style="color: Gray;"> = </span><span style="color: #9c3;">function</span><span style="color: Olive;">(</span><span style="color: #39c;">event</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">event</span><span style="color: Gray;"> = </span><span style="color: #39c;">event</span><span style="color: Gray;"> || </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: #39c;">event</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">target</span><span style="color: Gray;"> = </span><span style="color: #39c;">event</span><span style="color: Gray;">.</span><span style="color: #39c;">srcElement</span><span style="color: Gray;"> || </span><span style="color: #39c;">event</span><span style="color: Gray;">.</span><span style="color: #39c;">target</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">parent</span><span style="color: Gray;"> = </span><span style="color: #39c;">target</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">function</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">contain</span><span style="color: Olive;">(</span><span style="color: #39c;">item</span><span style="color: Gray;">,</span><span style="color: #39c;">list</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #aaa;">/* item对象是否就是list对象 */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">list</span><span style="color: Gray;">.</span><span style="color: #39c;">length</span><span style="color: Gray;"> == </span><span style="color: #39c;">undefined</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: #9c3;">return</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: #39c;">item</span><span style="color: Gray;"> === </span><span style="color: #39c;">list</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #aaa;">/* item对象是否是list对象数组中的一个 */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">for</span><span style="color: Olive;">(</span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">i</span><span style="color: Gray;">=</span><span style="color: Maroon;">0</span><span style="color: Gray;"> ; </span><span style="color: #39c;">i</span><span style="color: Gray;">&lt;</span><span style="color: #39c;">list</span><span style="color: Gray;">.</span><span style="color: #39c;">length</span><span style="color: Gray;">; </span><span style="color: #39c;">i</span><span style="color: Gray;">++</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">item</span><span style="color: Gray;"> === </span><span style="color: #39c;">list</span><span style="color: Olive;">[</span><span style="color: #39c;">i</span><span style="color: Olive;">])</span><span style="color: Gray;">&nbsp;</span><span style="color: #9c3;">return</span><span style="color: Gray;"> </span><span style="color: #9c3;">true</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: #9c3;">false</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">while</span><span style="color: Olive;">(</span><span style="color: #39c;">parent</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #aaa;">/* 如果触发的元素，属于绑定元素(elm)的子级。 */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">contain</span><span style="color: Olive;">(</span><span style="color: #39c;">parent</span><span style="color: Gray;">,</span><span style="color: #39c;">elm</span><span style="color: Olive;">)){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">event</span><span style="color: Gray;">.</span><span style="color: #39c;">type</span><span style="color: Gray;"> == </span><span style="color: #8b0000;">'</span><span style="color: #E33100;">mouseover</span><span style="color: #8b0000;">'</span><span style="color: Gray;"> || </span><span style="color: #39c;">event</span><span style="color: Gray;">.</span><span style="color: #39c;">type</span><span style="color: Gray;"> == </span><span style="color: #8b0000;">'</span><span style="color: #E33100;">mouseout</span><span style="color: #8b0000;">'</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #aaa;">/* </span></li>
<li><span style="color: #aaa;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; * 将mouseover/out直接处理成mouseenter/leave: 事件相关元素不属于绑定元素的子级，才绑定方法 </span></li>
<li><span style="color: #aaa;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #aaa;">//事件相关元素。ie下使用toElement和fromElement，其他用relatedTarget。</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">related</span><span style="color: Gray;"> = </span><span style="color: #39c;">event</span><span style="color: Gray;">.</span><span style="color: #39c;">relatedTarget</span><span style="color: Gray;"> || </span><span style="color: Olive;">((</span><span style="color: #39c;">event</span><span style="color: Gray;">.</span><span style="color: #39c;">type</span><span style="color: Gray;"> == </span><span style="color: #8b0000;">'</span><span style="color: #E33100;">mouseout</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;"> ? </span><span style="color: #39c;">event</span><span style="color: Gray;">.</span><span style="color: #39c;">toElement</span><span style="color: Gray;"> : </span><span style="color: #39c;">event</span><span style="color: Gray;">.</span><span style="color: #39c;">fromElement</span><span style="color: Olive;">)</span><span style="color: Gray;">; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">contain</span><span style="color: Olive;">(</span><span style="color: #39c;">target</span><span style="color: Gray;">,</span><span style="color: #39c;">elm</span><span style="color: Olive;">)</span><span style="color: Gray;"> &amp;&amp; </span><span style="color: #39c;">contain</span><span style="color: Olive;">(</span><span style="color: #39c;">related</span><span style="color: Gray;">,</span><span style="color: #39c;">elm</span><span style="color: Olive;">))</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #aaa;">/* 如果，触发元素和相关元素都属于绑定元素(elm)。执行方法 */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">fn</span><span style="color: Gray;">.</span><span style="color: #39c;">call</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">event</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">return</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">while</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">related</span><span style="color: Gray;"> &amp;&amp; !</span><span style="color: #39c;">contain</span><span style="color: Olive;">(</span><span style="color: #39c;">related</span><span style="color: Gray;">,</span><span style="color: #39c;">elm</span><span style="color: Olive;">)){</span><span style="color: Gray;">&nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">related</span><span style="color: Gray;"> = </span><span style="color: #39c;">related</span><span style="color: Gray;">.</span><span style="color: #39c;">parentNode</span><span style="color: Gray;">; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #aaa;">/* 事件相关元素，不属于绑定元素(elm)的子级，执行方法&nbsp; */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !</span><span style="color: #39c;">contain</span><span style="color: Olive;">(</span><span style="color: #39c;">related</span><span style="color: Gray;">,</span><span style="color: #39c;">elm</span><span style="color: Olive;">)</span><span style="color: Gray;"> &amp;&amp; </span><span style="color: Olive;">(</span><span style="color: #39c;">fn</span><span style="color: Gray;">.</span><span style="color: #39c;">call</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">event</span><span style="color: Olive;">))</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: #9c3;">else</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">fn</span><span style="color: Gray;">.</span><span style="color: #39c;">call</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">event</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">return</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">parent</span><span style="color: Gray;"> = </span><span style="color: #39c;">parent</span><span style="color: Gray;">.</span><span style="color: #39c;">parentNode</span><span style="color: Gray;">;&nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">func</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">addEvent</span><span style="color: Gray;"> = </span><span style="color: #9c3;">function</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">addEventListener</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">{</span><span style="color: Gray;">&nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">onmouseenter</span><span style="color: Gray;"> !== </span><span style="color: #39c;">undefined</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #aaa;">//for opera11，firefox10。他们也支持“onmouseenter”和“onmouseleave”，可以直接绑定</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">addEventListener</span><span style="color: Olive;">(</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Gray;">,</span><span style="color: #9c3;">false</span><span style="color: Olive;">)</span><span style="color: Gray;">;&nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">return</span><span style="color: Gray;"> ;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">type</span><span style="color: Gray;">==</span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">mouseenter</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> || </span><span style="color: #39c;">type</span><span style="color: Gray;">==</span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">mouseleave</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">){</span><span style="color: Gray;">&nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">eType</span><span style="color: Gray;"> = </span><span style="color: Olive;">(</span><span style="color: #39c;">type</span><span style="color: Gray;">==</span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">mouseenter</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;"> ? </span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">mouseover</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> : </span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">mouseout</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">fnNew</span><span style="color: Gray;"> = </span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseHandle</span><span style="color: Olive;">(</span><span style="color: #39c;">fn</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">addEventListener</span><span style="color: Olive;">(</span><span style="color: #39c;">eType</span><span style="color: Gray;">,</span><span style="color: #39c;">fnNew</span><span style="color: Gray;">,</span><span style="color: #9c3;">false</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: #aaa;">/* 将方法存入events._mouseFn，以便以后remove */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseFn</span><span style="color: Olive;">[</span><span style="color: #39c;">obj</span><span style="color: Olive;">])</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseFn</span><span style="color: Olive;">[</span><span style="color: #39c;">obj</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseFn</span><span style="color: Olive;">[</span><span style="color: #39c;">obj</span><span style="color: Olive;">][</span><span style="color: #39c;">eType</span><span style="color: Olive;">])</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseFn</span><span style="color: Olive;">[</span><span style="color: #39c;">obj</span><span style="color: Olive;">][</span><span style="color: #39c;">eType</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseFn</span><span style="color: Olive;">[</span><span style="color: #39c;">obj</span><span style="color: Olive;">][</span><span style="color: #39c;">eType</span><span style="color: Olive;">][</span><span style="color: #39c;">fn</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: #39c;">fnNew</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: #9c3;">else</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">addEventListener</span><span style="color: Olive;">(</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Gray;">,</span><span style="color: #9c3;">false</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: #9c3;">else</span><span style="color: Gray;">&nbsp;</span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">attachEvent</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #aaa;">// for ie </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">attachEvent</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">on</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> + </span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">removeEvent</span><span style="color: Gray;"> = </span><span style="color: #9c3;">function</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">addEventListener</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">{</span><span style="color: Gray;">&nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">onmouseenter</span><span style="color: Gray;"> !== </span><span style="color: #39c;">undefined</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">removeEventListener</span><span style="color: Olive;">(</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Gray;">,</span><span style="color: #9c3;">false</span><span style="color: Olive;">)</span><span style="color: Gray;">;&nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">return</span><span style="color: Gray;"> ;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">type</span><span style="color: Gray;">==</span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">mouseenter</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> || </span><span style="color: #39c;">type</span><span style="color: Gray;">==</span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">mouseleave</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">){</span><span style="color: Gray;">&nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">eType</span><span style="color: Gray;"> = </span><span style="color: Olive;">(</span><span style="color: #39c;">type</span><span style="color: Gray;">==</span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">mouseenter</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;"> ? </span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">mouseover</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> : </span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">mouseout</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseFn</span><span style="color: Olive;">[</span><span style="color: #39c;">obj</span><span style="color: Olive;">][</span><span style="color: #39c;">eType</span><span style="color: Olive;">][</span><span style="color: #39c;">fn</span><span style="color: Olive;">])</span><span style="color: Gray;">&nbsp;</span><span style="color: #9c3;">return</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">removeEventListener</span><span style="color: Olive;">(</span><span style="color: #39c;">eType</span><span style="color: Gray;">,</span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseFn</span><span style="color: Olive;">[</span><span style="color: #39c;">obj</span><span style="color: Olive;">][</span><span style="color: #39c;">eType</span><span style="color: Olive;">][</span><span style="color: #39c;">fn</span><span style="color: Olive;">]</span><span style="color: Gray;">,</span><span style="color: #9c3;">false</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_mouseFn</span><span style="color: Olive;">[</span><span style="color: #39c;">obj</span><span style="color: Olive;">][</span><span style="color: #39c;">eType</span><span style="color: Olive;">][</span><span style="color: #39c;">fn</span><span style="color: Olive;">]</span><span style="color: Gray;">=</span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: #9c3;">else</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">removeEventListener</span><span style="color: Olive;">(</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Gray;">,</span><span style="color: #9c3;">false</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">else</span><span style="color: Gray;">&nbsp;</span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">attachEvent</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #39c;">obj</span><span style="color: Gray;">.</span><span style="color: #39c;">detachEvent</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: #E33100;">on</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> + </span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">delegate</span><span style="color: Gray;"> = </span><span style="color: #9c3;">function</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">elm</span><span style="color: Gray;">,</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">fnNew</span><span style="color: Gray;"> = </span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_delegateHandle</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">elm</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">addEvent</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fnNew</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #aaa;">/* 将绑定的方法存入events._deleFn，以便之后解绑操作 */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_deleFn</span><span style="color: Olive;">[</span><span style="color: #39c;">elm</span><span style="color: Olive;">])</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_deleFn</span><span style="color: Olive;">[</span><span style="color: #39c;">elm</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_deleFn</span><span style="color: Olive;">[</span><span style="color: #39c;">elm</span><span style="color: Olive;">][</span><span style="color: #39c;">type</span><span style="color: Olive;">])</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_deleFn</span><span style="color: Olive;">[</span><span style="color: #39c;">elm</span><span style="color: Olive;">][</span><span style="color: #39c;">type</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_deleFn</span><span style="color: Olive;">[</span><span style="color: #39c;">elm</span><span style="color: Olive;">][</span><span style="color: #39c;">type</span><span style="color: Olive;">][</span><span style="color: #39c;">fn</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: #39c;">fnNew</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">undelegate</span><span style="color: Gray;"> = </span><span style="color: #9c3;">function</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">elm</span><span style="color: Gray;">,</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fn</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: #39c;">fnNew</span><span style="color: Gray;"> = </span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_deleFn</span><span style="color: Olive;">[</span><span style="color: #39c;">elm</span><span style="color: Olive;">][</span><span style="color: #39c;">type</span><span style="color: Olive;">][</span><span style="color: #39c;">fn</span><span style="color: Olive;">]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #9c3;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: #39c;">fnNew</span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span><span style="color: #9c3;">return</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">removeEvent</span><span style="color: Olive;">(</span><span style="color: #39c;">obj</span><span style="color: Gray;">,</span><span style="color: #39c;">type</span><span style="color: Gray;">,</span><span style="color: #39c;">fnNew</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #39c;">events</span><span style="color: Gray;">.</span><span style="color: #39c;">_deleFn</span><span style="color: Olive;">[</span><span style="color: #39c;">elm</span><span style="color: Olive;">][</span><span style="color: #39c;">type</span><span style="color: Olive;">][</span><span style="color: #39c;">fn</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: #9c3;">null</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li></ol></div>


<p>No related posts. From:<a href=\]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2011/1127.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>瀑布流布局及扩展——格子块的智能堆砌</title>
		<link>http://www.cssass.com/blog/index.php/2011/1095.html</link>
		<comments>http://www.cssass.com/blog/index.php/2011/1095.html#comments</comments>
		<pubDate>Wed, 12 Oct 2011 14:32:45 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[交换]]></category>
		<category><![CDATA[布局]]></category>
		<category><![CDATA[拖动]]></category>
		<category><![CDATA[瀑布流]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=1095</guid>
		<description><![CDATA[图片分享网站Pinterest（beta），在不久前获得了2700$的投资，估值已超2亿元（据说现该公司团队有8人）。该网站的一大特色就是每一张分享的图片被拟作“Pin”被钉在页面上面，每一Pin依尺寸智能排列，同时滚动页面时异步加载新Pin，极具效果。这种创新模式被在国内也被广泛copy，其中最有前途的当属Mark之，以&#8221;Mark&#8221;代&#8221;Pin&#8221;,也算有些想法。
以下是利用豆瓣API数据做的效果：完整效果
部分代码：


&#60;!doctype html&#62;
&#60;html&#62;
&#60;head&#62;
&#60;meta charset=&#34;UTF-8&#34; /&#62;
&#60;title&#62;等宽格子堆砌&#60;/title&#62;
&#60;style&#62;
*{padding:0;margin:0;}
#wrap{position:relative;zoom:1;margin:0px auto;}
#wrap li{width:250px;float:left;list-style:none;}
.boxCont{position:relative;margin:15px;border:1px solid #ccc;background:#eee;
	background: -webkit-gradient(linear, 0% 20%, 0% 92%, from(#fff), to(#f3f3f3), color-stop(.1,#fff));
	background: -webkit-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
	background: -moz-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
	background: -o-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
	-webkit-border-radius: 60px / 5px;
	-moz-border-radius: 60px / 5px;
	border-radius:60px / 5px;
	-webkit-box-shadow: 0px 0px 35px rgba(0, 0, 0, 0.1) inset;
	-moz-box-shadow: 0px 0px [...]


Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2008/31.html' rel='bookmark' title='Permanent Link: 二列左列宽度固定，右列宽度自适应布局的四种方法'>二列左列宽度固定，右列宽度自适应布局的四种方法</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>图片分享网站<a href="http://pinterest.com/">Pinterest</a>（beta），在不久前获得了2700$的投资，估值已超2亿元（据说现该公司团队有8人）。该网站的一大特色就是每一张分享的图片被拟作“Pin”被钉在页面上面，每一Pin依尺寸智能排列，同时滚动页面时异步加载新Pin，极具效果。这种创新模式被在国内也被广泛copy，其中最有前途的当属<a href="http://www.markzhi.com" target="_blank">Mark之</a>，以&#8221;Mark&#8221;代&#8221;Pin&#8221;,也算有些想法。</p>
<p>以下是利用豆瓣API数据做的效果：<a href="http://www.cssass.com/blog/index.php/douban" target="_blank">完整效果</a><br />
部分代码：</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_e9bUmZ" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot; /&gt;
&lt;title&gt;等宽格子堆砌&lt;/title&gt;
&lt;style&gt;
*{padding:0;margin:0;}
#wrap{position:relative;zoom:1;margin:0px auto;}
#wrap li{width:250px;float:left;list-style:none;}
.boxCont{position:relative;margin:15px;border:1px solid #ccc;background:#eee;
	background: -webkit-gradient(linear, 0% 20%, 0% 92%, from(#fff), to(#f3f3f3), color-stop(.1,#fff));
	background: -webkit-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
	background: -moz-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
	background: -o-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
	-webkit-border-radius: 60px / 5px;
	-moz-border-radius: 60px / 5px;
	border-radius:60px / 5px;
	-webkit-box-shadow: 0px 0px 35px rgba(0, 0, 0, 0.1) inset;
	-moz-box-shadow: 0px 0px 35px rgba(0, 0, 0, 0.1) inset;
	box-shadow: 0px 0px 35px rgba(0, 0, 0, 0.1) inset;
}
.boxCont:before{
	content: '';
	width: 50px;
	height: 50px;
	top:0; right:0;
	position:absolute;
	display: inline-block;
	z-index:-1;
	-webkit-box-shadow: 10px -10px 8px rgba(0, 0, 0, 0.2);
	-moz-box-shadow: 10px -10px 8px rgba(0, 0, 0, 0.2);
	box-shadow: 10px -10px 8px rgba(0, 0, 0, 0.2);
	-webkit-transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
	-moz-transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
	-o-transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
	transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
}
.boxCont:after{
	content: '';
	width: 100px;
	height: 100px;
	top:0; left:0;
	position:absolute;
	z-index:-1;
	display: inline-block;
	-webkit-box-shadow: -10px -10px 10px rgba(0, 0, 0, 0.2);
	-moz-box-shadow: -10px -10px 10px rgba(0, 0, 0, 0.2);
	box-shadow: -10px -10px 10px rgba(0, 0, 0, 0.2);
	-webkit-transform: rotate(2deg) translate(20px,25px) skew(20deg);
	-moz-transform: rotate(2deg) translate(20px,25px) skew(20deg);
	-o-transform: rotate(2deg) translate(20px,25px) skew(20deg);
	transform: rotate(2deg) translate(20px,25px) skew(20deg);
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;ul id=&quot;wrap&quot;&gt;&lt;/ul&gt;
&lt;/body&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
var $id = function(o){ return document.getElementById(o) || o};
function sort(el){
	var h = [];
	var box = el.getElementsByTagName(&quot;li&quot;);
	var minH = box[0].offsetHeight,
		boxW = box[0].offsetWidth,
		boxH,
		n = document.documentElement.offsetWidth / boxW | 0;  //计算页面能排下多少Pin
	el.style.width = n * boxW + &quot;px&quot;;
	for(var i = 0; i &lt; box.length; i++) {
		boxh = box[i].offsetHeight; //获取每个Pin的高度
		if(i &lt; n) { //第一行Pin以浮动排列，不需绝对定位
			h[i] = boxh;
			box[i].style.position = '';
		} else {
			minH =  Math.min.apply({},h); //取得各列累计高度最低的一列
			minKey = getarraykey(h, minH);
			h[minKey] += boxh ; //加上新高度后更新高度值
			box[i].style.position = 'absolute';
			box[i].style.top = minH + 'px';
			box[i].style.left = (minKey * boxW) + 'px';
		}
	}
};
/* 返回数组中某一值的对应项数 */
function getarraykey(s, v) {
	for(k in s) {
		if(s[k] == v) {
			return k;
		}
	}
};
/* 随机创建Pin */
var pin = '';
for(i = 0; i &lt; 30; i++) {
	height = Math.floor(Math.random()*200 + 200);
	pin += '&lt;li&gt;&lt;div class=&quot;boxCont&quot; style=&quot;height:' + height + 'px;&quot;&gt;&lt;/div&gt;&lt;/li&gt;';
};
$id(&quot;wrap&quot;).innerHTML = pin;
window.onload = window.onresize = function() {
	sort($id(&quot;wrap&quot;));
};
&lt;/script&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_e9bUmZ');"/> </div>
</div>
<p>这种布局中虽然每个Pin的高度不尽相同，但是他们的宽度都是一样的。<br />
那么假如，很邪恶的提出一个要求，宽度也不尽相同，只是说宽高都按比例成倍增加，那还怎么排列呢？<br />
呵呵，如下：</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode__Aj2FR" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot; /&gt;
&lt;title&gt;宽高尺寸不同的格子堆砌&lt;/title&gt;
&lt;style&gt;
body{background:#F6F7F8;}
.myWidget{position:relative;overflow:hidden;zoom:1;margin:0 auto;}
.MBox{float:left;}
.widgetBox{position:relative;overflow:hidden;zoom:1;width:186px;height:166px;margin:6px;border:1px solid #E1E1E3;
	border-radius:10px;
	-moz-border-radius:10px;
	-webkit-border-radius:10px;
	box-shadow:2px 3px 5px #d3d3d3;
	-moz-box-shadow:2px 3px 5px #d3d3d3;
	-webkit-box-shadow:2px 3px 5px #d3d3d3;
	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#fefefe, endColorstr=#e0e0e2);
	background: linear-gradient(top, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2);
	background: -moz-linear-gradient(top, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2);
	background: -webkit-gradient(linear, 0 0, 0 100% , from(#fefefe),to(#e0e0e2));
	background: -webkit-linear-gradient(0 0, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2);
}
&lt;/style&gt;
&lt;script&gt;
var $id = function(o){ return document.getElementById(o) || o ;};
var getElementsByClassName = function(className,parent,tag) {
	parent = parent || document;
    if(parent.getElementsByClassName){
        return  parent.getElementsByClassName(className)
    }else{
        tag = tag || '*';
        var returnElements = []
        var els =  parent.getElementsByTagName(tag);
        className = className.replace(/\-/g, &quot;\\-&quot;);
        var pattern = new RegExp(&quot;(^|\\s)&quot;+className+&quot;(\\s|$)&quot;);
		var i = 0;
        while(i &lt; els.length){
            if (pattern.test(els[i].className) ) {
                returnElements.push(els[i]);
            }
			i++;
        }
        return returnElements;
    }
};
/* 格子排序 */
var box={};
box.gen={w:200,h:180};
box.init=function(el){
	box.size=[]; //格子,[1,2]表示1X2的大格子
	box.obj={};
	box.oArray=[];
	box.maxY=-1;
	box.mbox = getElementsByClassName(&quot;MBox&quot;,el,'div');
	box.row = document.documentElement.offsetWidth / box.gen.w &gt;&gt; 0;  //每行标准格数
	el.style.width = box.row * box.gen.w + &quot;px&quot;;
	var i = 0 , nx, ny;
	while( i &lt; this.mbox.length){
		if( getElementsByClassName(&quot;bigBox&quot;,this.mbox[i],'div').length &gt; 0 ){
			nx=Math.ceil(this.mbox[i].offsetWidth / this.gen.w);
			nx=(nx &gt; this.row) ? this.row : nx; //大小超出限制
			ny=Math.ceil(this.mbox[i].offsetHeight / this.gen.h);
			this.size.push([nx,ny]);
		}else{
			this.size.push(1);
		}
		i++;
	}
	box.sort(el);
};
box.setIfr=function(el){  //大格子初始化
 	var ifr = getElementsByClassName(&quot;bigBox&quot;,el,'div');;
   	if(ifr.length==0) return false;
	var i = 0, nx, ny, theifr;
	while(i &lt; ifr.length){
		theifr =  getElementsByClassName(&quot;innerBox&quot;,ifr[i],'div');
		nx=Math.ceil(theifr[0].offsetWidth / this.gen.w); //bigBox横向占的块数
		ny=Math.ceil(theifr[0].offsetHeight / this.gen.h);
		ifr[i].style.width = nx*this.gen.w-14 + 'px' ;
		ifr[i].style.height = ny*this.gen.h-14 + 'px' ;
		i++;
	}
};
box.sort=function(el){
	var y=0, x=0, temp={x:Infinity, y:Infinity}, flag=Infinity, name;
	for(var n=0; n &lt; this.size.length ; n++){
		if(flag == 0){
			x=temp.x;
			y=temp.y;
		}
		flag=flag-1;
		if(x&gt;box.row-1){ //换行
			x=0;
			y++;
		}
		name=x+'_'+y;  //对象属性名（反映占领的格子）
		if(this.hasN(name)) {  //判断属性名是否存在
			n--;
			x++;
			if(flag&lt;Infinity) flag=flag+1;
			continue;
		}
		if(!this.size[n].length){  //普通格子
			this.obj[name]=[x,y];  //项值（反映坐标值）
			x++;
		}
		else{  //大格子
			if(this.over(x,y,n)) {
				if(temp.y &gt; y){
					temp.y = y;
					temp.x = x;
				}
				if(temp.y &lt; Infinity){
					flag=1;
				}
				n--;
				x++;
				continue;
			}
			this.obj[name]=[x,y];
			this.apply(x,y,n);
			x+=this.size[n][0];
		}
		if(flag==-1) {
			flag = 	Infinity;
			temp.y = Infinity;
			temp.x = Infinity;
		}
		var h=this.size[n][1]-1 || 0;
		box.maxY=(box.maxY &gt; y+h)? box.maxY : y+h;
	}
	for(var i in this.obj){
		if(this.obj[i]===0 || !this.obj.hasOwnProperty(i)) continue;
		this.oArray.push(this.obj[i]);
	}
	box.put(el);
};
box.hasN=function(n){
	return n in this.obj;
};
box.over=function(x,y,n){  //判断是否会重叠
	var name;
	if(x+this.size[n][0] &gt; this.row) return true; //超出显示范围
	for(var k=1; k&lt;this.size[n][1];k++){
		name=x+'_'+(y-0+k);
		if(this.hasN(name)) {return true;}  //左侧一列有无重叠
	}
	for(k=1; k&lt;this.size[n][0];k++){
		name=(x-0+k)+'_'+y;
		if(this.hasN(name)) {return true;}  //上侧一行有无重叠
	}
	return false;
};
box.apply=function(x,y,n){  //大格子中多占的位置
	var posX=x, //大格子左上角位置
		posY=y;
	for(var t=0; t&lt;this.size[n][0]; t++) {
		for(var k=0; k&lt;this.size[n][1]; k++){
			name=(posX+t)+'_'+(posY+k);
			if(t==0 &amp;&amp; k==0) { continue; }
			this.obj[name]=0;   //多占的格子无坐标值
		}
	}
};
box.put=function(el){
	var x,y;
	for(var i =0;i&lt; this.oArray.length; i++){
		x=box.gen.w*this.oArray[i][0];
		y=box.gen.h*this.oArray[i][1];
		box.mbox[i].style.cssText = &quot;position:absolute;left:&quot;+ x +&quot;px;top:&quot; + y + &quot;px;&quot;;
	}
	el.style.height= box.gen.h*(box.maxY+1) +'px';
};
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;myWidget&quot; class=&quot;myWidget&quot;&gt;&lt;/div&gt;
&lt;script&gt;
var myWidget = $id(&quot;myWidget&quot;);
//创建随机内容
var content = '';
for(i = 0; i &lt; 30; i++) {
	if(!(Math.random()*3 &gt;&gt; 0)){
		height = Math.floor(Math.random()*200 + 100);
		width = Math.floor(Math.random()*200 + 100);
		content += '&lt;div class=&quot;MBox&quot;&gt;&lt;div class=&quot;widgetBox bigBox&quot;&gt;&lt;div style=&quot;width:' + width +'px;height:' + height +'px;margin:0 auto;&quot; class=&quot;innerBox&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;';
	}else{
		content += '&lt;div class=&quot;MBox&quot;&gt;&lt;div class=&quot;widgetBox&quot;&gt;&lt;/div&gt;&lt;/div&gt;';
	}
};
myWidget.innerHTML = content;
window.onload = function(){
	box.setIfr(myWidget);
	box.init(myWidget);
};
window.onresize = function(){
	box.init(myWidget);
};
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode__Aj2FR');"/> </div>
</div>
<p>现在这种布局已经不能叫瀑布流了，我们称之为格子块，格子块通过算法智能堆砌。</p>
<p>到最后，说点下睛也好，说添下足也好，我们再加一个拖动交换格子的效果。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_z2py3N" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot; /&gt;
&lt;title&gt;宽高尺寸不同的格子堆砌(可拖动换位)&lt;/title&gt;
&lt;style&gt;
body{background:#F6F7F8;}
.myWidget{position:relative;overflow:hidden;zoom:1;margin:0 auto;}
.MBox{float:left;}
.widgetBox{position:relative;overflow:hidden;zoom:1;width:186px;height:166px;margin:6px;border:1px solid #E1E1E3;cursor:move;
	border-radius:10px;
	-moz-border-radius:10px;
	-webkit-border-radius:10px;
	box-shadow:2px 3px 5px #d3d3d3;
	-moz-box-shadow:2px 3px 5px #d3d3d3;
	-webkit-box-shadow:2px 3px 5px #d3d3d3;
	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#fefefe, endColorstr=#e0e0e2);
	background: linear-gradient(top, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2);
	background: -moz-linear-gradient(top, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2);
	background: -webkit-gradient(linear, 0 0, 0 100% , from(#fefefe),to(#e0e0e2));
	background: -webkit-linear-gradient(0 0, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2);
}
&lt;/style&gt;
&lt;script&gt;
var $id = function(o){ return document.getElementById(o) || o ;};
var getElementsByClassName = function(className,parent,tag) {
	parent = parent || document;
    if(parent.getElementsByClassName){
        return  parent.getElementsByClassName(className)
    }else{
        tag = tag || '*';
        var returnElements = []
        var els =  parent.getElementsByTagName(tag);
        className = className.replace(/\-/g, &quot;\\-&quot;);
        var pattern = new RegExp(&quot;(^|\\s)&quot;+className+&quot;(\\s|$)&quot;);
		var i = 0;
        while(i &lt; els.length){
            if (pattern.test(els[i].className) ) {
                returnElements.push(els[i]);
            }
			i++;
        }
        return returnElements;
    }
};
var Util = new Object();
Util.getOffset = function (el, isLeft) {
    var retValue = 0;
   // while (el != null) {
        retValue += el[&quot;offset&quot; + (isLeft ? &quot;Left&quot; : &quot;Top&quot;)];
     //   el = el.offsetParent;
    //}
    return retValue;
};
Util.bindFunction = function (el, fucName) {
    return function () {
        return el[fucName].apply(el, arguments);
    };
};
Util.re_calcOff = function (el) {
    for (var i = 0; i &lt; Util.dragArray.length; i++) {
        var ele = Util.dragArray[i];
        ele.elm.pagePosLeft = Util.getOffset(ele.elm, true);
        ele.elm.pagePosTop = Util.getOffset(ele.elm, false);
    }
    var nextSib = el.elm.nextSibling;
    while (nextSib) {
        nextSib.pagePosTop -= el.elm.offsetHeight;
        nextSib = nextSib.nextSibling;
    }
};
Util.hide = function () {
    Util.rootElement.style.display = &quot;none&quot;;
};
Util.show = function () {
    Util.rootElement.style.display = &quot;&quot;;
};
ghostElement = null;
found = null;
getGhostElement = function () {
    if (!ghostElement) {
        ghostElement = document.createElement(&quot;DIV&quot;);
        ghostElement.className = &quot;MBox ghostBox&quot;;
    }
    return ghostElement;
};
function draggable(el) {
    this._dragStart = start_Drag;
    this._drag = when_Drag;
    this._dragEnd = end_Drag;
    this._afterDrag = after_Drag;
    this.isDragging = false;
    this.elm = el;
	this.hasIFrame = this.elm.getElementsByTagName(&quot;IFRAME&quot;).length &gt; 0;
        Drag.init(el, this.elm);
        this.elm.onDragStart = Util.bindFunction(this, &quot;_dragStart&quot;);
        this.elm.onDrag = Util.bindFunction(this, &quot;_drag&quot;);
        this.elm.onDragEnd = Util.bindFunction(this, &quot;_dragEnd&quot;);
};
function start_Drag() {
	Util.re_calcOff(this);
    this.origNextSibling = this.elm.nextSibling;
    var _ghostElement = getGhostElement();
    var offH = this.elm.offsetHeight;
    var offW = this.elm.offsetWidth;
    var offLeft = Util.getOffset(this.elm, true);
    var offTop = Util.getOffset(this.elm, false);
   // Util.hide();
   //this.elm.parentNode.getElementsByTagName('iframe')[0].style.visibility = 'hidden';
    this.elm.style.width = offW + &quot;px&quot;;
    _ghostElement.style.height = offH + &quot;px&quot;;
    _ghostElement.style.width = offW + &quot;px&quot;;
    this.elm.parentNode.insertBefore(_ghostElement, this.elm.nextSibling);
    this.elm.style.position = &quot;absolute&quot;;
    this.elm.style.zIndex = 100;
    this.elm.style.left = offLeft + &quot;px&quot;;
    this.elm.style.top = offTop + &quot;px&quot;;
    //Util.show();
    this.isDragging = false;
    return false;
};
function when_Drag(clientX, clientY) {
	    if (!this.isDragging) {
        this.elm.style.filter = &quot;alpha(opacity=70)&quot;;
        this.elm.style.opacity = 0.7;
        this.isDragging = true;
    }
    found = null;
    var max_distance = 100000000;
    for (var i = 0; i &lt; Util.dragArray.length; i++) {
        var ele = Util.dragArray[i];
        var distance = Math.sqrt(Math.pow(clientX - ele.elm.pagePosLeft, 2) + Math.pow(clientY -  ele.elm.offsetTop, 2));
        if (ele == this) {
            continue;
        }
        if (isNaN(distance)) {
            continue;
        }
        if (distance &lt; max_distance) {
            max_distance = distance;
           	 found = ele;
        }
    };
    var _ghostElement = getGhostElement();
    if (found != null) {
    	if(this.elm.pagePosLeft &lt; clientX){
    		found.elm.parentNode.insertBefore(_ghostElement, found.elm.nextSibling);
    	}else{
    		found.elm.parentNode.insertBefore(_ghostElement, found.elm);
    	}
    };
};
function end_Drag() {
	//this.elm.parentNode.getElementsByTagName('iframe')[0].style.visibility = 'visible';
	if (this._afterDrag()) {
	}
	return true;
};
function after_Drag() {
    var returnValue = false;
   // Util.hide();
    this.elm.style.position = &quot;&quot;;
    this.elm.style.width = &quot;&quot;;
    this.elm.style.zIndex = &quot;&quot;;
    this.elm.style.filter = &quot;&quot;;
    this.elm.style.opacity = &quot;&quot;;
    var ele = getGhostElement();
    if (ele.nextSibling != this.origNextSibling) {
    	ele.parentNode.insertBefore(found.elm, this.elm);
    	ele.parentNode.insertBefore(this.elm, ele.nextSibling);
        returnValue = true;
    }
    ele.parentNode.removeChild(ele);
    //Util.show();
   box.init(Util.rootElement);
   return returnValue;
};
var Drag = {
		obj:null,
		init:function (elementHeader, element) {
		    	elementHeader.onmousedown = Drag.start;
    		    elementHeader.obj = element;
		    if (isNaN(parseInt(element.style.left))) {
				element.style.left = &quot;0px&quot;;
			}
			if (isNaN(parseInt(element.style.top))) {
				element.style.top = &quot;0px&quot;;
			}
			element.onDragStart = new Function();
			element.onDragEnd = new Function();
			element.onDrag = new Function();
		},
		start:function (event) {
	    var element = Drag.obj = this.obj;
		    event = Drag.fixE(event);
		    if (event.which != 1) {
	    		return true;
    		}
    		element.onDragStart();
		    element.lastMouseX = event.clientX;
			element.lastMouseY = event.clientY;
		    document.onmouseup = Drag.end;
			document.onmousemove = Drag.drag;
			return false;
		},
		drag:function (event) {
			event = Drag.fixE(event);
		    if (event.which == 0) {
	    		return Drag.end();
    		}
    		var element = Drag.obj;
		    var _clientX = event.clientY;
			var _clientY = event.clientX;
		    if (element.lastMouseX == _clientY &amp;&amp; element.lastMouseY == _clientX) {
				return false;
			};
			if(_clientX + document.documentElement.scrollTop + document.body.scrollTop &lt; 0 ||  _clientX &gt; document.documentElement.offsetHeight){
				return false;
			};
			var sTo=0;
			if( _clientX &lt; 0 ){
				sTo=_clientX;
			};
			if((_clientX - document.documentElement.clientHeight) &gt; 0){
		    	sTo=_clientX - document.documentElement.clientHeight;
			};
			window.scrollBy(0,sTo);
		    var _lastX = parseInt(element.style.top);
			var _lastY = parseInt(element.style.left);
		    var newX, newY;
		    newX = _lastY + _clientY - element.lastMouseX;
			newY = _lastX + _clientX - element.lastMouseY;
		    element.style.left = newX  + &quot;px&quot;;
			element.style.top = newY + sTo + &quot;px&quot;;
		    element.lastMouseX = _clientY;
			element.lastMouseY = _clientX;
		    element.onDrag(newX, newY);
			return false;
		},
		end:function (event) {
			event = Drag.fixE(event);
		    document.onmousemove = null;
			document.onmouseup = null;
		    var _onDragEndFuc = Drag.obj.onDragEnd();
		    Drag.obj = null;
	    return _onDragEndFuc;
		},
		fixE:function (ig_) {
	    if (typeof ig_ == &quot;undefined&quot;) {
	        ig_ = window.event;
	    }
	    if (typeof ig_.layerX == &quot;undefined&quot;) {
	        ig_.layerX = ig_.offsetX;
	    }
	    if (typeof ig_.layerY == &quot;undefined&quot;) {
	        ig_.layerY = ig_.offsetY;
	    }
	    if (typeof ig_.which == &quot;undefined&quot;) {
	        ig_.which = ig_.button;
	    }
    	return ig_;
	}
};
var initDrag = function (el) {
	Util.rootElement = el;
    Util.elem = Util.rootElement.children;
    Util.dragArray = new Array();
    var counter = 0;
    for (var i = 0; i &lt; Util.elem.length; i++) {
    	var elem = Util.elem[i];
		Util.dragArray[counter] = new draggable(elem);
		counter++;
    };
	box.setIfr(Util.rootElement);
	box.init(Util.rootElement);
};
/* 格子排序 */
var box={};
box.gen={w:200,h:180};
box.init=function(el){
	box.size=[]; //格子,[1,2]表示1X2的大格子
	box.obj={};
	box.oArray=[];
	box.maxY=-1;
	box.mbox = getElementsByClassName(&quot;MBox&quot;,el,'div');
	box.row = document.documentElement.offsetWidth / box.gen.w &gt;&gt; 0;  //每行标准格数
	el.style.width = box.row * box.gen.w + &quot;px&quot;;
	var i = 0 , nx, ny;
	while( i &lt; this.mbox.length){
		if( getElementsByClassName(&quot;bigBox&quot;,this.mbox[i],'div').length &gt; 0 ){
			nx=Math.ceil(this.mbox[i].offsetWidth / this.gen.w);
			nx=(nx &gt; this.row) ? this.row : nx; //大小超出限制
			ny=Math.ceil(this.mbox[i].offsetHeight / this.gen.h);
			this.size.push([nx,ny]);
		}else{
			this.size.push(1);
		}
		i++;
	}
	box.sort(el);
};
box.setIfr=function(el){  //大格子初始化
 	var ifr = getElementsByClassName(&quot;bigBox&quot;,el,'div');;
   	if(ifr.length==0) return false;
	var i = 0, nx, ny, theifr;
	while(i &lt; ifr.length){
		theifr =  getElementsByClassName(&quot;innerBox&quot;,ifr[i],'div');
		nx=Math.ceil(theifr[0].offsetWidth / this.gen.w); //bigBox横向占的块数
		ny=Math.ceil(theifr[0].offsetHeight / this.gen.h);
		ifr[i].style.width = nx*this.gen.w-14 + 'px' ;
		ifr[i].style.height = ny*this.gen.h-14 + 'px' ;
		i++;
	}
};
box.sort=function(el){
	var y=0, x=0, temp={x:Infinity, y:Infinity}, flag=Infinity, name;
	for(var n=0; n &lt; this.size.length ; n++){
		if(flag == 0){
			x=temp.x;
			y=temp.y;
		}
		flag=flag-1;
		if(x &gt; box.row-1){ //换行
			x=0;
			y++;
		}
		name=x+'_'+y;  //对象属性名（反映占领的格子）
		if(this.hasN(name)) {  //判断属性名是否存在
			n--;
			x++;
			if(flag&lt;Infinity) flag=flag+1;
			continue;
		}
		if(!this.size[n].length){  //普通格子
			this.obj[name]=[x,y];  //（反映坐标值）
			x++;
		}
		else{  //大格子
			if(this.over(x,y,n)) {
				if(temp.y &gt; y){
					temp.y = y;
					temp.x = x;
				}
				if(temp.y &lt; Infinity){
					flag=1;
				}
				n--;
				x++;
				continue;
			}
			this.obj[name]=[x,y];
			this.apply(x,y,n);
			x+=this.size[n][0];
		}
		if(flag==-1) {
			flag = 	Infinity;
			temp.y = Infinity;
			temp.x = Infinity;
		}
		var h=this.size[n][1]-1 || 0;
		box.maxY=(box.maxY &gt; y+h)? box.maxY : y+h;
	}
	for(var i in this.obj){
		if(this.obj[i]===0 || !this.obj.hasOwnProperty(i)) continue;
		this.oArray.push(this.obj[i]);
	}
	box.put(el);
};
box.hasN=function(n){
	return n in this.obj;
};
box.over=function(x,y,n){  //判断是否会重叠
	var name;
	if(x+this.size[n][0] &gt; this.row) return true; //超出显示范围
	for(var k=1; k&lt;this.size[n][1];k++){
		name=x+'_'+(y-0+k);
		if(this.hasN(name)) {return true;}  //左侧一列有无重叠
	}
	for(k=1; k&lt;this.size[n][0];k++){
		name=(x-0+k)+'_'+y;
		if(this.hasN(name)) {return true;}  //上侧一行有无重叠
	}
	return false;
};
box.apply=function(x,y,n){  //大格子中多占的位置
	var posX=x, //大格子左上角位置
		posY=y;
	for(var t=0; t&lt;this.size[n][0]; t++) {
		for(var k=0; k&lt;this.size[n][1]; k++){
			name=(posX+t)+'_'+(posY+k);
			if(t==0 &amp;&amp; k==0) { continue; }
			this.obj[name]=0;   //多占的格子无坐标值
		}
	}
};
box.put=function(el){
	var x,y;
	for(var i =0;i&lt; this.oArray.length; i++){
		x=box.gen.w*this.oArray[i][0];
		y=box.gen.h*this.oArray[i][1];
		box.mbox[i].style.cssText = &quot;position:absolute;left:&quot;+ x +&quot;px;top:&quot; + y + &quot;px;&quot;;
	};
	el.style.height= box.gen.h*(box.maxY+1) +'px';
};
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;myWidget&quot; class=&quot;myWidget&quot;&gt;&lt;/div&gt;
&lt;script&gt;
var myWidget = $id(&quot;myWidget&quot;);
//创建随机内容
var content = '';
for(i = 0; i &lt; 20; i++) {
	if(!(Math.random()*5 &gt;&gt; 0)){
		height = Math.floor(Math.random()*200 + 100);
		width = Math.floor(Math.random()*200 + 100);
		content += '&lt;div class=&quot;MBox&quot;&gt;&lt;div class=&quot;widgetBox bigBox&quot;&gt;&lt;div style=&quot;width:' + width +'px;height:' + height +'px;margin:0 auto;&quot; class=&quot;innerBox&quot;&gt;'+ i +'&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;';
	}else{
		content += '&lt;div class=&quot;MBox&quot;&gt;&lt;div class=&quot;widgetBox&quot;&gt;'+ i +'&lt;/div&gt;&lt;/div&gt;';
	}
};
myWidget.innerHTML = content;
//绑定拖动元素
initDrag(myWidget);
window.onresize = function(){box.init(myWidget)};
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_z2py3N');"/> </div>
</div>


<p>Related posts:<ol><li><a href='http://www.cssass.com/blog/index.php/2008/31.html' rel='bookmark' title='Permanent Link: 二列左列宽度固定，右列宽度自适应布局的四种方法'>二列左列宽度固定，右列宽度自适应布局的四种方法</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2011/1095.html/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Typing&#8230;</title>
		<link>http://www.cssass.com/blog/index.php/2011/1086.html</link>
		<comments>http://www.cssass.com/blog/index.php/2011/1086.html#comments</comments>
		<pubDate>Thu, 28 Jul 2011 13:21:38 +0000</pubDate>
		<dc:creator>ONEBOYS</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[心形]]></category>
		<category><![CDATA[打字效果]]></category>

		<guid isPermaLink="false">http://www.cssass.com/blog/?p=1086</guid>
		<description><![CDATA[最近一个多月都比较忙，没什么时间精力更新blog，现在终于闲下来了。
之前有个朋友发给我一个打字机的效果，蛮有感觉的，不过那是用VBscript写的&#8230;
而下面的这个demo里除了打字的效果，还结合了以前这个：我是谁里的效果。
至于里面的心形图案，是我一个一个取出坐标得到的，如果你对心形图案还有兴趣，还可以看看这篇文章笛卡尔情书的秘密。


&#60;!DOCTYPE html&#62;
&#60;html&#62;
&#60;head&#62;
&#60;meta charset=&#34;UTF-8&#34; /&#62;
&#60;title&#62;Typing...&#60;/title&#62;
&#60;style type=&#34;text/css&#34;&#62;
*{padding:0;margin:0;}
body
{font-family:'MS Gothic';line-height: 1.8;font-size: 15px;color: #444;padding:10px;}
#avatar{position:relative;width:800px;word-wrap:break-word;margin:0 auto;}
b{font-weight:normal;display:none;}
&#60;/style&#62;
&#60;/head&#62;
&#60;body&#62;
&#60;div id=&#34;avatar&#34;&#62;
&#60;p&#62;我们都一样&#60;/p&#62;
&#60;p&#62;推开窗看见星星,依然守在夜空中。&#60;/p&#62;
&#60;p&#62;心中不免多了些,暖暖的感动。&#60;/p&#62;
&#60;p&#62;一闪一闪的光,努力把黑夜点亮，气氛如此安详。&#60;/p&#62;
&#60;p&#62;你在我的生命中,是那最闪亮的星。&#60;/p&#62;
&#60;p&#62;一直在无声夜空,守护着我们的梦。&#60;/p&#62;
&#60;p&#62;这世界那么大,我的爱只想要你懂。&#60;/p&#62;
&#60;p&#62;陪伴我孤寂旅程。&#60;/p&#62;
&#60;p&#62;你知道我的梦,你知道我的痛。&#60;/p&#62;
&#60;p&#62;你知道我们感受都相同。&#60;/p&#62;
&#60;p&#62;就算有再大的风,也挡不住勇敢的冲动。&#60;/p&#62;
&#60;p&#62;努力的往前飞,再累也无所谓。&#60;/p&#62;
&#60;p&#62;黑夜过后的光芒有多美。&#60;/p&#62;
&#60;p&#62;分享你我的力量,就能把对方的路照亮。&#60;/p&#62;
&#60;p&#62;我想我们都一样,渴望梦想的光芒。&#60;/p&#62;
&#60;p&#62;这一路喜悦彷徨,不要轻易说失望。&#60;/p&#62;
&#60;p&#62;回到最初时光,当时的你多么坚强。&#60;/p&#62;
&#60;p&#62;那鼓励让我难忘。&#60;/p&#62;
&#60;p&#62;你知道我的梦,你知道我的痛。&#60;/p&#62;
&#60;p&#62;你知道我们感受都相同。&#60;/p&#62;
&#60;p&#62;就算有再大的风,也挡不住勇敢的冲动。&#60;/p&#62;
&#60;p&#62;努力的往前飞,再累也无所谓。&#60;/p&#62;
&#60;p&#62;黑夜过后的光芒有多美。&#60;/p&#62;
&#60;p&#62;分享你我的力量,就能把对方的路照亮。&#60;/p&#62;
&#60;/div&#62;
&#60;span id=&#34;cursor&#34;&#62;&#124;&#60;/span&#62;
&#60;embed name=&#34;我们都一样&#34; pluginspage=&#34;http://www.microsoft.com/Windows/MediaPlayer&#34; src=&#34;http://www.cssass.com/blog/resource/bgsound/bgsound.mp3&#34;
width=&#34;1&#34; height=&#34;1&#34; type=&#34;application/x-mplayer2&#34; autostart=&#34;1&#34;  loop=&#34;1&#34; volume=&#34;50&#34;&#62;&#60;/embed&#62;
&#60;script&#62;
var $id=function(o){return document.getElementById(o) &#124;&#124; o};
var g=$id('avatar');
var cursor=$id(&#34;cursor&#34;);
var init=function ()
{
	var n=0, l=g.innerHTML, s='';
	while (n&#60;l.length)
	{
		var r=l.charAt(n);
		if (r==' ') { s+=r; n++}
		if (r=='&#60;') while (l.charAt(n-1)!='&#62;') s+=l.charAt(n++);
		s+='&#60;b&#62;'+l.charAt(n++)+'&#60;/b&#62;';
	}
	g.innerHTML=s;
};
var Wt={};
Wt.n = 0,
Wt.i = 0;
Wt.p = g.getElementsByTagName(&#34;p&#34;);
Wt.loop=function(){
	if( Wt.n &#62;= Wt.p.length ) {
		window.scrollTo(0,0);
		pos();
		anim();
		cursor.innerHTML='';
		g.onclick=anim;
		return [...]


No related posts. From:<a href=\]]></description>
			<content:encoded><![CDATA[<p>最近一个多月都比较忙，没什么时间精力更新blog，现在终于闲下来了。<br />
之前有个朋友发给我一个打字机的效果，蛮有感觉的，不过那是用VBscript写的&#8230;<br />
而下面的这个demo里除了打字的效果，还结合了以前这个：<a href="http://www.cssass.com/blog/index.php/2010/903.html">我是谁</a>里的效果。<br />
至于里面的心形图案，是我一个一个取出坐标得到的，如果你对心形图案还有兴趣，还可以看看这篇文章<a href="http://www.cssass.com/blog/index.php/2010/808.html">笛卡尔情书的秘密</a>。</p>
<div class="runcode">
<div><span class='areaBox' onmousedown="runcode.resize(this,event);"><textarea name="runcode" class="runcode_text" id="runcode_ww9i33" onmousedown="(document.all)?(event.cancelBubble = true) : (event.stopPropagation())">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot; /&gt;
&lt;title&gt;Typing...&lt;/title&gt;
&lt;style type=&quot;text/css&quot;&gt;
*{padding:0;margin:0;}
body
{font-family:'MS Gothic';line-height: 1.8;font-size: 15px;color: #444;padding:10px;}
#avatar{position:relative;width:800px;word-wrap:break-word;margin:0 auto;}
b{font-weight:normal;display:none;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;avatar&quot;&gt;
&lt;p&gt;我们都一样&lt;/p&gt;
&lt;p&gt;推开窗看见星星,依然守在夜空中。&lt;/p&gt;
&lt;p&gt;心中不免多了些,暖暖的感动。&lt;/p&gt;
&lt;p&gt;一闪一闪的光,努力把黑夜点亮，气氛如此安详。&lt;/p&gt;
&lt;p&gt;你在我的生命中,是那最闪亮的星。&lt;/p&gt;
&lt;p&gt;一直在无声夜空,守护着我们的梦。&lt;/p&gt;
&lt;p&gt;这世界那么大,我的爱只想要你懂。&lt;/p&gt;
&lt;p&gt;陪伴我孤寂旅程。&lt;/p&gt;
&lt;p&gt;你知道我的梦,你知道我的痛。&lt;/p&gt;
&lt;p&gt;你知道我们感受都相同。&lt;/p&gt;
&lt;p&gt;就算有再大的风,也挡不住勇敢的冲动。&lt;/p&gt;
&lt;p&gt;努力的往前飞,再累也无所谓。&lt;/p&gt;
&lt;p&gt;黑夜过后的光芒有多美。&lt;/p&gt;
&lt;p&gt;分享你我的力量,就能把对方的路照亮。&lt;/p&gt;
&lt;p&gt;我想我们都一样,渴望梦想的光芒。&lt;/p&gt;
&lt;p&gt;这一路喜悦彷徨,不要轻易说失望。&lt;/p&gt;
&lt;p&gt;回到最初时光,当时的你多么坚强。&lt;/p&gt;
&lt;p&gt;那鼓励让我难忘。&lt;/p&gt;
&lt;p&gt;你知道我的梦,你知道我的痛。&lt;/p&gt;
&lt;p&gt;你知道我们感受都相同。&lt;/p&gt;
&lt;p&gt;就算有再大的风,也挡不住勇敢的冲动。&lt;/p&gt;
&lt;p&gt;努力的往前飞,再累也无所谓。&lt;/p&gt;
&lt;p&gt;黑夜过后的光芒有多美。&lt;/p&gt;
&lt;p&gt;分享你我的力量,就能把对方的路照亮。&lt;/p&gt;
&lt;/div&gt;
&lt;span id=&quot;cursor&quot;&gt;|&lt;/span&gt;
&lt;embed name=&quot;我们都一样&quot; pluginspage=&quot;http://www.microsoft.com/Windows/MediaPlayer&quot; src=&quot;http://www.cssass.com/blog/resource/bgsound/bgsound.mp3&quot;
width=&quot;1&quot; height=&quot;1&quot; type=&quot;application/x-mplayer2&quot; autostart=&quot;1&quot;  loop=&quot;1&quot; volume=&quot;50&quot;&gt;&lt;/embed&gt;
&lt;script&gt;
var $id=function(o){return document.getElementById(o) || o};
var g=$id('avatar');
var cursor=$id(&quot;cursor&quot;);
var init=function ()
{
	var n=0, l=g.innerHTML, s='';
	while (n&lt;l.length)
	{
		var r=l.charAt(n);
		if (r==' ') { s+=r; n++}
		if (r=='&lt;') while (l.charAt(n-1)!='&gt;') s+=l.charAt(n++);
		s+='&lt;b&gt;'+l.charAt(n++)+'&lt;/b&gt;';
	}
	g.innerHTML=s;
};
var Wt={};
Wt.n = 0,
Wt.i = 0;
Wt.p = g.getElementsByTagName(&quot;p&quot;);
Wt.loop=function(){
	if( Wt.n &gt;= Wt.p.length ) {
		window.scrollTo(0,0);
		pos();
		anim();
		cursor.innerHTML='';
		g.onclick=anim;
		return false;
	};
	Wt.p[Wt.n].appendChild(cursor);
	var _loop=function(){
		var m = Wt.p[Wt.n].getElementsByTagName(&quot;b&quot;);
		if(Wt.i &lt; m.length ){
			setTimeout(function(){
				m[Wt.i].style.display='inline';
				Wt.i++;
				_loop();
			},300);
		}
		else{
			setTimeout(function(){
				Wt.i=0;
				Wt.n++;
				Wt.loop();
			},300);
		}
	};
	_loop();
};
var glint=setInterval(function(){
	cursor.style.display = (cursor.style.display==&quot;none&quot;) ? &quot;inline&quot; : &quot;none&quot;;
},500);
var xo=[], yo=[], xd=[], yd=[], e=[], an=-1, dir=-1 , t=0;
var d='6=.6&gt;&amp;5&amp;84OF4(@4*?3*J3-53*&gt;3-B3*13G%44&amp;5),6.D6377E%8.B;.0;3J?$+&gt;E&lt;B))B;@EG*F%-I0&gt;I6AM&amp;&gt;M,=Q),PJ;T:DT@5X1$X60[NO[T,_8B_=8b16b)3eC)e!?i,Gh3!l&gt;&lt;kD,o*Go!!r0)r%&gt;u54t92w=+v@=y+HxGF6H86248D+8-G6H/8G-7-889C8677&lt;&gt;8748E?8D79C1;0C86+:6&amp;;/0;&gt;$=)?&lt;#$=*#&lt;H%=*;=!(=*G:5(=++=!?=+7&lt;&lt;HA9;&lt;HD?3*=GDAF3&gt;C5A9#&gt;E$A9/A03A:!B!@A:8@1?B+AA/1BE&amp;B-)BO2A/OA83A/GA8BE&gt;/E0DB.FF.#CE%F-3E&gt;8F,OE&gt;EF,CF#&lt;F,7E?)F-?E?3F,+F0AHB-H*(F+GE@6J:GG.&gt;J;-I65J&lt;!J2#J&lt;-J2%J01J2/J&lt;9J=GJ=*J39J;@J2GJ;4J2;I65O.&lt;K0@LCBL9$O.BL.!O/;M,/NJ7N@@O#4NA#O0+NA/P,HO&amp;HO07O&amp;&lt;P!ANA&gt;Q,$Q.=S&gt;)RC=S=ES4,S&gt;6RDCS&gt;ARD)S?%S(HT!OT22S?1U/&amp;T=1V!*X%#T@&amp;X%/V!*X%;X5(X%HWCCX&amp;+WC8X&amp;7X(JX30WC,ZE4W8,ZE@WE$ZF$ZH%[P1[R0[P=[R&lt;[]3[RJ[]@[S/]%.[S:_,8[SF_ED]@4_,OaBD_-3^27_::a6&lt;`7@`9/a*?c$(`:#`6D`FFcH;`!&gt;c&lt;3e,Bc&lt;JdH:e7@e-:fB.e!4h$$fC(h1(i/)h1%i#!h/Hh2-h/&gt;h2;i:,mJ9jDCm%0kB$l@Ol39l(2n-@p*7o+Ar%#p)7r%,q3!u63s!&gt;t85z6)v@*sGCr$;pO0n.Ak62h=GdGGd:Oc$4a);_.1]@)[,!Z.AW6&amp;W)DT$&lt;RO3P.BO&gt;#MB8L8AK!HHO)H5JF;3E=:CC&amp;C)D@$F?@&amp;&lt;GG;J)9C#9)A6=.6&gt;&amp;5&amp;84OF4(@4*?3*J3-53*&gt;3-B3*13G%44&amp;5),6.D6377E%8.B;.0;3J?$+&gt;E&lt;B))B;@EG*F%-I0&gt;I6AM&amp;&gt;M,=Q),PJ;T:DT@5X1$X60[NO[T,_8B_=8b16b)3eC)e!?i,Gh3!l&gt;&lt;kD,o*Go!!r0)r%&gt;u54t92w=+v@=y+HxGF6=.6&gt;&amp;5&amp;84OF4(@4*?3*J3-53*&gt;3-B3*13G%44&amp;5),6.D6377E%8.B;.0;3J?$+&gt;E&lt;B))B;@EG*F%-I0&gt;I6AM&amp;&gt;M,=Q),PJ;T:DT@5X1$X60[NO[T,_8B_=8b16b)3eC)e!?i,Gh3!l&gt;&lt;kD,o*Go!!r0)r%&gt;u54t92w=+v@=y+HxGF';
function pos(){
	e=g.getElementsByTagName('b');
	for (n=0; n&lt;e.length; n++)
	{
		xo[n]=e[n].offsetLeft;
		yo[n]=e[n].offsetTop;
		var p=d.charCodeAt(n*3)*1600+d.charCodeAt(n*3+1)*40+d.charCodeAt(n*3+2)-78768;
		yd[n]=p%500;
		xd[n]=(p-yd[n])/500;
	}
	for (n=0; n&lt;e.length; n++)
	{
		e[n].style.position='absolute';
		e[n].style.left=xo[n]+'px';
		e[n].style.top=yo[n]+'px';
	}
};
function ani()
{	t=e.length;
	for (var n=0; n&lt;t; n++)
	{
		if ((an-n&lt;=30)&amp;&amp;(an-n&gt;=0))
		{
			var b=(Math.cos((((an-n)*Math.PI)/30))+1)/2;
			var a=1-b;
			e[n].style.left=((yd[n]+111)*a+xo[n]*b)+'px';
			e[n].style.top=((xd[n]+74)*a+yo[n]*b)+'px';
		}
	}
	an+=dir;
	if ((an-t&lt;=30)&amp;&amp;(an&gt;=0))
	{
		window.setTimeout(&quot;ani()&quot;, 20);
	}
};
function anim()
{
	dir*=-1;
	if ((an&lt;0)||(an-t&gt;30)) ani();
};
init();
Wt.loop();
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea></span></div>
<div><input type="button" value="Run" class="runcode_button" onclick="runcode.open_new('runcode_ww9i33');"/> </div>
</div>


<p>No related posts. From:<a href=\]]></content:encoded>
			<wfw:commentRss>http://www.cssass.com/blog/index.php/2011/1086.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
<enclosure url="http://www.cssass.com/blog/resource/bgsound/bgsound.mp3" length="4850976" type="audio/mpeg" />
		</item>
	</channel>
</rss>

