<?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/"
	>

<channel>
	<title>BAsil</title>
	<atom:link href="http://www.basilwang.net/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.basilwang.net</link>
	<description>BAsil &#38;&#38; 糖糖 &#38;&#38; Natasha</description>
	<pubDate>Tue, 31 Aug 2010 10:39:27 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>重构一个贪吃蛇游戏（linux c++)</title>
		<link>http://www.basilwang.net/?p=504</link>
		<comments>http://www.basilwang.net/?p=504#comments</comments>
		<pubDate>Tue, 31 Aug 2010 10:39:27 +0000</pubDate>
		<dc:creator>basil</dc:creator>
		
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.basilwang.net/?p=504</guid>
		<description><![CDATA[最近读dave_cn的[原创]分享自己写的一个贪吃蛇的游戏(Linux) ，C程序写的，就想着用C++重写一下，把面向对象的思想也引入进来。
这里感谢dave_cn，重构后应该有40%的代码是重用的，省了不少功夫。
程序继续采用了ncurses.h库，关于ncurses猛击这里。不知道在window下有没有类似的库（查了一下，可以用conio.h在类dos窗口下实现，有空实现一个window版)。
第一次在linux下用c++写东西，碰到的问题比较多，好歹都解决了，这里也一并做记号。
<span class="readmore"><a href="http://www.basilwang.net/?p=504" title="重构一个贪吃蛇游戏（linux c++)" target="_blank">阅读全文——共2153字</a></span>]]></description>
			<content:encoded><![CDATA[<p>最近读<a href="http://www.cnblogs.com/dave_cn">dave_cn</a>的<a href="http://www.cnblogs.com/dave_cn/archive/2010/07/18/1780317.html">[原创]分享自己写的一个贪吃蛇的游戏(Linux)</a> ，C程序写的，就想着用C++重写一下，把面向对象的思想也引入进来。</p>
<p>这里感谢dave_cn，重构后应该有40%的代码是重用的，省了不少功夫。</p>
<p>程序继续采用了ncurses.h库，关于ncurses<a href="http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/">猛击这里</a>。不知道在window下有没有类似的库（查了一下，可以用conio.h在类dos窗口下实现，有空实现一个window版)。</p>
<p>第一次在linux下用c++写东西，碰到的问题比较多，好歹都解决了，这里也一并做记号。</p>
<p><a href="http://www.basilwang.net/wp-content/uploads/snake.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="snake" border="0" alt="snake" src="http://www.basilwang.net/wp-content/uploads/snake-thumb.jpg" width="492" height="412"></a> </p>
<p>需求比较简单，直接上UML图</p>
<p><a href="http://www.basilwang.net/wp-content/uploads/uml.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="uml" border="0" alt="uml" src="http://www.basilwang.net/wp-content/uploads/uml-thumb.jpg" width="464" height="706"></a></p>
<p>Screen 类 主要负责定时刷新<br />Snake类&nbsp;&nbsp;&nbsp; footprintx,footprinty&nbsp; 由于蛇移动实际就是重绘窗口，所以需要把它走过的痕迹擦掉（用空字符代替*即可),只记录一步痕迹<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list&nbsp; 蛇的身体，采用了双链表，关于双链表<a href="http://baike.baidu.com/view/1627720.htm">猛击这里</a>，代码中调用 dlinkedList.h<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bodyReshape()&nbsp; 每一步移动时，其实就是蛇身体各部位坐标的移动，bodyReshape修改各部位坐标<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eraseFootPrint() 擦除痕迹<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isClapseArea() 是否走到边界<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isSpiralDead() 是否头部碰到身体<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lifeProbing()&nbsp; 生命迹象探测，就是看看是不是还活着<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; move()&nbsp;&nbsp; 移动，在移动的过程会做一些工作，详见时序图<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; receivingNavi() 接受键盘控制蛇头移动方向<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; selfGeneration() 吃到Block后，身体张长<br />LivingArea类 蛇的活动区域<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Block 障碍物，由于一次只有一个障碍，所以LivingArea和Block是1对1的<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blockChecking() 检测障碍物<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isEattingPhase() 是否是吃Block的时刻，当蛇头和Block的坐标相同，即认为是isEattingPhase=true<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isDigestPhase() 未用<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eraseBlock() 将isBlockExisted置为false<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; generateBlock() 生成Block<br />再看一下时序图</p>
<p><a href="http://www.basilwang.net/wp-content/uploads/sequence.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="sequence" border="0" alt="sequence" src="http://www.basilwang.net/wp-content/uploads/sequence-thumb.jpg" width="476" height="805"></a></p>
<p>关于蛇的身体，原c程序采用的是一个倒置的首尾相连的链表,head-&gt;front指向snake的尾部<br />如: [a]&lt;-[b]&lt;-[c]&lt;-[d]&nbsp;&nbsp;&nbsp; a为head<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;&nbsp;&nbsp; ^&nbsp;&nbsp;&nbsp;&nbsp; snake移动的时候,只用head指向d,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; `&#8212;&#8212;&#8212;&#8212;&#8211; &#8216;&nbsp;&nbsp;&nbsp;&nbsp; 并且修改d的(y,x)为snake头移动到的位置.<br />这样的好处是在移动时（身体不增长时），只需要把不用的节点（即上面提到的痕迹）设为头节点，修改其坐标为头的坐标</p>
<p>重构的时候为了简单，用了双链表的源代码，简单的删除痕迹节点，增加新节点，效率不高，简单粗暴。</p>
<p>原c代码</p>
<pre class="code"><span style="color: blue">void </span>movesnake(<span style="color: blue">struct </span><span style="color: #2b91af">TSnake </span>*psnake)
{
 <span style="color: blue">int </span>hy = psnake-&gt;head-&gt;y;
 <span style="color: blue">int </span>hx = psnake-&gt;head-&gt;x;

 psnake-&gt;head = GetSnakeTail(psnake);

 <span style="color: blue">switch </span>(psnake-&gt;dir) {
 <span style="color: blue">case </span>DIR_UP:
     psnake-&gt;head-&gt;y = hy - 1;
     psnake-&gt;head-&gt;x = hx;
     <span style="color: blue">break</span>;

 <span style="color: blue">case </span>DIR_DOWN:
     psnake-&gt;head-&gt;y = hy + 1;
     psnake-&gt;head-&gt;x = hx;
     <span style="color: blue">break</span>;

 <span style="color: blue">case </span>DIR_LEFT:
     psnake-&gt;head-&gt;y = hy;
     psnake-&gt;head-&gt;x = hx - 1;
     <span style="color: blue">break</span>;

 <span style="color: blue">case </span>DIR_RIGHT:
     psnake-&gt;head-&gt;y = hy;
     psnake-&gt;head-&gt;x = hx + 1;
     <span style="color: blue">break</span>;

 <span style="color: blue">default</span>:
     <span style="color: blue">break</span>;
 }
}
</pre>
<p><a href="http://11011.net/software/vspaste"></a>重构后c++代码</p>
<pre class="code"><span style="color: blue">void </span>Snake::bodyReshape()
{
  SnakeNode t;
  list.pop_back(t);
  footprinty=t.y;
  footprintx=t.x;
  list.retrieve(0,t);
  <span style="color: blue">switch </span>(dir)
  {
   <span style="color: blue">case </span>DIR_UP:
     t.y = t.y - 1;
     t.x = t.x;
     <span style="color: blue">break</span>;

   <span style="color: blue">case </span>DIR_DOWN:
     t.y = t.y + 1;
     t.x = t.x;
     <span style="color: blue">break</span>;

   <span style="color: blue">case </span>DIR_LEFT:
     t.y = t.y;
     t.x = t.x - 1;
     <span style="color: blue">break</span>;

   <span style="color: blue">case </span>DIR_RIGHT:
     t.y = t.y;
     t.x = t.x + 1;
     <span style="color: blue">break</span>;

   <span style="color: blue">default</span>:
     <span style="color: blue">break</span>;
  }
  list.insert(0,t);

}
</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>编译：</p>
<p>sudo g++ -o mySnake mySnake.cpp Screen.cpp LivingArea.cpp Snake.cpp SnakeNode.cpp Block.cpp –lncurses</p>
<p>源代码下载</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilwang.net/?feed=rss2&amp;p=504</wfw:commentRss>
		</item>
		<item>
		<title>Ubuntu 9.10 Server 配置Apache + WebDav 实现文档协同管理</title>
		<link>http://www.basilwang.net/?p=497</link>
		<comments>http://www.basilwang.net/?p=497#comments</comments>
		<pubDate>Tue, 01 Jun 2010 08:37:58 +0000</pubDate>
		<dc:creator>basil</dc:creator>
		
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.basilwang.net/?p=497</guid>
		<description><![CDATA[先来了解一下百度百科关于WebDav（Web-based Distributed Authoring and Versioning）的解释
一种基于 HTTP 1.1协议的通信协议.它扩展了HTTP 1.1，在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法，使应用程序可直接对Web Server直接读写，并支持写文件锁定(Locking)及解锁(Unlock)，还可以支持文件的版本控制。

下面来看如何实现文档的协同管理
<span class="readmore"><a href="http://www.basilwang.net/?p=497" title="Ubuntu 9.10 Server 配置Apache + WebDav 实现文档协同管理" target="_blank">阅读全文——共3312字</a></span>]]></description>
			<content:encoded><![CDATA[<p>先来了解一下百度百科关于WebDav（Web-based Distributed Authoring and Versioning）的解释</p>
<blockquote><p>一种基于 HTTP 1.1协议的通信协议.它扩展了HTTP 1.1，在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法，使应用程序可直接对Web Server直接读写，并支持写文件锁定(Locking)及解锁(Unlock)，还可以支持文件的版本控制。</p>
</blockquote>
<p>下面来看如何实现文档的协同管理</p>
<p>1安装软件及模块一览
<p>&nbsp; （1）Apache2.2.14&nbsp; 自己下载编译。未用ubuntu 9.10 server 下apt-get安装的apache2 是因为这个版本的apache2在启用ssl的时候总是报undefined symbol apr_ldap_ssl_init错误，此处我怀疑可能是ubuntu9.10 server的问题,我在虚拟机ubuntu 8.04 desktop下配置成功。
<p>2 加载Dav Module
<p>&nbsp;&nbsp;&nbsp;&nbsp; 在对Apache进行编译时已经开启了dav的设置（具体参见<a href="http://www.basilwang.net/?p=456">Ubuntu 9.10 Server 配置基于SSL的Subversion</a>，svn需要webdav协议支持）
<pre class="code">#sudo ./configure   –enable-dav –enable-dav-fs –enable-so
                    –enable-ssl –enable-maintainer-mode -prefix=/usr/local/apache2
                    –enable-mods-shared=all   </pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注意enable-dav和enable-dav-fs是我们文档协同所需要的。我们可以通过&nbsp;&nbsp;&nbsp;&nbsp; </p>
<pre class="code">cd /usr/local/apache2/bin
sudo ./httpd -l</pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 来查看已加载的Module。另外自主编译的方式无法通过修改httpd.conf,加入</p>
<p>LoadModule dav_module modules/mod_dav.so<br />LoadModule dav_fs_module modules/mod_dav_fs.so</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 来完成，modules文件夹下也没有这两个so文件，启动apache后会报文件已加载，我搞了很长时间才明白这点。</p>
<p>3 配置WebDav</p>
<p>&nbsp;&nbsp; 在httpd.conf文件下 将#Include conf/extra/httpd-dav.conf的注释去掉，我们来看一下httpd-dav.conf的配置</p>
<p>DavLockDB &#8220;/usr/local/apache2/var/DavLock&#8221; </p>
<p>Alias /uploads &#8220;/usr/local/apache2/uploads&#8221;</p>
<p>&lt;Directory &#8220;/usr/local/apache2/uploads&#8221;&gt;<br />&nbsp;&nbsp;&nbsp; Dav On<br />&nbsp;&nbsp;&nbsp; Options Indexes FollowSymLinks<br />&nbsp;&nbsp;&nbsp; Order Allow,Deny<br />&nbsp;&nbsp;&nbsp; Allow from all </p>
<p>&nbsp;&nbsp;&nbsp; AuthType Basic<br />&nbsp;&nbsp;&nbsp; AuthName DAV-upload<br />&nbsp;&nbsp;&nbsp; Require valid-user<br />&nbsp;&nbsp;&nbsp; # You can use the htpasswd program to create the password database:<br />&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp; htpasswd -c &#8220;/usr/local/apache2/user.passwd&#8221; DAV-upload admin<br />&nbsp;&nbsp;&nbsp; AuthUserFile &#8220;/svn/authfile&#8221; <br />&nbsp;&nbsp;&nbsp; &lt;Limit GET OPTIONS PUT POST DELETE PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/Limit&gt;<br />&lt;/Directory&gt;</p>
<p>注意一定是Allow from all 另外我使用了Basic的验证方法，要求用户验证;这里Subversion和WebDav使用的是同样的用户文件;Options Indexes FollowSymLinks允许我们在浏览器访问时遍历文件。</p>
<p>4 权限</p>
<p>&nbsp;&nbsp; #cd /usr/local/apache2<br />&nbsp;&nbsp; #sudo mkdir uploads<br />&nbsp;&nbsp; #sudo chown www-data:www-data uploads<br />&nbsp;&nbsp; #sudo chmod 777 uploads<br />&nbsp;&nbsp; 以上创建上传目录并设置权限为可读可写&nbsp; www-data为ubuntu的用户和组</p>
<p>&nbsp;&nbsp; 另外可能需要手动创建 DavLockDB<br />&nbsp;&nbsp; #cd /usr/local/apache2<br />&nbsp;&nbsp; #sudo mkdir var<br />&nbsp;&nbsp; #cd var<br />&nbsp;&nbsp; #sudo vim DavLock<br />&nbsp;&nbsp; #cd ..<br />&nbsp;&nbsp; #cd ..<br />&nbsp;&nbsp; #sudo chown www-data:www-data uploads<br />&nbsp;&nbsp; #sudo chmod -R 777 var/</p>
<p>5 WebDav客户端</p>
<p>&nbsp; 分别使用了XP和Vista自带的web folder</p>
<p>&nbsp;&nbsp; 使用方法，在XP的资源管理器下选择增加网上邻居（Vista为添加一个网络位置）输入http://your ip or sitename/uploads&nbsp; 并输入用户名和密码。然后再word里就可以直接对文件进行增加修改了，而且当一个用户在更改的时候，其他用户只能只读访问。</p>
<p>&nbsp;&nbsp; <img style="border-bottom: 0px; border-left: 0px; margin: 1px; display: inline; border-top: 0px; border-right: 0px" title="webfolder" border="0" alt="webfolder" src="http://www.basilwang.net/wp-content/uploads/webfolder.gif" width="547" height="439"> </p>
<p>当一个用户打开某文件，会加一个只读锁，其他的用户打开该文件时提示</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="conflict" border="0" alt="conflict" src="http://www.basilwang.net/wp-content/uploads/conflict.gif" width="547" height="439"> </p>
<p>最后附上fiddler抓到的http包,（webdav协议是http协议的扩展，所以可以观察到)</p>
<p>HTTP/1.1 207 Multi-Status<br />Date: Tue, 01 Jun 2010 08:30:34 GMT<br />Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8g DAV/2 SVN/1.6.2<br />Content-Length: 966<br />Keep-Alive: timeout=5, max=100<br />Connection: Keep-Alive<br />Content-Type: text/xml; charset=&#8221;utf-8&#8243; </p>
<p>&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;<br />&lt;D:multistatus xmlns:D=&#8221;DAV:&#8221;&gt;<br />&lt;D:response xmlns:lp1=&#8221;DAV:&#8221; xmlns:lp3=&#8221;<a href="http://subversion.tigris.org/xmlns/dav/&quot;">http://subversion.tigris.org/xmlns/dav/&#8221;</a> xmlns:lp2=&#8221;<a href="http://apache.org/dav/props/&quot;">http://apache.org/dav/props/&#8221;</a>&gt;<br />&lt;D:href&gt;/uploads/blackjack/Post.doc&lt;/D:href&gt;<br />&lt;D:propstat&gt;<br />&lt;D:prop&gt;<br />&lt;lp1:resourcetype/&gt;<br />&lt;lp1:creationdate&gt;2010-06-01T06:11:10Z&lt;/lp1:creationdate&gt;<br />&lt;lp1:getcontentlength&gt;46080&lt;/lp1:getcontentlength&gt;<br />&lt;lp1:getlastmodified&gt;Tue, 01 Jun 2010 06:11:10 GMT&lt;/lp1:getlastmodified&gt;<br />&lt;lp1:getetag&gt;&#8221;23a06-b400-487f1d6fea216&#8243;&lt;/lp1:getetag&gt;<br />&lt;lp2:executable&gt;F&lt;/lp2:executable&gt;<br />&lt;D:supportedlock&gt;<br />&lt;D:lockentry&gt;<br />&lt;D:lockscope&gt;&lt;D:exclusive/&gt;&lt;/D:lockscope&gt;<br />&lt;D:locktype&gt;&lt;D:write/&gt;&lt;/D:locktype&gt;<br />&lt;/D:lockentry&gt;<br />&lt;D:lockentry&gt;<br />&lt;D:lockscope&gt;&lt;D:shared/&gt;&lt;/D:lockscope&gt;<br />&lt;D:locktype&gt;&lt;D:write/&gt;&lt;/D:locktype&gt;<br />&lt;/D:lockentry&gt;<br />&lt;/D:supportedlock&gt;<br />&lt;D:lockdiscovery/&gt;<br />&lt;D:getcontenttype&gt;application/msword&lt;/D:getcontenttype&gt;<br />&lt;/D:prop&gt;<br />&lt;D:status&gt;HTTP/1.1 200 OK&lt;/D:status&gt;<br />&lt;/D:propstat&gt;<br />&lt;/D:response&gt;<br />&lt;/D:multistatus&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilwang.net/?feed=rss2&amp;p=497</wfw:commentRss>
		</item>
		<item>
		<title>javascript事件机制与jQuery.bind的补充说明</title>
		<link>http://www.basilwang.net/?p=494</link>
		<comments>http://www.basilwang.net/?p=494#comments</comments>
		<pubDate>Mon, 10 May 2010 09:38:02 +0000</pubDate>
		<dc:creator>basil</dc:creator>
		
		<category><![CDATA[javascript+css]]></category>

		<guid isPermaLink="false">http://www.basilwang.net/?p=494</guid>
		<description><![CDATA[在之前的文章javascript 事件机制 与 jQuery.Bind中，为了说明冒泡阶段中Event Handler Function的表现，我使用了event.data来记录触发function的次数。并且提出了一个问题，就是在jQuery.bind方式中,event.data无法正确记录触发的次数。后来经过测试和查阅网上的相关的资料，得出了一个结论，就是我之前关于event.data的使用方式是错误的，或者说对于跨浏览器的支持是困难的。同时我也意识到，由于event.data在w3c dom level 2文档中，并不是作为event的标准属性出现的，所以jQuery对event进行了fix,使其能够兼容各个浏览器。
<span class="readmore"><a href="http://www.basilwang.net/?p=494" title="javascript事件机制与jQuery.bind的补充说明" target="_blank">阅读全文——共5100字</a></span>]]></description>
			<content:encoded><![CDATA[<p>在之前的文章<a href="http://www.basilwang.net/?p=492">javascript 事件机制 与 jQuery.Bind</a>中，为了说明冒泡阶段中Event Handler Function的表现，我使用了event.data来记录触发function的次数。并且提出了一个问题，就是在jQuery.bind方式中,event.data无法正确记录触发的次数。后来经过测试和查阅网上的相关的资料，得出了一个结论，就是我之前关于event.data的使用方式是错误的，或者说对于跨浏览器的支持是困难的。同时我也意识到，由于event.data在w3c dom level 2文档中，并不是作为event的标准属性出现的，所以jQuery对event进行了fix,使其能够兼容各个浏览器。</p>
<p>在我纠正误用event.data的方式之前，再描述一下我对event的理解。在我查看jQuery(1.3.2)源代码的时候，jQuery.event的add方法中有如下代码</p>
<pre class="code"><span style="color: green">// Init the element's event structure
</span><span style="color: blue">var </span>events = jQuery.data(elem, <span style="color: #a31515">"events"</span>) || jQuery.data(elem, <span style="color: #a31515">"events"</span>, {}),
    handle = jQuery.data(elem, <span style="color: #a31515">"handle"</span>) || jQuery.data(elem, <span style="color: #a31515">"handle"</span>, <span style="color: blue">function</span>() {
         <span style="color: green">// Handle the second event of a trigger and when
         // an event is called after a page has unloaded
         </span><span style="color: blue">return typeof </span>jQuery !== <span style="color: #a31515">"undefined" </span>&amp;&amp; !jQuery.event.triggered ?
                jQuery.event.handle.apply(arguments.callee.elem, arguments) :
                undefined;
        });</pre>
<p><a href="http://11011.net/software/vspaste"></a>其中的jQuery.event.handle中进行event的fix</p>
<pre class="code">event = arguments[0] = jQuery.event.fix(event || window.event);</pre>
<p>这里按照网上的资料大多是说ie下使用window.event,而firefox下使用arguments[0]也就是传递过来的函数参数event。可我在测试中发现ie6,ie7(未测试）,ie8在fix之前event并不为空，也就是说在fix的时候并没有使用window.event。</p>
<p>看一下这段代码</p>
<pre class="code"><span style="color: blue">&lt;!</span><span style="color: #a31515">DOCTYPE </span><span style="color: red">html PUBLIC </span><span style="color: blue">"-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;</span><span style="color: #a31515">html </span><span style="color: red">xmlns</span><span style="color: blue">="http://www.w3.org/1999/xhtml" </span><span style="color: red">lang</span><span style="color: blue">="zh-CN"&gt;
&lt;</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">meta </span><span style="color: red">http-equiv</span><span style="color: blue">="Content-Type" </span><span style="color: red">content</span><span style="color: blue">="text/html; charset=utf-8"    /&gt;
&lt;</span><span style="color: #a31515">title</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">title</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
     </span><span style="color: #a31515">#panelGrandPa</span>,<span style="color: #a31515">#panelPaPa</span>,<span style="color: #a31515">#panelSon  </span>{ <span style="color: red">border</span>:<span style="color: blue">1px  solid #320213</span>;}
 <span style="color: blue">&lt;/</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
 &lt;</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelGrandPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">300px</span>;<span style="color: red">height</span>:<span style="color: blue">200px</span>;<span style="color: blue">" &gt;
       &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelPaPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">200px</span>;<span style="color: red">height</span>:<span style="color: blue">100px</span>;<span style="color: blue">" &gt;
            &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelSon" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">100px</span>;<span style="color: red">height</span>:<span style="color: blue">50px</span>;<span style="color: blue">" &gt;

            &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
       &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
    function </span>click() {
        alert(event.srcElement.id);
        event.data = event.data || 1;
        alert(<span style="color: #a31515">"click function has fired  " </span>+ event.data + <span style="color: #a31515">" times"</span>);
        event.data = parseInt(event.data) + 1;
    }
    <span style="color: blue">function </span>clickSon() {
        alert(<span style="color: #a31515">"I am son"</span>);
        click();
    }
    <span style="color: blue">function </span>clickGrandPa() {
        alert(<span style="color: #a31515">"I am GrandPa"</span>);
        click();
    }
    document.getElementById(<span style="color: #a31515">"panelGrandPa"</span>).onclick = clickGrandPa;
    document.getElementById(<span style="color: #a31515">"panelSon"</span>).onclick = clickSon;
<span style="color: blue">&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">html</span><span style="color: blue">&gt;</span><span style="color: blue">
</span></pre>
<p>只能在ie8下正常工作，在ie6和ie7下都报event.data undefined错误。当然我们这里使用的是window.event也就是页面维护的event相当于全局变量，那我们再试一下事件方法的event参数（之前阅读jQuery源代码提到的ie中除却window.event另外的event）</p>
<pre class="code"><span style="color: blue">&lt;!</span><span style="color: #a31515">DOCTYPE </span><span style="color: red">html PUBLIC </span><span style="color: blue">"-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;</span><span style="color: #a31515">html </span><span style="color: red">xmlns</span><span style="color: blue">="http://www.w3.org/1999/xhtml" </span><span style="color: red">lang</span><span style="color: blue">="zh-CN"&gt;
&lt;</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">meta </span><span style="color: red">http-equiv</span><span style="color: blue">="Content-Type" </span><span style="color: red">content</span><span style="color: blue">="text/html; charset=utf-8"    /&gt;
&lt;</span><span style="color: #a31515">title</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">title</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
     </span><span style="color: #a31515">#panelGrandPa</span>,<span style="color: #a31515">#panelPaPa</span>,<span style="color: #a31515">#panelSon  </span>{ <span style="color: red">border</span>:<span style="color: blue">1px  solid #320213</span>;}
 <span style="color: blue">&lt;/</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
 &lt;</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelGrandPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">300px</span>;<span style="color: red">height</span>:<span style="color: blue">200px</span>;<span style="color: blue">" &gt;
       &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelPaPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">200px</span>;<span style="color: red">height</span>:<span style="color: blue">100px</span>;<span style="color: blue">" &gt;
            &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelSon" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">100px</span>;<span style="color: red">height</span>:<span style="color: blue">50px</span>;<span style="color: blue">" &gt;

            &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
       &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
    function </span>click(e) {
        alert(event.srcElement.id);
        e.data = e.data || 1;
        alert(<span style="color: #a31515">"click function has fired  " </span>+ e.data + <span style="color: #a31515">" times"</span>);
        e.data = parseInt(e.data) + 1;
    }
    <span style="color: blue">function </span>clickSon() {
        alert(<span style="color: #a31515">"I am son"</span>);
        click(arguments[0]);
    }
    <span style="color: blue">function </span>clickGrandPa() {
        alert(<span style="color: #a31515">"I am GrandPa"</span>);
        click(arguments[0]);
    }
    document.getElementById(<span style="color: #a31515">"panelGrandPa"</span>).attachEvent(<span style="color: #a31515">"onclick"</span>, clickGrandPa);
    document.getElementById(<span style="color: #a31515">"panelSon"</span>).attachEvent(<span style="color: #a31515">"onclick"</span>, clickSon);
<span style="color: blue">&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">html</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>注意必须用attachEvent我们才能得到区别于window.event的“另一个”event。以上代码在ie8下正常工作，在ie6和ie7下event.data始终为1</p>
<p>对于window.event，在ie6和ie7下，通过调试工具发现其中并没有event.data的属性。而attachEvent的得到的event.data 在ie6和ie7下不能正确计数，始终为1，但ie8下正确。</p>
<p>鉴于event在各浏览器下的差异以及我们对书写跨浏览器脚本的良好愿望，我个人认为不应该在多个事件方法中传递event.data。</p>
<p>当然jQuery在这方面做得更好经过fix后的event 使得event.data在各种浏览器下表现一致</p>
<pre class="code"><span style="color: blue">&lt;!</span><span style="color: #a31515">DOCTYPE </span><span style="color: red">html PUBLIC </span><span style="color: blue">"-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;</span><span style="color: #a31515">html </span><span style="color: red">xmlns</span><span style="color: blue">="http://www.w3.org/1999/xhtml" </span><span style="color: red">lang</span><span style="color: blue">="zh-CN"&gt;
&lt;</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">meta </span><span style="color: red">http-equiv</span><span style="color: blue">="Content-Type" </span><span style="color: red">content</span><span style="color: blue">="text/html; charset=utf-8"    /&gt;
 &lt;</span><span style="color: #a31515">script </span><span style="color: red">type</span><span style="color: blue">="text/javascript" </span><span style="color: red">src</span><span style="color: blue">="http://jqueryjs.googlecode.com/files/jquery-1.3.2.js"&gt;&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">title</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">title</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
     </span><span style="color: #a31515">#panelGrandPa</span>,<span style="color: #a31515">#panelPaPa</span>,<span style="color: #a31515">#panelSon  </span>{ <span style="color: red">border</span>:<span style="color: blue">1px  solid #320213</span>;}
 <span style="color: blue">&lt;/</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelGrandPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">300px</span>;<span style="color: red">height</span>:<span style="color: blue">200px</span>;<span style="color: blue">" &gt;
       &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelPaPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">200px</span>;<span style="color: red">height</span>:<span style="color: blue">100px</span>;<span style="color: blue">" &gt;
            &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelSon" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">100px</span>;<span style="color: red">height</span>:<span style="color: blue">50px</span>;<span style="color: blue">" &gt;

            &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
       &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
    function </span>click(e) {
        alert(e.target.id);
        e.data = e.data || 1;
        alert(<span style="color: #a31515">"click function has fired  " </span>+ e.data + <span style="color: #a31515">" times"</span>);
        e.data = parseInt(e.data) + 1;
    }
    <span style="color: blue">function </span>clickSon(e) {
        alert(<span style="color: #a31515">"I am son"</span>);
        click(e);
    }
    <span style="color: blue">function </span>clickGrandPa(e) {
        alert(<span style="color: #a31515">"I am GrandPa"</span>);
        click(e);
    }
    $(<span style="color: #a31515">"#panelGrandPa"</span>).bind(<span style="color: #a31515">"click"</span>, clickGrandPa);
    $(<span style="color: #a31515">"#panelSon"</span>).bind(<span style="color: #a31515">"click"</span>, clickSon);
<span style="color: blue">&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">html</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a>上述代码在任何浏览器下都不能正常计数，显示event.data为1（这下ie8也不行了）。</p>
<p>我们分析一下原因，这也是我对上一篇提出问题的一个回答</p>
<p>jQuery.event.add方法封装了attachEvent/addEventListener并且给每一个handler方法附加了data</p>
<pre class="code">add:<span style="color: blue">function</span>(elem, types, handler, data) {
    <span style="color: green">//省略部分代码
    // if data is passed, bind to handler
    </span><span style="color: blue">if </span>(data !== undefined) {
        <span style="color: green">// Create temporary function pointer to original handler
        </span><span style="color: blue">var </span>fn = handler;

        <span style="color: green">// Create unique handler function, wrapped around original handler
        </span>handler = <span style="color: blue">this</span>.proxy(fn);

        <span style="color: green">// Store data in unique handler
        </span>handler.data = data;
    }
    <span style="color: green">//省略部分代码
</span>}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>在jQuery.event的fix方法中，我们看到其将传入的event复制了一份（包括data)，注意不是引用（这意味着每次方法的event都是不同的）</p>
<pre class="code">fix: <span style="color: blue">function</span>(event) {
    <span style="color: blue">if </span>(event[expando])
        <span style="color: blue">return </span>event;

    <span style="color: green">// store a copy of the original event object
    // and "clone" to set read-only properties
    </span><span style="color: blue">var </span>originalEvent = event;
    event = jQuery.Event(originalEvent);

    <span style="color: blue">for </span>(<span style="color: blue">var </span>i = <span style="color: blue">this</span>.props.length, prop; i; ) {
        prop = <span style="color: blue">this</span>.props[--i];
        event[prop] = originalEvent[prop];
    }
    <span style="color: green">//以下省略
</span>}</pre>
<p>那么这样一来，我们肯定不能在多个事件方法中用上述方法传递data了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilwang.net/?feed=rss2&amp;p=494</wfw:commentRss>
		</item>
		<item>
		<title>javascript 事件机制 与 jQuery.Bind</title>
		<link>http://www.basilwang.net/?p=492</link>
		<comments>http://www.basilwang.net/?p=492#comments</comments>
		<pubDate>Sun, 09 May 2010 00:03:52 +0000</pubDate>
		<dc:creator>basil</dc:creator>
		
		<category><![CDATA[javascript+css]]></category>

		<guid isPermaLink="false">http://www.basilwang.net/?p=492</guid>
		<description><![CDATA[W3C DOM Level2的事件模型规范中，事件在DOM树中的传播过程（从根节点到目标节点）被分为了两个阶段：捕捉（Capture）和冒泡（Bubbling）,而事件在传递的过程中需要先经历Capture Phrase后经历Bubble Phrase 。在firefox下，我们可以用target.addEventListener(type, listener, useCapture),第三个参数指定是否为Capture；但IE不支持捕获，而且jQuery也不支持Capture(不过我觉得Bubbling足够了）。因此后面的讨论主要在Bubbling阶段。首先看一下IE下实现事件模型的代码。
<span class="readmore"><a href="http://www.basilwang.net/?p=492" title="javascript 事件机制 与 jQuery.Bind" target="_blank">阅读全文——共3650字</a></span>]]></description>
			<content:encoded><![CDATA[<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image_1" border="0" alt="image_1" align="right" src="http://www.basilwang.net/wp-content/uploads/image-14.jpg" width="355" height="316"></p>
<p>W3C DOM Level2的事件模型规范中，事件在DOM树中的传播过程（从根节点到目标节点）被分为了两个阶段：捕捉（Capture）和冒泡（Bubbling）,而事件在传递的过程中需要先经历Capture Phrase后经历Bubble Phrase 。在firefox下，我们可以用target.addEventListener(type, listener, useCapture),第三个参数指定是否为Capture；但IE不支持捕获，而且jQuery也不支持Capture(不过我觉得Bubbling足够了）。因此后面的讨论主要在Bubbling阶段。首先看一下IE下实现事件模型的代码。</p>
<p>请在IE8下运行以下代码(只能在ie8下运行)</p>
<pre class="code"><span style="color: blue">&lt;!</span><span style="color: #a31515">DOCTYPE </span><span style="color: red">html PUBLIC </span><span style="color: blue">"-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;</span><span style="color: #a31515">html </span><span style="color: red">xmlns</span><span style="color: blue">="http://www.w3.org/1999/xhtml" </span><span style="color: red">lang</span><span style="color: blue">="zh-CN"&gt;
&lt;</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">meta </span><span style="color: red">http-equiv</span><span style="color: blue">="Content-Type" </span><span style="color: red">content</span><span style="color: blue">="text/html; charset=utf-8"    /&gt;
&lt;</span><span style="color: #a31515">title</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">title</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
     </span><span style="color: #a31515">#panelGrandPa</span>,<span style="color: #a31515">#panelPaPa</span>,<span style="color: #a31515">#panelSon  </span>{ <span style="color: red">border</span>:<span style="color: blue">1px  solid #320213</span>;}
 <span style="color: blue">&lt;/</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
 &lt;</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelGrandPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">300px</span>;<span style="color: red">height</span>:<span style="color: blue">200px</span>;<span style="color: blue">" &gt;
       &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelPaPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">200px</span>;<span style="color: red">height</span>:<span style="color: blue">100px</span>;<span style="color: blue">" &gt;
            &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelSon" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">100px</span>;<span style="color: red">height</span>:<span style="color: blue">50px</span>;<span style="color: blue">" &gt;

            &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
       &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
    function </span>click() {
        alert(event.srcElement.id);
        event.data = event.data || 1;
        alert(<span style="color: #a31515">"click function has fired  " </span>+ event.data + <span style="color: #a31515">" times"</span>);
        event.data = parseInt(event.data) + 1;
    }
    <span style="color: blue">function </span>clickSon() {
        alert(<span style="color: #a31515">"I am son"</span>);
        click();
    }
    <span style="color: blue">function </span>clickGrandPa() {
        alert(<span style="color: #a31515">"I am GrandPa"</span>);
        click();
    }
    document.getElementById(<span style="color: #a31515">"panelGrandPa"</span>).onclick = clickGrandPa;
    document.getElementById(<span style="color: #a31515">"panelSon"</span>).onclick = clickSon;
<span style="color: blue">&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">html</span><span style="color: blue">&gt;

</span></pre>
<p>注意传统element.onclick或者element['on'+eventName]，这个是所有浏览器都支持的事件绑定的Event Listener，但由于上述代码使用了event.srcElement.id，因此只能在IE8下运行。下面看一下在firefox下的使用，这里我们采用了符合W3C DOM的target.addEventListener(type, listener, useCapture)，另外使用了event.target.id。 <br />请在firefox,chrome下运行以下代码</p>
<pre class="code"><span style="color: blue">&lt;!</span><span style="color: #a31515">DOCTYPE </span><span style="color: red">html PUBLIC </span><span style="color: blue">"-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;</span><span style="color: #a31515">html </span><span style="color: red">xmlns</span><span style="color: blue">="http://www.w3.org/1999/xhtml" </span><span style="color: red">lang</span><span style="color: blue">="zh-CN"&gt;
&lt;</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">meta </span><span style="color: red">http-equiv</span><span style="color: blue">="Content-Type" </span><span style="color: red">content</span><span style="color: blue">="text/html; charset=utf-8"    /&gt;
&lt;</span><span style="color: #a31515">title</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">title</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
     </span><span style="color: #a31515">#panelGrandPa</span>,<span style="color: #a31515">#panelPaPa</span>,<span style="color: #a31515">#panelSon  </span>{ <span style="color: red">border</span>:<span style="color: blue">1px  solid #320213</span>;}
 <span style="color: blue">&lt;/</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelGrandPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">300px</span>;<span style="color: red">height</span>:<span style="color: blue">200px</span>;<span style="color: blue">" &gt;
       &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelPaPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">200px</span>;<span style="color: red">height</span>:<span style="color: blue">100px</span>;<span style="color: blue">" &gt;
            &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelSon" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">100px</span>;<span style="color: red">height</span>:<span style="color: blue">50px</span>;<span style="color: blue">" &gt;

            &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
       &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
    function </span>click(e) {
        alert(e.target.id);
        e.data = e.data || 1;
        alert(<span style="color: #a31515">"click function has fired  " </span>+ e.data + <span style="color: #a31515">" times"</span>);
        e.data = parseInt(e.data) + 1;
    }
    <span style="color: blue">function </span>clickSon(e) {
        alert(<span style="color: #a31515">"I am son"</span>);
        click(e);
    }
    <span style="color: blue">function </span>clickGrandPa(e) {
        alert(<span style="color: #a31515">"I am GrandPa"</span>);
        click(e);
    }
    document.getElementById(<span style="color: #a31515">"panelGrandPa"</span>).addEventListener(<span style="color: #a31515">"click"</span>, clickGrandPa, <span style="color: blue">false</span>);
    document.getElementById(<span style="color: #a31515">"panelSon"</span>).addEventListener(<span style="color: #a31515">"click"</span>, clickSon, <span style="color: blue">false</span>);
<span style="color: blue">&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">html</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>那么在jQuery中我们是怎么处理的呢</p>
<pre class="code"><span style="color: blue">&lt;!</span><span style="color: #a31515">DOCTYPE </span><span style="color: red">html PUBLIC </span><span style="color: blue">"-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;</span><span style="color: #a31515">html </span><span style="color: red">xmlns</span><span style="color: blue">="http://www.w3.org/1999/xhtml" </span><span style="color: red">lang</span><span style="color: blue">="zh-CN"&gt;
&lt;</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">meta </span><span style="color: red">http-equiv</span><span style="color: blue">="Content-Type" </span><span style="color: red">content</span><span style="color: blue">="text/html; charset=utf-8"    /&gt;
 &lt;</span><span style="color: #a31515">script </span><span style="color: red">type</span><span style="color: blue">="text/javascript" </span><span style="color: red">src</span><span style="color: blue">="http://jqueryjs.googlecode.com/files/jquery-1.3.2.js"&gt;&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">title</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">title</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
     </span><span style="color: #a31515">#panelGrandPa</span>,<span style="color: #a31515">#panelPaPa</span>,<span style="color: #a31515">#panelSon  </span>{ <span style="color: red">border</span>:<span style="color: blue">1px  solid #320213</span>;}
 <span style="color: blue">&lt;/</span><span style="color: #a31515">style</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelGrandPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">300px</span>;<span style="color: red">height</span>:<span style="color: blue">200px</span>;<span style="color: blue">" &gt;
       &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelPaPa" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">200px</span>;<span style="color: red">height</span>:<span style="color: blue">100px</span>;<span style="color: blue">" &gt;
            &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="panelSon" </span><span style="color: red">style</span><span style="color: blue">="</span><span style="color: red">width</span>:<span style="color: blue">100px</span>;<span style="color: red">height</span>:<span style="color: blue">50px</span>;<span style="color: blue">" &gt;

            &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
       &lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
    function </span>click(e) {
        alert(e.target.id);
        e.data = e.data || 1;
        alert(<span style="color: #a31515">"click function has fired  " </span>+ e.data + <span style="color: #a31515">" times"</span>);
        e.data = parseInt(e.data) + 1;
    }
    <span style="color: blue">function </span>clickSon(e) {
        alert(<span style="color: #a31515">"I am son"</span>);
        click(e);
    }
    <span style="color: blue">function </span>clickGrandPa(e) {
        alert(<span style="color: #a31515">"I am GrandPa"</span>);
        click(e);
    }
    $(<span style="color: #a31515">"#panelGrandPa"</span>).bind(<span style="color: #a31515">"click"</span>, clickGrandPa);
    $(<span style="color: #a31515">"#panelSon"</span>).bind(<span style="color: #a31515">"click"</span>, clickSon);
<span style="color: blue">&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">html</span><span style="color: blue">&gt;
</span></pre>
<p>这里使用了e.target，不过和之前的非jQuery版本不同，此处的e(event)是调用了jQuery.event.fix(event),也就是说jQuery的处理让event更加透明。不过这段代码的运行还是有问题的，就是click function的fire time 始终为1，也就是说e.data的值无法在多个事件函数里传递，这个我暂时还没有找到原因；不过希望通过进一步探究jQuery源代码找到问题原因及解决思路，本文旨在说明javascript 事件机制 与 jQuery.Bind的简单用法，就此搁笔了，关于前面抛出的问题，也请各位不吝赐教。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilwang.net/?feed=rss2&amp;p=492</wfw:commentRss>
		</item>
		<item>
		<title>Ubuntu 9.10 Server 配置基于SSL的Subversion</title>
		<link>http://www.basilwang.net/?p=456</link>
		<comments>http://www.basilwang.net/?p=456#comments</comments>
		<pubDate>Tue, 09 Feb 2010 12:15:36 +0000</pubDate>
		<dc:creator>basil</dc:creator>
		
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.basilwang.net/?p=456</guid>
		<description><![CDATA[1 配置准备
&#160; Ubuntu 9.10 Server 英文版。服务器版还是以稳定高效为主，也没有安装图形界面，另外主要是通过putty.exe远程访问。没有采用中文版的原因是，在shell下，中文字体可能没有安装总显示乱码，拜过谷哥大神，未解决。
2 安装软件及模块一览 
&#160; （1）Apache2.2.14&#160; 自己下载编译。未用ubuntu 9.10 server 下apt-get安装的apache2 是因为这个版本的apache2在启用ssl的时候总是报undefined symbol apr_ldap_ssl_init错误，此处我怀疑可能是ubuntu9.10 server的问题,我在虚拟机ubuntu 8.04 desktop下配置成功。
<span class="readmore"><a href="http://www.basilwang.net/?p=456" title="Ubuntu 9.10 Server 配置基于SSL的Subversion" target="_blank">阅读全文——共5463字</a></span>]]></description>
			<content:encoded><![CDATA[<p>1 配置准备</p>
<p>&#160; Ubuntu 9.10 Server 英文版。服务器版还是以稳定高效为主，也没有安装图形界面，另外主要是通过<a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">putty.exe</a>远程访问。没有采用中文版的原因是，在shell下，中文字体可能没有安装总显示乱码，拜过谷哥大神，未解决。</p>
<p>2 安装软件及模块一览 </p>
<p>&#160; （1）Apache2.2.14&#160; 自己下载编译。未用ubuntu 9.10 server 下apt-get安装的apache2 是因为这个版本的apache2在启用ssl的时候总是报undefined symbol apr_ldap_ssl_init错误，此处我怀疑可能是ubuntu9.10 server的问题,我在虚拟机ubuntu 8.04 desktop下配置成功。</p>
<p>&#160; （2）OpenSSL 通过apt-get install openssl 安装即可</p>
<p>&#160; （3）Subversion 自己编译下载。很不幸，我无法使用ubuntu的subversion来成功配置SSL。</p>
<p>3 Ubuntu &amp; Linux&#160;&#160; </p>
<p>鉴于大家可能对不同发行版的linux不太了解，我简单介绍一下，并比较apache2的Ubuntu版本和自主安装的安装及配置文件路径</p>
<p>&#160;&#160; 以下摘自Wiki</p>
<blockquote><p>&#160;&#160;&#160;&#160; One can distinguish between commercially backed distributions, such as <a href="http://en.wikipedia.org/wiki/Fedora_%28operating_system%29">Fedora</a> (<a href="http://en.wikipedia.org/wiki/Red_Hat">Red Hat</a>), <a href="http://en.wikipedia.org/wiki/OpenSUSE">openSUSE</a> (<a href="http://en.wikipedia.org/wiki/Novell">Novell</a>), <a href="http://en.wikipedia.org/wiki/Ubuntu_%28operating_system%29">Ubuntu</a> (<a href="http://en.wikipedia.org/wiki/Canonical_Ltd.">Canonical Ltd.</a>), and <a href="http://en.wikipedia.org/wiki/Mandriva_Linux">Mandriva Linux</a> (<a href="http://en.wikipedia.org/wiki/Mandriva">Mandriva</a>) and entirely community-driven distributions such as <a href="http://en.wikipedia.org/wiki/Debian">Debian</a> and <a href="http://en.wikipedia.org/wiki/Gentoo_Linux">Gentoo</a>, though there are other distributions that are driven neither by a corporation nor a community, perhaps most famously <a href="http://en.wikipedia.org/wiki/Slackware">Slackware</a>.</p>
</blockquote>
<p>简单翻译一下，就是说linux有商业支持的发行版如Fedora,openSUSE,Ubuntu和社区推动的版本如Debian和Gentoo。另外Ubuntu本身又是基于Debian的，这点大家应该清楚。</p>
<p>&#160;&#160;&#160; </p>
<table border="0" cellspacing="0" cellpadding="2" width="747">
<tbody>
<tr>
<td valign="top" width="142">&#160;</td>
<td valign="top" width="282">Ubuntu Apache2</td>
<td valign="top" width="321">自主安装Apache2</td>
</tr>
<tr>
<td valign="top" width="142">安装目录</td>
<td valign="top" width="282">/etc/apache2         </td>
<td valign="top" width="321">指定路径         <br />例如：          <br />/usr/local/apache2          </td>
</tr>
<tr>
<td valign="top" width="142">应用程序</td>
<td valign="top" width="282">/etc/sbin/apache2         <br />/etc/lib/apache2</td>
<td valign="top" width="321">/usr/local/apache2/bin/httpd</td>
</tr>
<tr>
<td valign="top" width="142">服务</td>
<td valign="top" width="282">/etc/init.d/apache2&#160; restart</td>
<td valign="top" width="321">/usr/local/apache2/bin/httpd –k restart&#160; <br />（不知还有没有别的方式？)</td>
</tr>
<tr>
<td valign="top" width="142">配置文件</td>
<td valign="top" width="282">/etc/apache2/apache2.conf         <br />/etc/apache2/httpd.conf (通常为空）          <br />/etc/apache2/ports.conf          <br />/etc/apache2/mods_available/          <br />/etc/apache2/sites_available/          <br />apache2.conf负责调用其他的配置文件</td>
<td valign="top" width="321">/usr/local/apache2/conf/httpd.conf         <br />/usr/local/apache2/conf/extra/          <br />httpd.conf负责调用extra文件夹下的配置文件</td>
</tr>
</tbody>
</table>
<p>4 自主安装Apache2</p>
<p>#sudo wget <a title="http://apache.etoak.com/httpd/httpd-2.2.14.tar.gz" href="http://apache.etoak.com/httpd/httpd-2.2.14.tar.gz">http://apache.etoak.com/httpd/httpd-2.2.14.tar.gz</a>    <br />#sudo tar -zxvf httpd-2.2.14.tar.gz&#160;&#160;&#160;&#160; <br />#cd httpd-2.2.14&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />#sudo ./configure&#160;&#160; &#8211;enable-dav &#8211;enable-dav-fs &#8211;enable-so&#160;&#160; &#8211;enable-ssl &#8211;enable-maintainer-mode -prefix=/usr/local/apache2&#160;&#160; &#8211;enable-mods-shared=all&#160;&#160;&#160; <br />#sudo make&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />#sudo make install</p>
<p>&#160;&#160; 注意./configure 时确保enable-dav和enable-ssl，其中dav模块是通过apache2存储文件的基础。   <br />5 安装OpenSSL</p>
<p>#sudo apt-get install openssl</p>
<p>6 安装Subversion</p>
<p># sudo apt-get install build-essential openssl ssh expat libxyssl-dev libssl-dev&#160;&#160;&#160; <br /># sudo apt-get remove subversion&#160;&#160;&#160; <br /># sudo dpkg &#8211;purge subversion&#160;&#160;&#160; <br /># wget <a href="http://subversion.tigris.org/downloads/subversion-1.6.2.tar.gz">http://subversion.tigris.org/downloads/subversion-1.6.2.tar.gz</a>    <br /># wget <a href="http://subversion.tigris.org/downloads/subversion-deps-1.6.2.tar.gz">http://subversion.tigris.org/downloads/subversion-deps-1.6.2.tar.gz</a>    <br /># tar xvfz subversion-1.6.2.tar.gz&#160;&#160;&#160; <br /># tar xvfz subversion-deps-1.6.2.tar.gz&#160;&#160;&#160; <br /># cd subversion-1.6.2/neon/&#160;&#160;&#160; <br /># ./configure &#8211;prefix=/usr/local &#8211;with-ssl &#8211;with-pic&#160;&#160; <br /># make&#160;&#160;&#160; <br /># sudo make install&#160;&#160;&#160;&#160;&#160;&#160; <br /># ./configure &#8211;prefix=/usr/local &#8211;with-ssl &#8211;with-neon=/usr/local&#160;&#160;&#160; <br /># make&#160;&#160;&#160; <br /># sudo make install&#160;&#160; </p>
<p>&#160; 注意：首先移除ubuntu自带的subversion，随后进行编译安装。其中<a href="http://subversion.tigris.org/downloads/subversion-deps-1.6.2.tar.gz">subversion-deps-1.6.2.tar.gz</a>是Subversion客户端使用的Neon库，它不仅仅可以用来验证服务器证书，也可以必要时提供客户端证书，因此也要安装上</p>
<p>7 配置http访问subversion</p>
<p>&#160; 参考了<a href="http://www.javaeye.com/topic/293540">主题：ubuntu下安装svn提供HTTP版本管理服务</a>和<a href="http://www.howtogeek.com/howto/ubuntu/install-subversion-with-web-access-on-ubuntu/">Install Subversion with Web Access on Ubuntu</a></p>
<p>(1)#sudo svnadmin create /svn&#160;&#160; </p>
<p>&#160;&#160; 可以看一下/svn下是不是增加了些文件&#160; <br />(2)#sudo vim /usr/local/apache2/conf/httpd.conf</p>
<p>&#160;&#160; 增加&#160; <br />&#160;&#160; &lt;Location /svn&gt;    <br />&#160;&#160;&#160;&#160; DAV svn    <br />&#160;&#160;&#160;&#160; SVNPath /svn    <br />&#160;&#160;&#160;&#160; AuthzSVNAccessFile /svn/conf/authz    <br />&#160;&#160;&#160;&#160; AuthType Basic    <br />&#160;&#160;&#160;&#160; AuthName &quot;Subversion.Tracker&quot;    <br />&#160;&#160;&#160;&#160; AuthUserFile /svn/conf/passwd&#160;&#160;&#160;&#160; Require valid-user    <br />&#160;&#160; &lt;/Location&gt;</p>
<p>&#160;&#160;&#160; 这部分应该也可以放置到 conf/extra/httpd_dav.conf文件中，然后将httpd.conf中的 include conf/extra/httpd_dav.conf 注释去掉，不过奇怪的是httpd_dav.conf文件中的示例使用&lt;Directory&gt;而不是&lt;Location&gt;,我未作尝试。</p>
<p>(3)#sudo htpasswd -cm /svn/conf/passwd &lt;username&gt;   <br />&#160;&#160; 增加一个用户名,可以打开passwd文件查看是否创建成功    <br />&#160;&#160; 同时在Ubuntu上创建同名用户和相同密码&#160; (此处待验证，网络上有的文章没有强调这一点    <br />&#160;&#160; sudo useradd &lt;username&gt;    <br />&#160;&#160; sudo passwd &lt;password&gt;</p>
<p>(4)#sudo chown www-data:www-data&#160; -R /svn&#160; </p>
<p>&#160;&#160;&#160; 将/svn的所有者和所在的组更改为www-data（ubuntu下apache2的账户)</p>
<p>&#160;&#160;&#160; #sudo chmod –R g+ws /svn</p>
<p>(5)#sudo /usr/local/apache2/bin/httpd –k restart</p>
<p>&#160;&#160;&#160; 看看<a href="http://localhost/svn">http://localhost/svn</a> 是否可以访问了</p>
<p>8 配置ssl访问subversion</p>
<p>&#160; 参考了<a href="http://ywbanm.javaeye.com/blog/341562">Linux SVN+Apache+SSL 安装配置</a>和<a href="http://koda.javaeye.com/blog/288187">Apache SSL配置</a></p>
<p>openssl genrsa -des3 -out ca.key 1024   <br />//按提示输入密码：****    <br />chmod 400 ca.key    <br />//生成证书    <br />openssl req -new -x509 -days 3650 -key ca.key -out ca.crt    <br />//按提示分别输入如下内容：    <br />//Country Name: CN    <br />//State or Province Name:     <br />//Locality Name:     <br />//Organization Name:    <br />//Organizational Unit Name:    <br />//Common Name:    <br />//Email Address: your email    <br />chmod 400 ca.crt    <br />openssl genrsa -des3 -out server.key 1024    <br />//按提示输入密码：    <br />chmod 400 server.key    <br />openssl req -new -key server.key -out server.csr    <br />//按提示分别输入如下内容：    <br />//Country Name: CN    <br />//State or Province Name:     <br />//Locality Name:     <br />//Organization Name:    <br />//Organizational Unit Name:    <br />//Common Name:    <br />//Email Address: your email    <br />(ca.crt 和server.csr 的Common Name不能一样)    <br />openssl req -noout -text -in server.csr    <br />openssl x509 -req -days 365 -in server.csr -signkey server.key -out&#160; server.crt     <br />chmod 400 server.crt </p>
<p>vim /usr/local/apache2/conf/httpd.conf    <br />取消Include conf/extra/httpd-ssl.conf前的注释#</p>
<p>打开httpd-ssl.conf文件查看如下两行，确保前面生成的证书放置在该路径下</p>
<p>SSLCertificateFile &quot;/usr/local/apache2/conf/server.crt&quot;</p>
<p>SSLCertificateKeyFile &quot;/usr/local/apache2/conf/server.key&quot;</p>
<p>重启httpd服务</p>
<p>查看<a title="https://202.194.254.21/svn/" href="https://localhost/svn/">https://localhost/svn/</a>&#160; 浏览器显示此网站的安全证书有问题，忽略它，输入用户名和密码，至此基于SSL的Subversion配置完成。</p>
<p>9 总结</p>
<p>&#160; 配置过程中应该了解ubuntu和其他linux发行版安装软件的不同，掌握make和make install。如碰到apache2不能启动，阅读错误提示以及查看日志(/usr/local/apache2/logs/error.log).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilwang.net/?feed=rss2&amp;p=456</wfw:commentRss>
		</item>
		<item>
		<title>Ubuntu 9.10 Server (Karmic) 迁移Bugzilla</title>
		<link>http://www.basilwang.net/?p=455</link>
		<comments>http://www.basilwang.net/?p=455#comments</comments>
		<pubDate>Sat, 06 Feb 2010 17:18:19 +0000</pubDate>
		<dc:creator>basil</dc:creator>
		
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.basilwang.net/?p=455</guid>
		<description><![CDATA[项目组去年年底配置了两台服务器，其中的一台安装了Ubuntu 9.10 Server。由于项目组采用Bugzilla作为bug生命周期的管理，需要把Bugzilla迁移了过来。以下记录迁移过程备忘。
原服务器 Ubuntu 8.04 Desktop ，&#160; Bugzilla 3.2.2
新服务器 Ubuntu 9.10 Server&#160; , &#8211;
参考网上部分方案，打算采用比较稳妥的方式，形成如下思路
<span class="readmore"><a href="http://www.basilwang.net/?p=455" title="Ubuntu 9.10 Server (Karmic) 迁移Bugzilla" target="_blank">阅读全文——共2288字</a></span>]]></description>
			<content:encoded><![CDATA[<p>项目组去年年底配置了两台服务器，其中的一台安装了Ubuntu 9.10 Server。由于项目组采用Bugzilla作为bug生命周期的管理，需要把Bugzilla迁移了过来。以下记录迁移过程备忘。</p>
<p>原服务器 Ubuntu 8.04 Desktop ，&#160; Bugzilla 3.2.2</p>
<p>新服务器 Ubuntu 9.10 Server&#160; , &#8211;</p>
<p>参考网上部分方案，打算采用比较稳妥的方式，形成如下思路</p>
<p>1 备份mysql数据库</p>
<p>&#160; 将数据库bugs备份到文件bugsdata.sql    <br />&#160;&#160;&#160; $mysqldump bugs &gt; bugsdata.sql     <br />&#160;&#160;&#160; 再修改bugsdata.sql，在文件头加两行     <br />&#160;&#160;&#160; create database if not exists bugs;     <br />&#160;&#160;&#160; USE bugs;</p>
<p>2 在已安装mysql的9.10Server上恢复数据库</p>
<p>&#160;&#160; 此步骤一定在第5步之前，因为Bugzilla的checksetup.pl会自动升级数据库脚本从3.2.2到3.4.4</p>
</p>
<p>3 打包Bugzilla 文件夹并恢复到Ubuntu 9.10上&#160; （此步骤浏览时报错，忘了具体错误，比较难处理，转到步骤3）</p>
<p>4 下载最新Bugzilla 3.4.4, 重新编译。 至于为什么不用ubuntu自带的Bugzilla以及如何下载编译配置Bugzilla，请参见这篇博文<a href="http://www.basilwang.net/?p=396">Ubuntu 8.04 安装 Bugzilla 3.2.2</a></p>
<p>&#160;&#160; 为了防止版本文件夹的变化而修改apache虚拟目录文件，可以创建symbolic link,比如解压后的文件夹为 Bugzilla_3.4.4 可以用 ln –s Bugzilla Bugzilla_3.4.4 创建名为Bugzilla的symbolic link,在apache虚拟目录的配置中可以使用该名称，将来出现新版本只更新Bugzilla的指向即可。</p>
<p>5 运行 ./checksetup.pl 的时候，按照提示下载缺少的部分模块，总是有3个模块安装不上</p>
<p>Checking perl modules&#8230;    <br />Checking for DateTime (v0.28) not found     <br />Checking for DateTime-TimeZone (v0.71) not found&#160; <br />Checking for Template-Toolkit (v2.22) not found </p>
<p>解决方法 sudo apt-get install libmysql++-dev&#160; (参考了ubuntuforums.org里一位老兄的帖子<strong><a href="http://ubuntuforums.org/showthread.php?p=8542197">Installing bugzilla and DateTime problem</a>)</strong></p>
<p>6 接下来就是按照提示修改Bugzilla的localconfig</p>
<p>$webservergroup = ‘www-data’;</p>
<p># The DNS name of the host that the database server runs on.    <br />$db_host = ‘localhost’;     <br /># The name of the database     <br />$db_name = ‘bugs’;</p>
<p># Who we connect to the database as.</p>
<p># The DNS name of the host that the database server runs on.    <br />$db_host = ‘localhost’;     <br /># The name of the database     <br />$db_name = ‘bugs’;</p>
<p># Who we connect to the database as.    <br />$db_user = ‘bugs’;     <br />$db_pass = ‘admin’;     <br />注意其中的webservergroup 我设置为了www-data，注意这个是ubuntu的运行apache的用户组（不同于其他linux发行版的apache用户组)     </p>
<p>7 别忘了在apache下配置该虚拟目录，ubuntu自带的apache可以直接修改的/etc/apache2/sites-enabled下面的文件加入</p>
<p>Alias /bugzilla “/var/www/bugzilla″    <br />&lt;Directory&#160; “/var/www/bugzilla″&gt;</p>
<p>Options +ExecCGI    <br />AllowOverride Limit     <br />DirectoryIndex index.cgi     <br />AddHandler cgi-script .cgi     <br />&lt;/Directory&gt;     <br />不过我们的服务器使用了自己下载编译的apache2，因为该服务器还做为svn的源代码管理服务器。我在ubuntu 9.10 server 下的apache在启用ssl的时候总是报undefined symbol apr_ldap_ssl_init错误，此处我怀疑可能是ubuntu9.10 server的问题，我在虚拟机ubuntu 8.04 desktop下没有出现此问题。</p>
<p>apache2的安装目录更改为/usr/local/apache2，在/usr/local/apache2/conf/httpd.conf中加入上述内容。</p>
<p>关于apache2的下载编译以及使用ssl的SVN请浏览<a href="http://www.basilwang.net/?p=456">Ubuntu 9.10 Server 配置基于SSL的Subversion</a></p>
<p>8 sudo /etc/init.d/apache2 restart&#160; (自带的apache2)</p>
<p>&#160;&#160; 或者    <br />&#160;&#160; cd /usr/local/apache2/bin&#160; (编译的apache2)     <br />&#160;&#160; sudo ./httpd –k restart</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilwang.net/?feed=rss2&amp;p=455</wfw:commentRss>
		</item>
		<item>
		<title>WordPress 2.7.1 的Themes 调用 jquery</title>
		<link>http://www.basilwang.net/?p=422</link>
		<comments>http://www.basilwang.net/?p=422#comments</comments>
		<pubDate>Mon, 28 Sep 2009 15:40:00 +0000</pubDate>
		<dc:creator>basil</dc:creator>
		
		<category><![CDATA[Featured]]></category>

		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.basilwang.net/?p=422</guid>
		<description><![CDATA[这半年的项目一直在用jquery,感觉确实很方便，这几天有点时间，把wp的theme处理了一下，原来的theme调用的是自己的jquery,而没有使用wp后台管理界面的jquery,于是处理了一下，用fiddler抓了一下，现在清静了。
&#160;
GET http://www.basilwang.net/wp-content/themes/redevo_newsblue/style.css    304 Not Modified 
GET http://www.basilwang.net/wp-includes/js/jquery/jquery.js?ver=1.2.6    304 Not Modified 
<span class="readmore"><a href="http://www.basilwang.net/?p=422" title="WordPress 2.7.1 的Themes 调用 jquery" target="_blank">阅读全文——共965字</a></span>]]></description>
			<content:encoded><![CDATA[<p>这半年的项目一直在用jquery,感觉确实很方便，这几天有点时间，把wp的theme处理了一下，原来的theme调用的是自己的jquery,而没有使用wp后台管理界面的jquery,于是处理了一下，用fiddler抓了一下，现在清静了。</p>
<p>&#160;</p>
<p>GET <a href="http://www.basilwang.net/wp-content/themes/redevo_newsblue/style.css">http://www.basilwang.net/wp-content/themes/redevo_newsblue/style.css</a>    <br />304 Not Modified </p>
<p>GET <a href="http://www.basilwang.net/wp-includes/js/jquery/jquery.js?ver=1.2.6">http://www.basilwang.net/wp-includes/js/jquery/jquery.js?ver=1.2.6</a>    <br />304 Not Modified </p>
<p>GET <a href="http://www.basilwang.net/wp-includes/js/jquery/ui.core.js?ver=2.7.1">http://www.basilwang.net/wp-includes/js/jquery/ui.core.js?ver=2.7.1</a>    <br />304 Not Modified </p>
<p>GET <a href="http://www.basilwang.net/wp-includes/js/jquery/ui.tabs.js?ver=2.7.1">http://www.basilwang.net/wp-includes/js/jquery/ui.tabs.js?ver=2.7.1</a>    <br />304 Not Modified </p>
<p>GET <a href="http://www.basilwang.net/wp-content/themes/redevo_newsblue/images/search.png">http://www.basilwang.net/wp-content/themes/redevo_newsblue/images/search.png</a>    <br />304 Not Modified </p>
<p>具体写法，参考了网上的一些内容，有些出入，可能是版本的问题，修改了一下，ok</p>
<p>在themes/*** 的header.php文件的&lt;head&gt;中&lt;?php wp_head(); ?&gt;前加上</p>
<p> &lt;?php wp_enqueue_script(&#8217;jquery&#8217;,'/wp-includes/js/jquery/jquery.js&#8217;); ?&gt;   <br /> &lt;?php wp_enqueue_script(&#8217;uicore&#8217;,'/wp-includes/js/jquery/ui.core.js&#8217;); ?&gt;    <br /> &lt;?php wp_enqueue_script(&#8217;uitabs&#8217;,'/wp-includes/js/jquery/ui.tabs.js&#8217;); ?&gt;</p>
<p>这样就能利用wp的js文件了。（用&lt;?php wp_enqueue_script(&#8217;jquery&#8217;); ?&gt;不行，不知为什么，估计是版本的问题）</p>
<p>另外在ubuntu+firefox下，可以使用httpfox来查看http信息。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilwang.net/?feed=rss2&amp;p=422</wfw:commentRss>
		</item>
		<item>
		<title>终于搞定了Spam的过滤，Akismet不错</title>
		<link>http://www.basilwang.net/?p=408</link>
		<comments>http://www.basilwang.net/?p=408#comments</comments>
		<pubDate>Tue, 14 Apr 2009 01:06:46 +0000</pubDate>
		<dc:creator>basil</dc:creator>
		
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.basilwang.net/?p=408</guid>
		<description><![CDATA[最近一段时间发现垃圾评论非常多，清明节三天假，垃圾评论就有1千多条，My god, 删到我手疼，于是只得求助于反垃圾评论软件，以前安装过一个发表评论需要输入验证码的插件，有童鞋评论说不好用，这次尝试了Aksimet。通过这几天的观察，效果很是不错，已经帮我拦截了600多的Spam了，好像只有两三个漏网的，不过还没有机会测试一下正常评论的识别率，请童鞋们踊跃发言，帮俺测试一下。
]]></description>
			<content:encoded><![CDATA[<p>最近一段时间发现垃圾评论非常多，清明节三天假，垃圾评论就有1千多条，My god, 删到我手疼，于是只得求助于反垃圾评论软件，以前安装过一个发表评论需要输入验证码的插件，有童鞋评论说不好用，这次尝试了Aksimet。通过这几天的观察，效果很是不错，已经帮我拦截了600多的Spam了，好像只有两三个漏网的，不过还没有机会测试一下正常评论的识别率，请童鞋们踊跃发言，帮俺测试一下。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilwang.net/?feed=rss2&amp;p=408</wfw:commentRss>
		</item>
		<item>
		<title>Ubuntu 8.04 安装 Bugzilla 3.2.2</title>
		<link>http://www.basilwang.net/?p=396</link>
		<comments>http://www.basilwang.net/?p=396#comments</comments>
		<pubDate>Tue, 31 Mar 2009 16:16:16 +0000</pubDate>
		<dc:creator>basil</dc:creator>
		
		<category><![CDATA[Featured]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[bugzilla]]></category>

		<guid isPermaLink="false">http://www.basilwang.net/?p=396</guid>
		<description><![CDATA[新的项目刚刚启动，虽说只有几个人七八条枪，但是也得装个正规军的样子，版本控制、Bug管理都得用上。以前项目用了个国产开源的Bug工具Bugfree，这次想换成强大的Bugzilla，先在虚拟机的Ubuntu安装一下，安装的过程及注意事项记录一下。
用apt-get install bugzilla 安装的版本是 bugzilla 2.22.1 debian，安装过程很简单，不过版本比较陈旧了，且无法升级到bugzilla 3 。从bugzilla论坛上了解到，2.22.1 debian版本是由ubuntu来维护的，其实可以算是bugzilla的一个分支，无法升级到bugzilla 3。这一点提醒在ubuntu下使用bugzilla的朋友，我是费了半天工夫才发现为什么无法把debian版本的2.22升级到bugzilla 3的。
<span class="readmore"><a href="http://www.basilwang.net/?p=396" title="Ubuntu 8.04 安装 Bugzilla 3.2.2" target="_blank">阅读全文——共2857字</a></span>]]></description>
			<content:encoded><![CDATA[<p>新的项目刚刚启动，虽说只有几个人七八条枪，但是也得装个正规军的样子，版本控制、Bug管理都得用上。以前项目用了个国产开源的Bug工具Bugfree，这次想换成强大的Bugzilla，先在虚拟机的Ubuntu安装一下，安装的过程及注意事项记录一下。</p>
<p>用apt-get install bugzilla 安装的版本是 bugzilla 2.22.1 debian，安装过程很简单，不过版本比较陈旧了，且无法升级到bugzilla 3 。从bugzilla论坛上了解到，2.22.1 debian版本是由ubuntu来维护的，其实可以算是bugzilla的一个分支，无法升级到bugzilla 3。这一点提醒在ubuntu下使用bugzilla的朋友，我是费了半天工夫才发现为什么无法把debian版本的2.22升级到bugzilla 3的。</p>
<p>我舍弃2.22.1 debian版本的一个重要原因是不支持Smtp authentication的邮件发送， 以前用bugfree，通过这个功能，我可以使用163的smtp服务器来发送邮件，小组成员能够及时地通过邮件了解bug情况。可是bugzilla提供的smtp却是不需要authentication的方式，这需要我们自己假设邮件服务器，有点郁闷。</p>
<p>bugzilla 3.2.2已经提供了smtp authentication的支持，3.2.2的安装不能通过apt-get install命令，可以参考源文件压缩包里的Quickstart。</p>
<p>下面是我采用的方式</p>
<p>bash$ cd /var/www  选择放置的位置<br />
bash$ wget <a href="http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-3.2.2.tar.gz">http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-3.2.2.tar.gz</a><br />
(Output omitted 输出忽略)<br />
bash$ tar xzvf bugzilla-3.2.2.tar.gz<br />
bugzilla-3.2.2/<br />
bugzilla-3.2.2/.cvsignore<br />
(Output truncated 输出截断)<br />
bash$ cd  /var/www/bugzilla-3.2.2/<br />
bash$ sudo ./checksetup.pl</p>
<p>此时列出是否满足安装的前提，按照要求操作即可，可多次执行此命令，我这里只安装了必须的module，这也造成了我后面采用Smtp发送邮件的时候出现了一系列的问题；也可以选择全部安装，但是好像挺慢，而且我没有执行成功。<br />
安装前提满足了，这是可以按照Quickstart来编辑文件夹下的localconfig文件，主要涉及文件访问权限组$webservergroup以及访问mysql的用户名和密码。<br />
例：</p>
<p>$webservergroup = &#8216;www-data&#8217;;</p>
<p># The DNS name of the host that the database server runs on.<br />
$db_host = &#8216;localhost&#8217;;<br />
# The name of the database<br />
$db_name = &#8216;bugs&#8217;;</p>
<p># Who we connect to the database as.</p>
<p># The DNS name of the host that the database server runs on.<br />
$db_host = &#8216;localhost&#8217;;<br />
# The name of the database<br />
$db_name = &#8216;bugs&#8217;;</p>
<p># Who we connect to the database as.<br />
$db_user = &#8216;bugs&#8217;;<br />
$db_pass = &#8216;admin&#8217;;</p>
<p>然后创建用户名和数据库并赋予相应的权限</p>
<p>mysql -u root -p<br />
Create database bugs;<br />
GRANT SELECT, INSERT, UPDATE, DELETE, INDEX, ALTER, CREATE, LOCK TABLES,CREATE TEMPORARY TABLES, DROP, REFERENCES ON bugs.* TO bugs@localhost IDENTIFIED BY &#8216;admin&#8217;;<br />
Flush privileges；</p>
<p>再次执行checksetup.pl 即可完成bugzilla的安装，不过要想正常的显示还需要配置一下apache2<br />
在apache2的配置文件中（我是直接修改的/etc/apache2/sites-enabled下面的文件）加入</p>
<p>Alias /bugzilla1 &#8220;/var/www/bugzilla-3.2.2&#8243;<br />
&lt;Directory  &#8220;/var/www/bugzilla-3.2.2&#8243;&gt;</p>
<p>Options +ExecCGI<br />
AllowOverride Limit<br />
DirectoryIndex index.cgi<br />
AddHandler cgi-script .cgi<br />
&lt;/Directory&gt;</p>
<p>你可能注意到了，我这里虚拟目录设置成bugzilla1而不是bugzilla,我设置成bugzilla总是报找不到index.cgi的错误，可能是原来安装过2.22.1 debian的缘故，还请知道的朋友告知。</p>
<p>在浏览器中执行<a href="http://localhost/bugzilla1">http://localhost/bugzilla1</a> 此时可以看到bugzilla的首页。</p>
<p>接着配置smtp</p>
<p>mail_delivery_method : smtp<br />
mailfrom                   : 设置成我的真实邮箱     例 <a href="mailto:me@163.com">me@163.com</a> 可能有的mail server会验证邮箱的真实性以及是否属于该mail server<br />
sendmailnow             : on<br />
smtpserver               : 设置成smtp authentication服务器 例smtp.163.com<br />
smtp_username        : 我的邮箱    例 <a href="mailto:me@163.com">me@163.com</a><br />
smtp_password        : 密码<br />
注意后两个parameters(选项)是2.22.1 debian所没有的。</p>
<p>但是接下来我在测试发送邮件的时候总是报</p>
<p>&#8220;The new value for smtp_username is invalid: Error requiring<br />
Authen::SASL: &#8216;Can&#8217;t locate Authen/SASL.pm in @INC (@INC contains: .<br />
lib c:/perl/site/lib c:/perl/lib) at (eval 84) line 3. &#8216;.&#8221;<br />
这个错误要求我们安装Authen::SASL 可以回到checksetup.pl处按照提示安装，但是我在这里却出现了问题。<br />
由于之前已经将bugzilla3.2.2文件夹的访问权限设置给了www-data组，现在无法进入到bugzilla3.2.2文件夹内执行任何操作，总报permissions access</p>
<p>采用 sudo –s –H 并输入密码，可以以root权限进入该文件夹操作，安装好Authen::SASL后，发送邮件功能ok。</p>
<p>回顾一下安装的过程，1是对apache默认目录设置以及perl语言环境支持的配置 2是对ubuntu下权限 两处不熟悉浪费了时间，这里记录下整个过程，已备查阅。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilwang.net/?feed=rss2&amp;p=396</wfw:commentRss>
		</item>
		<item>
		<title>dopod c720 刷k大的window mobile 6.1</title>
		<link>http://www.basilwang.net/?p=391</link>
		<comments>http://www.basilwang.net/?p=391#comments</comments>
		<pubDate>Sun, 29 Mar 2009 14:12:30 +0000</pubDate>
		<dc:creator>basil</dc:creator>
		
		<category><![CDATA[IT技术]]></category>

		<guid isPermaLink="false">http://www.basilwang.net/?p=391</guid>
		<description><![CDATA[上周五一咬牙把我的dopod c720的wm5.0给刷掉了，我的c720是行货，移动定制的心机，不过用起来很是垃圾，而wm6.1网上的评价不错，早想尝试一下。以前有过Palm系统的刷机经验，感觉基本差不多，下面把自己刷机的一些体会写一下。
1 网上的刷机教程很多，推荐k大的文章http://www.ioicn.com.cn/forum/viewthread.php?tid=252565&#38;highlight=c720，网上看wm6.1的刷机过程比wm5.0简单多了，写得也很详细。
2 我是在Vista Business下刷机的，当了一次小白鼠，幸好成功了，要不我S#*)$1%
3 刷机很顺利，不过我刷完后超频太猛 从180MHZ超到280MHZ,直接死机，之后没有任何反应，后来想到Palm的硬启，发现wm也可以，网上也有方法，不过我试了好多次，最后我的经验就是从关机开始，持续安住两个快速键（最上面的两个，开始我也不知道），中间安住开机键间隔1秒左右松开（快速键一直按住），直到系统启动看到桌面，会出现提示，按照提示操作即可。我的频率最后在240MHZ，现在速度可以接受
<span class="readmore"><a href="http://www.basilwang.net/?p=391" title="dopod c720 刷k大的window mobile 6.1" target="_blank">阅读全文——共561字</a></span>]]></description>
			<content:encoded><![CDATA[<p>上周五一咬牙把我的dopod c720的wm5.0给刷掉了，我的c720是行货，移动定制的心机，不过用起来很是垃圾，而wm6.1网上的评价不错，早想尝试一下。以前有过Palm系统的刷机经验，感觉基本差不多，下面把自己刷机的一些体会写一下。</p>
<p>1 网上的刷机教程很多，推荐k大的文章<a title="http://www.ioicn.com.cn/forum/viewthread.php?tid=252565&amp;highlight=c720" href="http://www.ioicn.com.cn/forum/viewthread.php?tid=252565&amp;highlight=c720">http://www.ioicn.com.cn/forum/viewthread.php?tid=252565&amp;highlight=c720</a>，网上看wm6.1的刷机过程比wm5.0简单多了，写得也很详细。</p>
<p>2 我是在Vista Business下刷机的，当了一次小白鼠，幸好成功了，要不我S#*)$1%</p>
<p>3 刷机很顺利，不过我刷完后超频太猛 从180MHZ超到280MHZ,直接死机，之后没有任何反应，后来想到Palm的硬启，发现wm也可以，网上也有方法，不过我试了好多次，最后我的经验就是从关机开始，持续安住两个快速键（最上面的两个，开始我也不知道），中间安住开机键间隔1秒左右松开（快速键一直按住），直到系统启动看到桌面，会出现提示，按照提示操作即可。我的频率最后在240MHZ，现在速度可以接受</p>
<p>4 输入法以前在wm6.1下很不爽，现在有了点讯梅花试用版，很不错，希望软件越做越好，我也捐了2块钱，呵呵。</p>
<p>以上就是本人的一些经验，最后提醒各位，刷机有害身体健康。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilwang.net/?feed=rss2&amp;p=391</wfw:commentRss>
		</item>
	</channel>
</rss>
