<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/xsl/rss.xsl" type="text/xsl" media="screen"?>
<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:ppp="http://blog.sohu.com/rss/module/ppp/"
	>

	<channel>
		<title>花非花</title>
		<link>http://dennnis-zane.blog.sohu.com/</link>
		<description><![CDATA[花非花]]></description>
		<pubDate>Tue, 6 Feb 2007 14:27:59 +0800</pubDate>
		<generator>搜狐博客</generator>
		<ppp:ebi>dd242a4792</ppp:ebi>
		<image>
			<title>http://blog.sohu.com</title>
			<url>http://js.pp.sohu.com/ppp/blog/images/common/logo_150_60.gif</url>
			<link>http://blog.sohu.com/</link>
			<width>100</width>
			<height>43</height>
			<description>搜狐博客</description>
		</image>
		<item>
			<title>简单搬家完毕！</title>
			<link>http://dennnis-zane.blog.sohu.com/32879084.html</link>
			<comments>http://dennnis-zane.blog.sohu.com/32879084.html#comment</comments>
			<dc:creator>花非花</dc:creator>
			<pubDate>Tue, 6 Feb 2007 14:27:59 +0800</pubDate>
			<category>闲谈</category>
			<guid>http://dennnis-zane.blog.sohu.com/32879084.html</guid>
			<description><![CDATA[<p>项目要初验，完善文档基本没我什么事，正好有时间把blog搬家!-_- <br />第一次写blog在CSDN(<a href="http://blog.csdn.net/killme2008">killme2008</a>)，那时CSDN的blog系统刚出来，速度很惊人&mdash;&mdash;慢的惊人，而且3天两头当机的玩意。不是我玩blog，是blog玩我。忍受了接近一年的时间，把家搬到了sohu(<a href="http://dennnis-zane.blog.sohu.com/">花非花</a>)。在那也呆了4，5个月了吧，可毕竟不是技术blog圈，八卦新闻一大堆，而且似乎大伙都喜欢在blog上贴图，写上那么一段风花雪月的文字然后满世界打广告叫别人去看!-_-&nbsp; 
我说你丫是写blog还是想出名啊！<br />blog对我的意义仅在于网上有个写东西的地方，写下自己每天的得失，写下某一件快乐的事情，写下几行也许以后用得着又怕忘记的代码......<br /><br />搬家够累，懒的一篇一篇复制黏贴了，转了20篇就没兴趣了，就这样吧，开始俺的blogjava生涯，等下顺便把域名映射新blog去，嘿嘿。欢迎访问我的新家：http://www.blogjava.net/killme2008/</p>]]></description>
		</item>
		    
		
		<item>
			<title>JavaScript之DOM技术(一)</title>
			<link>http://dennnis-zane.blog.sohu.com/32608004.html</link>
			<comments>http://dennnis-zane.blog.sohu.com/32608004.html#comment</comments>
			<dc:creator>花非花</dc:creator>
			<pubDate>Sun, 4 Feb 2007 16:54:19 +0800</pubDate>
			<category>Ajax及web开发</category>
			<guid>http://dennnis-zane.blog.sohu.com/32608004.html</guid>
			<description><![CDATA[首先需要理解的一点是，DOM是针对XML的基于树的API，它的实现有很多（各语言基本都有自己的实现），我们讨论的是javascript中或者说xhtml(html)对DOM的实现。<br /><br />一、使用DOM<br />考虑一个html文件：<br />&lt;html&gt;<br />&lt;head&gt;&lt;title&gt;测试&lt;/title&gt;&lt;/head&gt;<br />&lt;body&gt;<br />&lt;p&gt;测试&lt;/p&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;<br /><br />1.访问节点：<br />访问html元素：var oHtml=document.documentElement;<br />获取head元素：var oHead=oHtml.firstChild;<br />获取body元素：var oBody=oHtml.lastChild; 或者 var oBody=document.body;<br /><br />也可以通过childNodes来做同样的工作：<br />var oHead=oHtml.childNodes[0] 或者 oHtml.childNodes.item(0);<br />var oBody=oHtml.childNodes[1] 或者 oHtml.childNodes.item(1);<br /><br />判断节点间关系：<br />alert(oHead.parentNode==oHtml);&nbsp; <br />alert(oBody.previousSibling==oHead);<br />alert(oHead.nextSibling==oBody);<br />alert(oHead.ownerDocument==document);<br /><br />2.检测节点类型：<br />通过节点的nodeType属性来检验节点类型：<br />alert(document.nodeType);&nbsp; //输出9<br />需要注意的是，DOM兼容的浏览器（以FF2.0为例），拥有Node.DOCUMENT_NODE、Node.ELEMENT_NODE等常量。各常量名称与数值对照表如下：<br /><br />ELEMENT_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br />ATTRIBUTE_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<br />TEXT_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3<br />CDATA_SECTION_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; 4<br />ENTITY_REFERENCE_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5<br />ENTITY_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6<br />PROCESSING_INSTRCTION_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7<br />COMMENT_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8<br />DOCUMENT_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9<br />DOCUMENT_TYPE_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10<br />DOCUMENT_FRAGMENT_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11<br />NOTATION_NODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12<br /><br />IE6不支持，不过你可以自定义一个JS对象Node。<br /><br />3.处理特性<br />处理特性可以使用标准的NameNodeMap中的方法：<br />getNamedItem(name) removeNamedItem(name)&nbsp; setNamedItem(node)&nbsp;&nbsp;&nbsp; item(pos)<br /><br />比如:&lt;p id=&quot;test&quot;&gt;测试&lt;/p&gt;<br />假设变量oP是上面的p节点的引用，我们要访问oP的id属性:<br />var sId=oP.attributes.getNamedItem(&quot;id&quot;).nodeValue;<br /><br />这些方法用起来很累赘,所以DOM又定义了三个方法来简化:<br />getAttribute(name)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &mdash;&mdash;返回名称为name的属性的值<br />setAttribute(name,value) &nbsp; &mdash;&mdash;顾名思义<br />removeAttribute(name) &nbsp; &nbsp;&nbsp; &mdash;&mdash;顾名思义&nbsp;  <br /><br />上面的例子可以改写为：<br />var sId=oP.getAttribute(&quot;name&quot;);<br /><br />4.访问指定节点：<br />熟知的getElementByTagName(name),getElementByName(name),getElementById(id)三个方法，不再展开。<br /><br />5.创建和操作节点：<br />（1）创建新节点，一张IE(6.0)和FF对DOM Level1的创建新节点方法支持的对照表：<br />方法 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; IE&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; FF<br />createAttribute(name)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y<br />createCDATASection(text)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; N&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y<br />createComment(text)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y<br />createDocumentFragment()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y<br />createElement(tagName)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y<br />createEntityReference(name)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; N&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y<br />createProcessingInstruction(target,data) N&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y<br />createTextNode(text)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y<br /><br />下面介绍常用的几个方法<br /><br />（2）createElement(),createTextNode(),appendChild()<br />例子：<br />&lt;html&gt;<br />&nbsp;&nbsp;&nbsp; &lt;head&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;createElement() Example&lt;/title&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script type=&quot;text/javascript&quot;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function createMessage() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var oP = document.createElement(&quot;p&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var oText = document.createTextNode(&quot;Hello World!&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oP.appendChild(oText);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.body.appendChild(oP);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/script&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/head&gt;<br />&nbsp;&nbsp;&nbsp; &lt;body onload=&quot;createMessage()&quot;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/body&gt;<br />&lt;/html&gt;<br />在页面载入后，创建节点oP，并创建一个文本节点oText,oText通过appendChild方法附加在oP节点上，为了实际显示出来，将oP节点通过appendChild方法附加在body节点上。此例子将显示Hello World!<br /><br />（3）removeChild(),replaceChild()和insertBefore()<br />从方法名称就知道是干什么的：删除节点，替换节点，插入节点。需要注意的是replaceChild和insertBefore两个参数都是新节点在前，旧节点在后。<br /><br />（4）createDocumentFragment()<br />此方法主要是为了解决大量添加节点时，速度过慢。通过创建一个文档碎片节点，将要添加的新节点附加在此碎片节点上，然后再将文档碎片节点append到body上面，替代多次append到body节点。<br />例子：<br />&lt;html&gt;<br />&nbsp;&nbsp;&nbsp; &lt;head&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;insertBefore() Example&lt;/title&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script type=&quot;text/javascript&quot;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function addMessages() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var arrText = [&quot;first&quot;, &quot;second&quot;, &quot;third&quot;, &quot;fourth&quot;, &quot;fifth&quot;, &quot;sixth&quot;, &quot;seventh&quot;, &quot;eighth&quot;, &quot;ninth&quot;, &quot;tenth&quot;];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var oFragment = document.createDocumentFragment();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i=0; i &lt; arrText.length; i++) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var oP = document.createElement(&quot;p&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var oText = document.createTextNode(arrText[i]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oP.appendChild(oText);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oFragment.appendChild(oP);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.body.appendChild(oFragment);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/script&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/head&gt;<br />&nbsp;&nbsp;&nbsp; &lt;body onload=&quot;addMessages()&quot;&gt;<br /><br />&nbsp;&nbsp;&nbsp; &lt;/body&gt;<br />&lt;/html&gt;<br /><br />二、HTML DOM的特征功能<br /><br />HTML DOM的特性和方法不是标准的DOM实现，是专门针对HTML同时也让一些DOM操作变的更加简便。<br /><br />1.让特性像属性一样<br />访问某元素的特性需要用到getAttribute(name)方法，HTML DOM扩展，可以直接使用同样名称的属性来获取和设置这些值：<br />比如&nbsp; &lt;img src=&quot;test.jpg&quot;/&gt;<br />假设oImg是此元素的引用<br />(oImg.getAttribute(&quot;src&quot;)可以直接写成:oImg.src，设置值简化为：<br />oImg.src=&quot;test2.gif&quot;;<br />唯一特殊的class属性，因为class是ECMAScript的保留字，所以替代的属性名是className.<br /><br />2.table的系列方法：<br />为了简化创建表格，HTML DOM提供了一系列的表格方法，常用几个：<br />cells&nbsp; &mdash;&mdash;返回&lt;/tr&gt;元素中的所有单元格<br />rows&nbsp;&nbsp; &mdash;&mdash;表格中所有行的集合<br />insertRow(position) &mdash;&mdash;在rows集合中指定位置插入新行<br />deleteRow(position) &mdash;&mdash;与insertRow相反<br />insertCell(position) &mdash;&mdash;在cells集合的指定位置插入一个新的单元格<br />deleteCell(position) &mdash;&mdash;与insertCell相反<br /><br />三。遍历DOM<br />DOM的遍历是DOM Level2中提出的标准，IE6没有实现，Mozilla和Safari已经实现，最新IE7不清楚是否实现。不再展开，具体请见《JavaScript高级程序设计》<br /><br /><br /><br /><br /><br />&nbsp;<br />]]></description>
		</item>
		    
		
		<item>
			<title>学ruby要从娃娃抓起：）</title>
			<link>http://dennnis-zane.blog.sohu.com/32464829.html</link>
			<comments>http://dennnis-zane.blog.sohu.com/32464829.html#comment</comments>
			<dc:creator>花非花</dc:creator>
			<pubDate>Sat, 3 Feb 2007 15:30:24 +0800</pubDate>
			<category>闲谈</category>
			<guid>http://dennnis-zane.blog.sohu.com/32464829.html</guid>
			<description><![CDATA[周末在公司发布了预算系统的新版本，在javaeye上看到一个帖子，被投隐藏帖了，不过帖子的图片很可爱：<br /><img src="http://img45.pp.sohu.com/images/blog/2007/2/3/15/29/1111c8653cb.jpg" style="margin: 0px auto 10px; display: block; text-align: center;" alt="" border="0" /><img src="http://img45.pp.sohu.com/images/blog/2007/2/3/15/29/1111c869305.jpeg" style="margin: 0px auto 10px; display: block; text-align: center;" alt="" border="0" /><br />咱要有孩子了，也要让她从小学ruby@_@<br />]]></description>
		</item>
		    
		
		<item>
			<title>ruby on rails应用性能优化之道(转)</title>
			<link>http://dennnis-zane.blog.sohu.com/32158118.html</link>
			<comments>http://dennnis-zane.blog.sohu.com/32158118.html#comment</comments>
			<dc:creator>花非花</dc:creator>
			<pubDate>Thu, 1 Feb 2007 12:42:54 +0800</pubDate>
			<category>动态语言(ruby groovy)</category>
			<guid>http://dennnis-zane.blog.sohu.com/32158118.html</guid>
			<description><![CDATA[javaeye站长的经验之谈：http://www.javaeye.com/topic/51595<br /><br /><p>这是一篇我们运营JavaEye网站将近半年时间所得到经验的总结。目前在整个rails社区，都极少有运营rails大访问量网站经验的人详细的
谈这个话题。至于国内，rails应用都停留在学习和尝试阶段，真正投入商业运营的基本找不到，所以谈这个话题为时太早，颇有对牛弹琴的感觉。所以权当是
个人的总结性文章吧，也不会很详细的展开谈论，能对大家有所启发就好。</p>

<p>一、硬件</p>

<p>1、CPU
<br />ruby解析器相对于JVM，PHP解析器来说，比较低效，可能会导致比较多的context
switch，因此提高CPU和内存之间的总线带宽和传输速度会对ruby应用有比较大的性能提升。在目前主流的x86_64 CPU当中，AMD
Opteron在CPU芯片内置内存控制器，可以有效提高CPU和内存数据交换速度，提高context switch能力。所以用AMD
Opteron比Intel Xeon EM64T性能要好很多。</p>

<p>2、物理内存
<br />ruby是以进程方式运行的，rails应用的并发响应能力主要取决于ruby进程的数量。一个最简单的rails应用，一个ruby进程占用的
物理内存一般不过30-40MB，但是对于真正复杂的，而且数据库访问频繁，数据量大的rails应用来说，ruby进程稳定的物理内存占用至少100多
MB，经常达到200多MB，甚至300MB。以开10个ruby进程计算，那么物理内存使用上限就是3GB，所以4GB物理内存是起码的。</p>

<p>二、操作系统</p>

<p>1、Linux distro
<br />对于AMD x86_64的CPU来说，SLES要比RHEL有更多的优化。</p>

<p>2、32位版本还是64位版本</p>

<p>应该使用64位版本操作系统，以充分发挥x86_64 CPU的性能，并且x86_64的Linux很多Kernel参数也大很多，代价就是需要更多的物理内存。所以内存多多益善。</p>

<p>3、文件系统
<br />rails会对每个浏览器会话在硬盘生成session文件，一个繁忙的网站，临时文件目录下面有上万乃至几万个session文件是很常见的现象。对于这种目录下面几万个小文件的存取，reiserfs要比ext3性能好很多倍。</p>

<p>三、Web Server</p>

<p>主流的选择是apache2.2，lighttpd，litespeed。apache2.2可以首先排除，lighttpd和litespeed都不错，但我会选择开源免费的lighttpd。至于lighttpd的各种优化参数这里不谈。</p>

<p>四、ruby的部署</p>

<p>1、ruby GC
<br />可以使用railsbench提供的GC patch，以优化ruby内存使用，降低GC频率，提高throughput，代价就是ruby进程的物理内存占用加倍。所以物理内存越多越好，4G根本不够用，8G，16G绝对不嫌多。</p>

<p>2、FCGI还是mongrel
<br />ruby进程可以以FCGI方式来运行，以FastCGI协议和Web Server通讯，也可以以HTTP
Server方式来运行(即Mongrel)，以HTTP协议和Web
Server通讯，这两种方式性能上没有什么差异。FCGI方式，在单机上面通过Unix Socket和Web Server通讯，效率比走TCP
Port要高。</p>

<p>3、开多少个ruby进程
<br />ruby进程数量和web server的connection数量的比例没有定规，少了多了都会降低性能，要靠实践去摸索，也要参考CPU和内存资源的使用状况。</p>

<p>五、应用程序</p>

<p>1、避免使用component</p>

<p>2、hash的key使用symbol</p>

<p>3、对于ORM来说，数据库的表设计的原则是颗粒度应该小一些，把常用字段和不常用字段尽量分离到不同表，严重影响性能的大字段分离到单独的表</p>

<p>4、在不使用对象缓存的情况下，查询方法的:include可以预加载关联对象，避免n+1问题</p>

<p>六、缓存</p>

<p>1、rails的页面缓存，Action缓存和片断缓存
<br />rails提供的缓存方式可以有效降低对应用服务器的负载，但是缓存颗粒度太粗，适应范围比较狭窄，缓存过期的处理比较烦琐。</p>

<p>2、对象缓存
<br />rails应用本身是可以水平扩展的，性能瓶颈往往还是数据库访问，使用CachedModel对象缓存可以有效降低数据库负载，但
CachedModel不像Hibernate二级缓存那么强大，不能够针对非主键查询进行缓存读取，不能针对非主键查询进行缓存填充，和file-
column有冲突，需要自行覆盖model对象的save方法等等。另外在使用对象缓存的情况下，应该把查询方法的:include去掉，避免关联查询
无法利用缓存的现象。
</p><br /><br /><br />]]></description>
		</item>
		    
		
		<item>
			<title>使用Annotation设计持久层</title>
			<link>http://dennnis-zane.blog.sohu.com/32146111.html</link>
			<comments>http://dennnis-zane.blog.sohu.com/32146111.html#comment</comments>
			<dc:creator>花非花</dc:creator>
			<pubDate>Thu, 1 Feb 2007 11:07:23 +0800</pubDate>
			<category>Java</category>
			<guid>http://dennnis-zane.blog.sohu.com/32146111.html</guid>
			<description><![CDATA[这篇文章的想法来自于过去的两篇文章：《设计自己的MVC框架》《设计模式之事务处理》<br />链接：<br />http://www.javaresearch.org/article/59935.htm<br />http://www.javaresearch.org/article/59043.htm<br /><br /><br />代码下载同样在www.126.com的邮箱里，用户名 sharesources 密码 javafans<br /><br />&nbsp;&nbsp;&nbsp; 本文只是学习性质的文章，我一开始的想法就是修改《设计模式之事务处理》，提供Annotation来提供事务支持，支持到方法级别。通过引入一个@Transaction标注，如果被此标注的方法将自动享受事务处理。目的是学习下Annotation和加深下对声明式事务处理的理解。<br /><br />&nbsp;&nbsp;&nbsp; Annotation是JDK5引入的新特性，现在越来越多的框架采用此特性来代替烦琐的xml配置文件，比如hibernate,ejb3,spring等。对Annotation不了解，请阅读IBM网站上的文章，还有推荐javaeye的Annotation专栏：http://www.javaeye.com/subject/Annotation<br /><br />&nbsp;&nbsp;&nbsp; 代码的示例是一个简单的用户管理例子。<br /><br />&nbsp;&nbsp;&nbsp; 首先，环境是mysql+jdk5+myeclipse5+tomcat5，在mysql中建立一张表adminusers:<br />&nbsp;&nbsp;&nbsp; create table adminusers(id int(10) auto_increment not null primary key,<br />&nbsp;&nbsp;&nbsp;&nbsp; name varchar(10) not null,<br />&nbsp;&nbsp;&nbsp;&nbsp; password varchar(10) not null,<br />&nbsp;&nbsp;&nbsp;&nbsp; user_type varchar(10));<br />&nbsp;&nbsp;&nbsp; 然后在tomcat下建立一个数据源，把代码中的strutslet.xml拷贝到tomcat安装目录下的\conf\Catalina\localhost目录里，请自行修改文件中的数据库用户名和密码，以及数据库名称。另外，把mysql的 jdbc驱动拷贝到tomcat安装目录下的common/lib目录。这样数据源就建好了。在web.xml中引用：<br /><br />&nbsp;&nbsp; &lt;resource-ref&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;description&gt;DB Connection&lt;/description&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;res-ref-name&gt;jdbc/test&lt;/res-ref-name&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;res-auth&gt;Container&lt;/res-auth&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/resource-ref&gt;<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 我的例子只是在《设计模式之事务处理》的基础上改造的，在那篇文章里，我讲解了自己对声明式事务处理的理解，并利用动态代理实现了一个TransactionWrapper(事务包装器)，通过业务代理工厂提供两种版本的业务对象：经过事务包装的和未经过事务包装的。我们在默认情况下包装业务对象中的所有方法，但实际情况是，业务对象中的很多方法不用跟数据库打交道，它们根本不需要包装在一个事务上下文中，这就引出了，我们为什么不提供一种方式来配置哪些方法需要事务控制而哪些并不需要？甚至提供事务隔离级别的声明？很自然的想法就是提供一个配置文件，类似spring式的事务声明。既然JDK5已经引入Annotation，相比于配置文件的烦琐和容易出错，我们定义一个@Transaction的annotation来提供此功能。<br /><br />&nbsp;&nbsp;&nbsp; 看下Transaction.java的代码：<br />&nbsp;&nbsp;&nbsp; package com.strutslet.db;<br /><br />&nbsp;&nbsp;&nbsp; import java.lang.annotation.Documented;<br />&nbsp;&nbsp;&nbsp; import java.lang.annotation.ElementType;<br />&nbsp;&nbsp;&nbsp; import java.lang.annotation.Retention;<br />&nbsp;&nbsp;&nbsp; import java.lang.annotation.RetentionPolicy;<br />&nbsp;&nbsp;&nbsp; import java.lang.annotation.Target;<br />&nbsp;&nbsp;&nbsp; import java.sql.Connection;<br /><br />&nbsp;&nbsp;&nbsp; @Target(ElementType.METHOD)<br />&nbsp;&nbsp;&nbsp; @Retention(RetentionPolicy.RUNTIME)<br />&nbsp;&nbsp;&nbsp; @Documented<br />&nbsp;&nbsp;&nbsp; public @interface Transaction {<br />&nbsp;&nbsp; &nbsp; &nbsp; //事务隔离级别，默认为read_committed<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int level() default Connection.TRANSACTION_READ_COMMITTED&nbsp;&nbsp;&nbsp; ;<br />&nbsp;&nbsp;&nbsp; }<br /><br />@Transaction标注只有一个属性level，level表示事务的隔离级别，默认为Read_Committed（也是一般JDBC驱动的默认级别，JDBC驱动默认级别一般于数据库的隔离级别一致）。 @Target(ElementType.METHOD)表示此标注作用于方法级别， @Retention(RetentionPolicy.RUNTIME)表示在运行时，此标注的信息将被加载进JVM并可以通过Annotation的API读取。我们在运行时读取Annotation的信息，根据隔离级别和被标注的方法名决定是否将业务对象的方法加进事务控制。我们只要稍微修改下TransactionWrapper:<br /><br />//TransactionWrapper.java<br />package com.strutslet.db;<br /><br />import java.lang.annotation.Annotation;<br />import java.lang.reflect.InvocationHandler;<br />import java.lang.reflect.Method;<br />import java.lang.reflect.Proxy;<br />import java.sql.Connection;<br />import java.sql.SQLException;<br /><br />import com.strutslet.exception.SystemException;<br /><br />public class TransactionWrapper {<br /><br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; public static Object decorate(Object delegate) {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; delegate.getClass().getInterfaces(), new XAWrapperHandler(<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; delegate));<br />&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; static final class XAWrapperHandler implements InvocationHandler {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; private final Object delegate;<br /><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; XAWrapperHandler(Object delegate) {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Cache the wrapped delegate, so we can pass method invocations<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // to it.<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.delegate = delegate;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public Object invoke(Object proxy, Method method, Object[] args)<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throws Throwable {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Object result = null;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Connection con = ConnectionManager.getConnection();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到Transaction标注 <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Transaction transaction = method.getAnnotation(Transaction.class);<br /><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //如果不为空，说明代理对象调用的方法需要事务控制。<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (transaction != null) {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // System.out.println(&quot;transaction..&quot; + con.toString());<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 得到事务隔离级别信息<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int level = transaction.level();<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (con.getAutoCommit())<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置事务隔离级别<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; con.setTransactionIsolation(level);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //调用原始对象的业务方法<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result = method.invoke(delegate, args);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; con.commit();<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; con.setAutoCommit(true);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (SQLException se) {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Rollback exception will be thrown by the invoke method<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; con.rollback();<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; con.setAutoCommit(true);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throw new SystemException(se);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (Exception e) {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; con.rollback();<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; con.setAutoCommit(true);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throw new SystemException(e);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result = method.invoke(delegate, args);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return result;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />}<br /><br />现在，看下我们的UserManager业务接口，请注意，我们是使用动态代理，只能代理接口，所以要把@Transaction标注是接口中的业务方法（与EJB3中的Remote,Local接口类似的道理）:<br />package com.strutslet.demo.service;<br /><br />import java.sql.SQLException;<br /><br />import com.strutslet.db.Transaction;<br />import com.strutslet.demo.domain.AdminUser;<br /><br />public interface UserManager {<br />&nbsp;&nbsp;&nbsp; //查询，不需要事务控制<br />&nbsp;&nbsp;&nbsp; public boolean checkUser(String name, String password) throws SQLException;<br /><br />&nbsp;&nbsp;&nbsp; //新增一个用户，需要事务控制，默认级别<br />&nbsp;&nbsp;&nbsp; @Transaction<br />&nbsp;&nbsp;&nbsp; public boolean addUser(AdminUser user) throws SQLException;<br /><br />}<br /><br />要把addUser改成其他事务隔离级别（比如oracle的serializable级别），稍微修改下：@Transaction(level=Connection.TRANSACTION_SERIALIZABLE)<br />public boolean addUser(AdminUser user) throws SQLException;<br /><br />不准备详细解释例子的业务流程，不过是登录和增加用户两个业务方法，看下就明白。阅读本文前最好已经读过开头提过的两篇文章。我相信代码是最好的解释：）<br /><br /><br /><br /><br /><br /><br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;  <br /><br /><br /><br />]]></description>
		</item>
		    
		
		<item>
			<title>注册了一个域名，考虑建站...</title>
			<link>http://dennnis-zane.blog.sohu.com/32017666.html</link>
			<comments>http://dennnis-zane.blog.sohu.com/32017666.html#comment</comments>
			<dc:creator>花非花</dc:creator>
			<pubDate>Wed, 31 Jan 2007 13:19:42 +0800</pubDate>
			<category>闲谈</category>
			<guid>http://dennnis-zane.blog.sohu.com/32017666.html</guid>
			<description><![CDATA[<p>很早就打算注册一个域名，免的写些自己玩的程序时包名老要写的好长,com.sohu.blog.dennnis_zane，&nbsp;<img alt="呕吐" src="http://img3.pp.sohu.com/ppp/blog/images/emotion/27.gif" border="0" />&nbsp;</p>
<p><a href="http://www.rubyeye.net/">rubyeye.net</a>，嘿嘿，可惜rubyeye.com已经被人抢注了，哭&nbsp;<img alt="大哭" src="http://img3.pp.sohu.com/ppp/blog/images/emotion/13.gif" border="0" />&nbsp;</p>
<p>没想好要不要去建设一个个人站点，建一个ruby&amp;rails技术的讨论场所，带上一个自己写的blog系统，使我的blog彻底告别寄居生涯？再说了，现在还没时间，等春节后看看咯</p>]]></description>
		</item>
		    
		
		<item>
			<title>javascript事件模型框架</title>
			<link>http://dennnis-zane.blog.sohu.com/31990171.html</link>
			<comments>http://dennnis-zane.blog.sohu.com/31990171.html#comment</comments>
			<dc:creator>花非花</dc:creator>
			<pubDate>Wed, 31 Jan 2007 09:47:53 +0800</pubDate>
			<category>Ajax及web开发</category>
			<guid>http://dennnis-zane.blog.sohu.com/31990171.html</guid>
			<description><![CDATA[最近一直在读《javascript高级程序设计》，也快读完了，读到事件这一章，书中提供的一个事件工具类很实用，我注释了一下，并摘记：<br /><br />//eventutil.js<br />var EventUtil = new Object;<br />/* <br />&nbsp; 此方法用来给特定对象添加事件，oTarget是指定对象,sEventType是事件类型，如click、keydown等，&nbsp; &nbsp; fnHandler是事件回调函数<br />/*<br />EventUtil.addEventHandler = function (oTarget, sEventType, fnHandler) {<br />&nbsp;&nbsp;&nbsp; //firefox情况下<br />&nbsp;&nbsp;&nbsp; if (oTarget.addEventListener) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oTarget.addEventListener(sEventType, fnHandler, false);<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; //IE下<br />&nbsp; &nbsp; else if (oTarget.attachEvent) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oTarget.attachEvent(&quot;on&quot; + sEventType, fnHandler);<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp; &nbsp; else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oTarget[&quot;on&quot; + sEventType] = fnHandler;<br />&nbsp;&nbsp;&nbsp; }<br />};<br />/* <br />
&nbsp; 此方法用来移除特定对象的特定事件，oTarget是指定对象,sEventType是事件类型，如click、keydown等，fnHandler是事件回调函数<br />
/*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />EventUtil.removeEventHandler = function (oTarget, sEventType, fnHandler) {<br />&nbsp;&nbsp;&nbsp; if (oTarget.removeEventListener) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oTarget.removeEventListener(sEventType, fnHandler, false);<br />&nbsp;&nbsp;&nbsp; } else if (oTarget.detachEvent) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oTarget.detachEvent(&quot;on&quot; + sEventType, fnHandler);<br />&nbsp;&nbsp;&nbsp; } else { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oTarget[&quot;on&quot; + sEventType] = null;<br />&nbsp;&nbsp;&nbsp; }<br />};<br /><br />/*<br />&nbsp;格式化事件，因为IE和其他浏览器下获取事件的方式不同并且事件的属性也不尽相同，通过此方法提供一个一致的事件<br />*/<br />EventUtil.formatEvent = function (oEvent) {<br />&nbsp;&nbsp;&nbsp; //isIE和isWin引用到一个js文件，判断浏览器和操作系统类型<br />&nbsp;&nbsp;&nbsp; if (isIE &amp;&amp; isWin) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.charCode = (oEvent.type == &quot;keypress&quot;) ? oEvent.keyCode : 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //IE只支持冒泡，不支持捕获<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.eventPhase = 2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.isChar = (oEvent.charCode &gt; 0);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.pageX = oEvent.clientX + document.body.scrollLeft;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.pageY = oEvent.clientY + document.body.scrollTop;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //阻止事件的默认行为<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.preventDefault = function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.returnValue = false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //将toElement,fromElement转化为标准的relatedTarget <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (oEvent.type == &quot;mouseout&quot;) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.relatedTarget = oEvent.toElement;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (oEvent.type == &quot;mouseover&quot;) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.relatedTarget = oEvent.fromElement;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; //取消冒泡&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.stopPropagation = function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.cancelBubble = true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.target = oEvent.srcElement;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //添加事件发生时间属性，IE没有<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oEvent.time = (new Date).getTime();<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; return oEvent;<br />};<br /><br />EventUtil.getEvent = function() {<br />&nbsp;&nbsp;&nbsp; if (window.event) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //格式化IE的事件<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.formatEvent(window.event);<br />&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EventUtil.getEvent.caller.arguments[0];<br />&nbsp;&nbsp;&nbsp; }<br />};<br /><br />附带上一个判断浏览器和系统类型的js文件，通过引入一些名字显而易见的全局变量作为判断的结果，使用时需要小心变量名称冲突：<br />//detect.js，同样来自《JAVASCRIPT高级程序设计》<br />var sUserAgent = navigator.userAgent;<br />var fAppVersion = parseFloat(navigator.appVersion);<br /><br />function compareVersions(sVersion1, sVersion2) {<br /><br />&nbsp;&nbsp;&nbsp; var aVersion1 = sVersion1.split(&quot;.&quot;);<br />&nbsp;&nbsp;&nbsp; var aVersion2 = sVersion2.split(&quot;.&quot;);<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; if (aVersion1.length &gt; aVersion2.length) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i=0; i &lt; aVersion1.length - aVersion2.length; i++) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aVersion2.push(&quot;0&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; } else if (aVersion1.length &lt; aVersion2.length) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i=0; i &lt; aVersion2.length - aVersion1.length; i++) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aVersion1.push(&quot;0&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; for (var i=0; i &lt; aVersion1.length; i++) {<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (aVersion1[i] &lt; aVersion2[i]) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (aVersion1[i] &gt; aVersion2[i]) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; return 0;<br /><br />}<br /><br />var isOpera = sUserAgent.indexOf(&quot;Opera&quot;) &gt; -1;<br />var isMinOpera4 = isMinOpera5 = isMinOpera6 = isMinOpera7 = isMinOpera7_5 = false;<br /><br />if (isOpera) {<br />&nbsp;&nbsp;&nbsp; var fOperaVersion;<br />&nbsp;&nbsp;&nbsp; if(navigator.appName == &quot;Opera&quot;) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fOperaVersion = fAppVersion;<br />&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var reOperaVersion = new RegExp(&quot;Opera (\\d+\\.\\d+)&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reOperaVersion.test(sUserAgent);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fOperaVersion = parseFloat(RegExp[&quot;$1&quot;]);<br />&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; isMinOpera4 = fOperaVersion &gt;= 4;<br />&nbsp;&nbsp;&nbsp; isMinOpera5 = fOperaVersion &gt;= 5;<br />&nbsp;&nbsp;&nbsp; isMinOpera6 = fOperaVersion &gt;= 6;<br />&nbsp;&nbsp;&nbsp; isMinOpera7 = fOperaVersion &gt;= 7;<br />&nbsp;&nbsp;&nbsp; isMinOpera7_5 = fOperaVersion &gt;= 7.5;<br />}<br /><br />var isKHTML = sUserAgent.indexOf(&quot;KHTML&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;Konqueror&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;AppleWebKit&quot;) &gt; -1; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />var isMinSafari1 = isMinSafari1_2 = false;<br />var isMinKonq2_2 = isMinKonq3 = isMinKonq3_1 = isMinKonq3_2 = false;<br /><br />if (isKHTML) {<br />&nbsp;&nbsp;&nbsp; isSafari = sUserAgent.indexOf(&quot;AppleWebKit&quot;) &gt; -1;<br />&nbsp;&nbsp;&nbsp; isKonq = sUserAgent.indexOf(&quot;Konqueror&quot;) &gt; -1;<br /><br />&nbsp;&nbsp;&nbsp; if (isSafari) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var reAppleWebKit = new RegExp(&quot;AppleWebKit\\/(\\d+(?:\\.\\d*)?)&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reAppleWebKit.test(sUserAgent);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var fAppleWebKitVersion = parseFloat(RegExp[&quot;$1&quot;]);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isMinSafari1 = fAppleWebKitVersion &gt;= 85;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isMinSafari1_2 = fAppleWebKitVersion &gt;= 124;<br />&nbsp;&nbsp;&nbsp; } else if (isKonq) {<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var reKonq = new RegExp(&quot;Konqueror\\/(\\d+(?:\\.\\d+(?:\\.\\d)?)?)&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reKonq.test(sUserAgent);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isMinKonq2_2 = compareVersions(RegExp[&quot;$1&quot;], &quot;2.2&quot;) &gt;= 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isMinKonq3 = compareVersions(RegExp[&quot;$1&quot;], &quot;3.0&quot;) &gt;= 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isMinKonq3_1 = compareVersions(RegExp[&quot;$1&quot;], &quot;3.1&quot;) &gt;= 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isMinKonq3_2 = compareVersions(RegExp[&quot;$1&quot;], &quot;3.2&quot;) &gt;= 0;<br />&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; <br />}<br /><br />var isIE = sUserAgent.indexOf(&quot;compatible&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; sUserAgent.indexOf(&quot;MSIE&quot;) &gt; -1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; !isOpera;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />var isMinIE4 = isMinIE5 = isMinIE5_5 = isMinIE6 = false;<br /><br />if (isIE) {<br />&nbsp;&nbsp;&nbsp; var reIE = new RegExp(&quot;MSIE (\\d+\\.\\d+);&quot;);<br />&nbsp;&nbsp;&nbsp; reIE.test(sUserAgent);<br />&nbsp;&nbsp;&nbsp; var fIEVersion = parseFloat(RegExp[&quot;$1&quot;]);<br /><br />&nbsp;&nbsp;&nbsp; isMinIE4 = fIEVersion &gt;= 4;<br />&nbsp;&nbsp;&nbsp; isMinIE5 = fIEVersion &gt;= 5;<br />&nbsp;&nbsp;&nbsp; isMinIE5_5 = fIEVersion &gt;= 5.5;<br />&nbsp;&nbsp;&nbsp; isMinIE6 = fIEVersion &gt;= 6.0;<br />}<br /><br />var isMoz = sUserAgent.indexOf(&quot;Gecko&quot;) &gt; -1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; !isKHTML;<br /><br />var isMinMoz1 = sMinMoz1_4 = isMinMoz1_5 = false;<br /><br />if (isMoz) {<br />&nbsp;&nbsp;&nbsp; var reMoz = new RegExp(&quot;rv:(\\d+\\.\\d+(?:\\.\\d+)?)&quot;);<br />&nbsp;&nbsp;&nbsp; reMoz.test(sUserAgent);<br />&nbsp;&nbsp;&nbsp; isMinMoz1 = compareVersions(RegExp[&quot;$1&quot;], &quot;1.0&quot;) &gt;= 0;<br />&nbsp;&nbsp;&nbsp; isMinMoz1_4 = compareVersions(RegExp[&quot;$1&quot;], &quot;1.4&quot;) &gt;= 0;<br />&nbsp;&nbsp;&nbsp; isMinMoz1_5 = compareVersions(RegExp[&quot;$1&quot;], &quot;1.5&quot;) &gt;= 0;<br />}<br /><br />var isNS4 = !isIE &amp;&amp; !isOpera &amp;&amp; !isMoz &amp;&amp; !isKHTML <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; (sUserAgent.indexOf(&quot;Mozilla&quot;) == 0) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; (navigator.appName == &quot;Netscape&quot;) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; (fAppVersion &gt;= 4.0 &amp;&amp; fAppVersion &lt; 5.0);<br /><br />var isMinNS4 = isMinNS4_5 = isMinNS4_7 = isMinNS4_8 = false;<br /><br />if (isNS4) {<br />&nbsp;&nbsp;&nbsp; isMinNS4 = true;<br />&nbsp;&nbsp;&nbsp; isMinNS4_5 = fAppVersion &gt;= 4.5;<br />&nbsp;&nbsp;&nbsp; isMinNS4_7 = fAppVersion &gt;= 4.7;<br />&nbsp;&nbsp;&nbsp; isMinNS4_8 = fAppVersion &gt;= 4.8;<br />}<br /><br />var isWin = (navigator.platform == &quot;Win32&quot;) || (navigator.platform == &quot;Windows&quot;);<br />var isMac = (navigator.platform == &quot;Mac68K&quot;) || (navigator.platform == &quot;MacPPC&quot;) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || (navigator.platform == &quot;Macintosh&quot;);<br /><br />var isUnix = (navigator.platform == &quot;X11&quot;) &amp;&amp; !isWin &amp;&amp; !isMac;<br /><br />var isWin95 = isWin98 = isWinNT4 = isWin2K = isWinME = isWinXP = false;<br />var isMac68K = isMacPPC = false;<br />var isSunOS = isMinSunOS4 = isMinSunOS5 = isMinSunOS5_5 = false;<br /><br />if (isWin) {<br />&nbsp;&nbsp;&nbsp; isWin95 = sUserAgent.indexOf(&quot;Win95&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;Windows 95&quot;) &gt; -1;<br />&nbsp;&nbsp;&nbsp; isWin98 = sUserAgent.indexOf(&quot;Win98&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;Windows 98&quot;) &gt; -1;<br />&nbsp;&nbsp;&nbsp; isWinME = sUserAgent.indexOf(&quot;Win 9x 4.90&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;Windows ME&quot;) &gt; -1;<br />&nbsp;&nbsp;&nbsp; isWin2K = sUserAgent.indexOf(&quot;Windows NT 5.0&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;Windows 2000&quot;) &gt; -1;<br />&nbsp;&nbsp;&nbsp; isWinXP = sUserAgent.indexOf(&quot;Windows NT 5.1&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;Windows XP&quot;) &gt; -1;<br />&nbsp;&nbsp;&nbsp; isWinNT4 = sUserAgent.indexOf(&quot;WinNT&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;Windows NT&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;WinNT4.0&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;Windows NT 4.0&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; (!isWinME &amp;&amp; !isWin2K &amp;&amp; !isWinXP);<br />} <br /><br />if (isMac) {<br />&nbsp;&nbsp;&nbsp; isMac68K = sUserAgent.indexOf(&quot;Mac_68000&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;68K&quot;) &gt; -1;<br />&nbsp;&nbsp;&nbsp; isMacPPC = sUserAgent.indexOf(&quot;Mac_PowerPC&quot;) &gt; -1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || sUserAgent.indexOf(&quot;PPC&quot;) &gt; -1;&nbsp; <br />}<br /><br />if (isUnix) {<br />&nbsp;&nbsp;&nbsp; isSunOS = sUserAgent.indexOf(&quot;SunOS&quot;) &gt; -1;<br /><br />&nbsp;&nbsp;&nbsp; if (isSunOS) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var reSunOS = new RegExp(&quot;SunOS (\\d+\\.\\d+(?:\\.\\d+)?)&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reSunOS.test(sUserAgent);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isMinSunOS4 = compareVersions(RegExp[&quot;$1&quot;], &quot;4.0&quot;) &gt;= 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isMinSunOS5 = compareVersions(RegExp[&quot;$1&quot;], &quot;5.0&quot;) &gt;= 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isMinSunOS5_5 = compareVersions(RegExp[&quot;$1&quot;], &quot;5.5&quot;) &gt;= 0;<br />&nbsp;&nbsp;&nbsp; }<br />}<br /><br /><br />]]></description>
		</item>
		    
		
		<item>
			<title>oracle的导出与导入</title>
			<link>http://dennnis-zane.blog.sohu.com/31723135.html</link>
			<comments>http://dennnis-zane.blog.sohu.com/31723135.html#comment</comments>
			<dc:creator>花非花</dc:creator>
			<pubDate>Mon, 29 Jan 2007 12:03:20 +0800</pubDate>
			<category>数据库技术</category>
			<guid>http://dennnis-zane.blog.sohu.com/31723135.html</guid>
			<description><![CDATA[

<p><span>一。</span><span style="font-family: 宋体;">新建用户</span></p>

<p><span style="font-family: 宋体;">用管理员登录</span><span style="font-family: 宋体;"></span></p>

<p><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">create</span></b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"> <b>user</b> zhuangxd <b>identified</b> <b>by</b> </span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">zhuangxd </span><span style="font-size: 9pt; font-family: 宋体; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span></p>

<p><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">grant dba,create table to </span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">zhuangxd </span><span style="font-size: 9pt; font-family: 宋体; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">;</span></p>

<p><span style="font-size: 9pt; font-family: 宋体; color: black;">如果</span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">zhuangxd </span><span style="font-size: 9pt; font-family: 宋体; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"> </span><span style="font-size: 9pt; font-family: 宋体; color: black;">用户存在，先删除再建立。</span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span></p>

<p><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">Drop user </span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">zhuangxd </span><span style="font-size: 9pt; font-family: 宋体; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">cascade;</span><span style="font-size: 9pt; font-family: 宋体; color: black;">（保证所有的连接都断开）</span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span></p><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">二。</span><span style="font-size: 9pt; font-family: 宋体; color: black;">导入数据。</span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span>

<p><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">C:&gt;imp</span></b></p>

<p><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">C:&gt;</span></b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">zhuangxd </span><span style="font-size: 9pt; font-family: 宋体; color: black;"></span><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">/</span></b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">zhuangxd </span><span style="font-size: 9pt; font-family: 宋体; color: black;"></span><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">@dennis<span style="">&nbsp; </span></span></b><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">(连接到导入的数据库）</span></b></p>

<p><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">C:&gt;c:\tmp.dmp(</span></b><b><span style="font-size: 9pt; font-family: 宋体; color: black;">要导入的备份文件</span></b><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">)</span></b></p>

<p><b><span style="font-size: 9pt; font-family: 宋体; color: black;">接下来就是一路敲回车，</span></b><b><span style="font-size: 9pt; font-family: 宋体; color: red;">除了：在提示要你输入用户的时候，输入备份文件的用户名(&quot;zhuangxd&quot;)，下面会提到</span></b></p><p>

</p><span style="font-weight: bold;">三。导出数据<br /></span>

<p><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">C:&gt;exp</span></b></p>

<p><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">C:&gt;</span></b><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span></b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">zhuangxd </span><span style="font-size: 9pt; font-family: 宋体; color: black;"></span><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">/</span></b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">zhuangxd </span><span style="font-size: 9pt; font-family: 宋体; color: black;"></span><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">@dennis<span style="">&nbsp;</span></span></b><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"><span style="">&nbsp; </span></span></b><span style="font-size: 9pt; font-family: 宋体; color: black;"></span><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">（连接到要导出的数据库）</span></b></p>

<p><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">C:&gt;c:\tmp.dmp(</span></b><b><span style="font-size: 9pt; font-family: 宋体; color: black;">要导出的备份文件</span></b><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;">)</span></b></p>

<p><b><span style="font-size: 9pt; font-family: 宋体; color: black;">接下来就是一路敲回车，</span></b><b><span style="font-size: 9pt; font-family: 宋体; color: red;">除了：在提示要你输入用户的时候输入&ldquo;</span></b><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: red;">zhuangxd</span></b><b><span style="font-size: 9pt; font-family: 宋体; color: red;">&ldquo;然后回车，这个就是导入时提示你输入的用户名.</span></b><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: red;"></span></b></p>

<p><br /><b><span style="font-size: 9pt; font-family: 宋体; color: red;"></span></b><b><span style="font-size: 9pt; font-family: &quot;Courier New&quot;; color: black;"></span></b></p>

]]></description>
		</item>
		    
		
		<item>
			<title>连接DB2的命令 </title>
			<link>http://dennnis-zane.blog.sohu.com/31078960.html</link>
			<comments>http://dennnis-zane.blog.sohu.com/31078960.html#comment</comments>
			<dc:creator>花非花</dc:creator>
			<pubDate>Wed, 24 Jan 2007 16:54:56 +0800</pubDate>
			<category>数据库技术</category>
			<guid>http://dennnis-zane.blog.sohu.com/31078960.html</guid>
			<description><![CDATA[我们的项目一部分数据在信息中心的DB2上，一部分在oracle上，为什么这样设计我也不清楚。我对oracle已经比较熟悉，DB2还是很少接触，记下基本的连接方式。<br />安装完db2的客户端后，配置下数据库的别名,host等信息。<br />在命令行运行 db2cmd<br />跳出一个db2的命令行工具，然后运行 db2 命令，连接具体数据库的命令为：<br /><br />connect to 数据库别名 user 用户名 using 密码<br /><br />如：<br />connect to datacent user db2admin using db2admin<br />]]></description>
		</item>
		    
		
		<item>
			<title>调用IE内置打印组件完成web打印方案及例程</title>
			<link>http://dennnis-zane.blog.sohu.com/30858649.html</link>
			<comments>http://dennnis-zane.blog.sohu.com/30858649.html#comment</comments>
			<dc:creator>花非花</dc:creator>
			<pubDate>Tue, 23 Jan 2007 09:08:48 +0800</pubDate>
			<category>Ajax及web开发</category>
			<guid>http://dennnis-zane.blog.sohu.com/30858649.html</guid>
			<description><![CDATA[项目是使用OCX控件来做打印单据、票据等功能。web打印本来就是很麻烦的事情，各种报表工具就是做此类工作。曾经做过的一个项目是使用Jaspperreport，搞的很麻烦。还是ocx控件爽。今天根据客户领导要求，新写了一个打印功能，最简单的，直接调用IE内置的组件打印。做个笔记吧。<br /><br /><p>重点：<br />&lt;OBJECT&nbsp; id=WebBrowser&nbsp; classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2&nbsp; height=0&nbsp; width=0 VIEWASTEXT&gt;<br />&nbsp; &lt;/OBJECT&gt;<br /> &lt;input type=button value=打印&nbsp;&nbsp;&nbsp;&nbsp; onclick=&quot;document.all.WebBrowser.ExecWB(6,1)&quot; class=&quot;NOPRINT&quot;&gt;<br />&lt;input type=button value=直接打印 onclick=&quot;document.all.WebBrowser.ExecWB(6,6)&quot; class=&quot;NOPRINT&quot;&gt;<br />&lt;input type=button value=页面设置 onclick=&quot;document.all.WebBrowser.ExecWB(8,1)&quot; class=&quot;NOPRINT&quot;&gt;<br />&lt;input type=button value=打印预览 onclick=&quot;document.all.WebBrowser.ExecWB(7,1)&quot; class=&quot;NOPRINT&quot;&gt;</p>
<p>注意：<br />1、CSS对打印的控制：<br />&lt;!--media=print 这个属性可以在打印时有效--&gt;<br />&lt;style media=print&gt;<br />.Noprint{display:none;}<br />.PageNext{page-break-after: always;}<br />&lt;/style&gt;</p>
<p>Noprint样式可以使页面上的打印按钮等不出现在打印页面上，这一点非常重要，因为它可以用最少的代码完成最需要的功能</p>
<p>PageNext样式可以设置分页，在需要分页的地方&lt;div class=&quot;PageNext&quot;&gt;&lt;/div&gt;就OK了，呵呵</p>
<p>2、表格线粗细的设置，更是通过样式表：</p>
<p>&lt;style&gt;<br />.tdp<br />{<br />&nbsp;&nbsp;&nbsp; border-bottom: 1 solid #000000;<br />&nbsp;&nbsp;&nbsp; border-left:&nbsp; 1 solid #000000;<br />&nbsp;&nbsp;&nbsp; border-right:&nbsp; 0 solid #ffffff;<br />&nbsp;&nbsp;&nbsp; border-top: 0 solid #ffffff;<br />}<br />.tabp<br />{<br />&nbsp;&nbsp;&nbsp; border-color: #000000;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-collapse:collapse;<br />}<br />&lt;/style&gt;</p>
<p>或者：</p>
&lt;style&gt;<br />.TdCs1 {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border:solid windowtext 1.0pt;<br />}<br />.TdCs2 {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border:solid windowtext 1.0pt; border-left:none;<br />}<br />.TdCs3 {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-top:none;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-left:solid windowtext 1.0pt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-bottom:solid windowtext 1.0pt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-right:solid windowtext 1.0pt;<br />}<br />.TdCs4 {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-top:none;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-left:none;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-bottom:solid windowtext 1.0pt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-right:solid windowtext 1.0pt;<br />}<br />.underline {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-top-style: none;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-right-style: none;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-bottom-style: solid;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-left-style: none;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border-bottom-color: #000000;<br />}<br />&lt;/style&gt;<br />]]></description>
		</item>
		    
		
	</channel>
</rss>
