<?xml version="1.0" encoding="utf-8" ?>


<feed xmlns="http://www.w3.org/2005/Atom">
  <title>imAtlas</title>

  <description>javascript、css、html等web前端的技术分享与讨论</description>

  <link href="http://imatlas.com/"></link>

  <link ref="self" href="http://imatlas.com/feed"></link>

  <id>572b438be4fe268e15072c45eb72fe71879d3e10-blog.imatlas.com</id>


  <updated>2024-02-06T14:31:00Z</updated>


  <entry>


    <title>老码农的小感想</title>

    <link href="http://imatlas.com/post/lao-ma-nong-de-xiao-gan-xiang"  rel="alternate"></link>

    <updated>2024-02-06T14:31:00Z</updated>
    <id>lao-ma-nong-de-xiao-gan-xiang</id>

    <author>
      <name>iAzrael</name>

    </author>
    <summary type="html">&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;我发现，现在很多计算机和软件工程相关专业的学生，&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;都不是因为喜欢计算机这个行业或者编程才选这个专业的。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;都不是因为喜欢计算机这个行业，或者说编程才选这个专业的。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;临近毕业了。除了课堂作业，连一个项目都没有写过&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;当年我想学医。所以报考了纯医学类的院校。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;谁知，被调剂到了计算机专业。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;我也不明白校长的脑洞怎么会这么大。一个医学类院校竟然会有计算机专业？&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;当我看到录取通知书，简直都要崩溃了&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;等开学后。我发现。我还是这个学院的第二届学生&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;我更加崩溃了……&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;好不容易说服自己接受现实&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;一开始选择了C++入手。然而选错了&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;在图书馆找了一个不知名作者写的不知名的书，里面用的他写的不知名的库&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;懵懵懂懂的搞了一个月，才写出了一个hello world。&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>使用CSS mask 实现图片的斜线拼接</title>

    <link href="http://imatlas.com/post/use-css-mask-slash-achieve-image-stitching"  rel="alternate"></link>

    <updated>2016-02-04T03:50:00Z</updated>
    <id>use-css-mask-slash-achieve-image-stitching</id>

    <author>
      <name>iAzrael</name>

    </author>
    <summary type="html">&lt;h2 id="toc_0" class="h16"&gt;每次必说题外话&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;话说貌似好久没有写技术文章了，自从娃娃出来后，很少能有时间做技术研究，思考的时间也不足。不过有得必有失，世上事也就酱紫了。但是作为一个前端攻城师，不写代码，不研究技术，是会被后浪拍死在沙滩上的。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;碰巧前段时间碰到个CSS问题，一直很喜欢CSS的，能CSS解决的问题绝对不用JS，于是就抽时间整整看。&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_1" class="h16"&gt;什么是斜线拼接&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;回到本文主题上，”斜线拼接“是我自创的词语，因为我也不知道怎么描述这个需求，o(╯□╰)o，实际的效果是下面所示：&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_dom_embed md_line_start md_line_end"&gt;&lt;a class="md_compiled" href="/uploads/2015-09-01/example.png"&gt;&lt;img class="md_compiled " src="/uploads/2015-09-01/example.png" alt="" title="" &gt;&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;眼力好的筒子应该就能发现，上面这张图是两个帅锅拼接在一起的，看中间的斜线。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;但是呢，刚接到这个需求的时候，开发是抓狂的——第一反应就是用canvas画图，这得多累啊，只是要显示张图片而已，竟然还要动用一坨JS，O__O &amp;quot;…&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;不过依稀记得，CSS 貌似有个遮罩的特性，可以实现图片的部分显示的效果的。more&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_2" class="h16"&gt;CSS mask &amp;amp; linear gradient&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;要实现这个特性，就需要用到CSS遮罩和线性渐变。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;至于这两个是什么东西，我就不班门弄斧的介绍了，毕竟这两个属性出生也挺久了的，不了解的筒子可以看这两篇文章&lt;a class="md_compiled" href="http://www.w3cplus.com/css3/css-masking.html"&gt;CSS遮罩——如何在CSS中使用遮罩&lt;/a&gt;和&lt;a class="md_compiled" href="http://www.zhangxinxu.com/wordpress/2013/09/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3css3-gradient%E6%96%9C%E5%90%91%E7%BA%BF%E6%80%A7%E6%B8%90%E5%8F%98/"&gt;深入理解css3-gradient斜向线性渐变&lt;/a&gt;。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;先看下实际的效果&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_dom_embed md_line_start md_line_end"&gt;&lt;a class="md_compiled" href="http://demo.imatlas.com/use-css-mask-slash-achieve-image-stitching.html"&gt;&lt;img class="md_compiled " src="/uploads/2016-01-01/拼接效果图.png" alt="" title="" &gt;&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;大家请看妹子中间（注意表看错了，是两个妹子的中间），有一条比较明显的分界线。多说无益，我知道你们想看demo，&lt;a class="md_compiled" href="http://demo.imatlas.com/use-css-mask-slash-achieve-image-stitching.html"&gt;用力戳这里&amp;gt;&amp;gt;&lt;/a&gt;。&lt;/span&gt;
&lt;/p&gt;

&lt;h3 id="toc_3" class="h16"&gt;&lt;strong&gt;第一步，显示两张图&lt;/strong&gt;&lt;/h3&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;OK，先看代码，然后我再来解释。&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_html  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;img-container&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;img-left&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;img-right&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;然后是CSS&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_css  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="nc"&gt;.img-container&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;position&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;border&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#40BCFF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.img-left&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(img/left.jpg)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.img-right&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(img/right.jpg)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;OK，看下效果&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_dom_embed md_line_start md_line_end"&gt;&lt;a class="md_compiled" href="/uploads/2016-02-01/abcdefg.png"&gt;&lt;img class="md_compiled " src="/uploads/2016-02-01/abcdefg.png" alt="" title="" &gt;&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;小明：尼玛，这不是坑爹么，这么简单谁不会？&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;小朋友，别急，我们两个主角还没上了。&lt;/span&gt;
&lt;/p&gt;

&lt;h3 id="toc_4" class="h16"&gt;&lt;strong&gt;画个斜线&lt;/strong&gt;&lt;/h3&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;为了实现斜线拼接，你总得有个斜线吧？把img-right的背景换成一个带有“斜线”的图，这个就不用“真”图片啦，CSS渐变就能完成，如下：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_css  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="nc"&gt;.img-right&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;webkit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linear&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;left&lt;/span&gt; &lt;span class="nb"&gt;top&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;blue&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;white&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_dom_embed md_line_with_image md_line_start md_line_end"&gt;&lt;img class="md_compiled " src="/uploads/2016-02-01/QQ截图20160204112221.png" alt="" title="" &gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;好，把背景换成真实的美女，渐变图作为mask&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_css  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nc"&gt;.img-right&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(img/right.jpg)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;webkit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;webkit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linear&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;left&lt;/span&gt; &lt;span class="nb"&gt;top&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;blue&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;white&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;But，如果你这么做了，会发现看到的是完整的图，并没有被遮盖，跟下图一样。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_dom_embed md_line_start md_line_end"&gt;&lt;a class="md_compiled" href="/uploads/2016-02-01/abcdefg.png"&gt;&lt;img class="md_compiled " src="/uploads/2016-02-01/abcdefg.png" alt="" title="" &gt;&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;这是因为css mask的原理是，它只会把遮罩图里透明像素所对应的原图部分进行隐藏，而我们的渐变图是完全不透明的（我们是蓝白色相间的），所以没有遮罩效果。那么把蓝色改成透明试试。&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_css  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nc"&gt;.img-right&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(img/right.jpg)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;webkit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;webkit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linear&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;left&lt;/span&gt; &lt;span class="nb"&gt;top&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;white&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_dom_embed md_line_start md_line_end"&gt;&lt;a class="md_compiled" href="/uploads/2016-02-01/QQ%E6%88%AA%E5%9B%BE20160204113645.png"&gt;&lt;img class="md_compiled " src="/uploads/2016-02-01/QQ截图20160204113645.png" alt="" title="" &gt;&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;当当当~~美女只显示一半啦！♪(^∇^*)&lt;/span&gt;
&lt;/p&gt;

&lt;h3 id="toc_5" class="h16"&gt;&lt;strong&gt;层叠&lt;/strong&gt;&lt;/h3&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;最后，把第二张图层在第一章上面，由于第二张图左边一半都是透明的，背景里的美女也能直接透过来啦。&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_css  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nc"&gt;.img-right&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;position&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;top&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_dom_embed md_line_start md_line_end"&gt;&lt;a class="md_compiled" href="http://demo.imatlas.com/use-css-mask-slash-achieve-image-stitching.html"&gt;&lt;img class="md_compiled " src="/uploads/2016-01-01/拼接效果图.png" alt="" title="" &gt;&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;看下最终img-right所需要的样式代码&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_css  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nc"&gt;.img-right&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;position&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;top&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(img/right.jpg)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;webkit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;webkit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linear&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;left&lt;/span&gt; &lt;span class="nb"&gt;top&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;white&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nb"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;怎么样，很简单是吧？&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;CSS3有很多新鲜（其实这个不新鲜了~）的特性可以实现很多有趣的应用，如果你有其他方案，欢迎留言讨论，O(∩_∩)O谢谢阅读！&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>肿么安装Effect Game</title>

    <link href="http://imatlas.com/post/kuai-le-de-ma-nong/zhong-yao-an-zhuang-effect-game"  rel="alternate"></link>

    <updated>2015-07-22T07:52:00Z</updated>
    <id>kuai-le-de-ma-nong/zhong-yao-an-zhuang-effect-game</id>

    <author>
      <name>iAzrael</name>

    </author>
    <summary type="html">&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;Effect Game的安装还是很麻烦的, 原作者用的时代比较久远, 有很多软件包在新的linux系统上都可能有兼容问题, 这里做个安装记录方便后人查阅.&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_0" class="h16"&gt;环境准备&lt;/h2&gt;
&lt;ol&gt;
&lt;li class="md_li"&gt;&lt;span&gt;fedora 21
&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span&gt;能翻墙的比较快的网络
&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;Effect Game的需要运行在linux系统里, 理论上任何linux发行版都可以, 但是我在ubuntu上折腾了好久, 总归还是放弃了. &lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;各个发行版虽然内核一样, 但是各种软件包可能不一样, 名字也可能不一样, 包管理工具也不一样, 所以环境这里, 还是建议用 &lt;code&gt;fedora 21&lt;/code&gt;, 而且不能用最新版, 最新版的fedora把 yum 给替换成了 dnf, 还是很多问题.&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;这里的安装步骤是基本按照这个E文文档的, &lt;a class="md_compiled" href="https://github.com/jhuckaby/Effect-Games/wiki/Installation-Guide"&gt;https://github.com/jhuckaby/Effect-Games/wiki/Installation-Guide&lt;/a&gt;, 启用能用yum安装的软件包都直接用yum了.&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_1" class="h16"&gt;安装各种系统依赖包&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;作者列了yum install xxx 很多包, 但是其实可以批量安装的&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;如果是第一次用yum, 先更新下yum的版本库 &lt;code&gt;yum repolist&lt;/code&gt; &lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;批量安装, &lt;strong&gt;安装完成后再敲入整个命令确认是否有安装失败的&lt;/strong&gt;(已经安装了的不会重复安装)&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;yum install zlib-devel libxml2-devel libgpg-error-devel libgcrypt-devel libxslt-devel expat-devel db4-devel e2fsprogs-devel krb5-devel openssl-devel aspell-devel rpm-build gcc screen sendmail "gcc-c++" bzip2-devel freetype-devel libpng-devel libtiff-devel libjpeg libjpeg-devel libstdc++-devel curl curl-devel libidn-devel krb5-devel e2fsprogs-devel libgcrypt-devel libgpg-error-devel&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_2" class="h16"&gt;创建 Effect Game 的安装目录&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;这里就直接按照作者的目录来设置, 大部分东东都放到这里, 避免各种引用要修改  &lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;mkdir /effect
mkdir -p /effect/perl/bin/&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_3" class="h16"&gt;安装 perl 和 cpan&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;yum install perl
yum install cpan&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;作者把 perl 放到了 /effect/perl 里, 这里做个软连就好&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;ln -s /usr/bin/perl /effect/perl/bin/perl 
ln -s /usr/bin/cpan /effect/perl/bin/cpan&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_4" class="h16"&gt;安装各种 perl 模块&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;第一次使用cpan时, 直接敲入 &lt;code&gt;cpan&lt;/code&gt; 运行一次, 按提示使用自动配置&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;为了避免安装时可能会遇到的下面这个提示, 烦它的话可以先装一下 &lt;code&gt;YAML&lt;/code&gt;.&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; 'YAML' not installed, will not store persistent state

cpan YAML&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;然后批量安装各种模块, &lt;strong&gt;安装完成后再敲入整个命令确认是否有安装失败的&lt;/strong&gt;(已经安装了的不会重复安装)&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;cpan LWP::UserAgent Archive::Zip Archive::Tar Class::Loader Digest::SHA Digest::SHA1 Math::Pari Devel::Symdump Module::Build MIME::Lite Test::Simple Text::Wrap CGI Devel::CoreStack Cwd IO::Socket::INET Test::Harness Time::HiRes Unicode::String Date::Parse MIME::Parser Crypt::SSLeay ExtUtils::XSBuilder IO::Socket::SSL File::lockf IPC::ShareLite Syntax::Highlight::Engine::Kate Text::Aspell Net::Twitter::Lite HTTP::Daemon File::Flock&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;这个需要等很久很久, 比很久很久还要久.&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;&lt;code&gt;Text::Aspell&lt;/code&gt; 很容易安装失败, 按如下步骤重新安装&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;yum install aspell aspell-en

cpan Text::Aspell&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_5" class="h16"&gt;安装图片服务 ImageMagick&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;ImageMagic不要用yum安装, 编译时需要指定很多环境变量, 直接下载下载自己编译.&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;安装jpeg和png解码库&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;yum install libjpeg-devel libpng-devel&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;作者用的ImageMagick是6.5版本, 可能会编译失败, 这里下载&lt;strong&gt;最新版&lt;/strong&gt;(目前是6.9).&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;wget "http://www.imagemagick.org/download/ImageMagick.tar.gz"
tar zxf ImageMagick.tar.gz
cd ImageMagick-*

ln -s /usr/include/freetype2/freetype /usr/include/freetype
export CPPFLAGS="-I/usr/include/freetype2 -I/usr/local/include"
export LDFLAGS="-L/usr/local/lib"
mkdir -p /effect/fonts

./configure --prefix=/effect/magick --enable-lzw --without-threads --without-magick-plus-plus --with-perl=perl --with-fontpath=/effect/fonts --without-x --with-quantum-depth=8 --enable-shared=yes --enable-static=no

make
make install&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;添加库到系统&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;echo "/effect/magick/lib" &amp;gt; /etc/ld.so.conf.d/imagemagick.conf&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;重新加载配置&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;/sbin/ldconfig -v&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;测试是否已正常安装&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;perl -MImage::Magick -e ';'&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;没有出错就安装OK, 注意, 这里是没有什么显示&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;创建个软链&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;mkdir -p /opt/local/bin
ln -s /effect/magick/bin/convert /opt/local/bin/convert&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_6" class="h16"&gt;安装音视频模块 MPG123 and OGG Encoder&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;安装 MPG&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;wget "http://www.effectgames.com/install/mpg123-1.10.0.tar.bz2"
tar jxf mpg123-1.10.0.tar.bz2
cd mpg123-*
./configure
make
make install&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;安装 OGG&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;yum install libvorbis libvorbis-devel vorbis-tools&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;检查下面文件在不在, 有就安装正确了&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;ls /usr/local/bin/mpg123 /usr/bin/oggenc&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_7" class="h16"&gt;安装 Apache&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;先安装或更新一下openssl&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;yum install openssl&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;Apache也有很多安装选项, 自己下载来编译&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;wget "http://www.effectgames.com/install/httpd-2.2.14.tar.bz2"
tar jxf httpd-2.2.14.tar.bz2
cd httpd-*

./configure --prefix=/effect/apache --with-mpm=prefork --with-ssl=openssl --with-perl=perl --enable-so --enable-expires --enable-headers --enable-mime-magic --enable-rewrite --enable-ssl --enable-mods-shared="all authn_file authn_default authz_host authz_groupfile authz_user authz_default auth_basic include filter log_config env setenvif mime status autoindex asis cgi negotiation dir actions userdir alias expires headers ssl rewrite"

make
make install&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;之后Apache会安装到 &lt;code&gt;/effect/apache&lt;/code&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;安装 mod_perl 模块, 有些系统会缺少 perl 的一些依赖, 先用 yum 安装依赖, 然后安装最新版的 mod_perl ( 目前是2.0.9 )&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;yum install perl-ExtUtils-Embed

wget "http://mirror.bit.edu.cn/apache/perl/mod_perl-2.0.9.tar.gz"
tar zxf mod_perl-*.tar.gz
cd mod_perl-*
perl Makefile.PL MP_AP_PREFIX=/effect/apache
make
make install&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;在执行&lt;code&gt;perl Makefile.PL MP_AP_PREFIX=/effect/apache&lt;/code&gt; 时可能会报错&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;[  error] '/effect/apache/bin/apxs -q NOTEST_CPPFLAGS' failed:
[  error] Use of assignment to $[ is deprecated at /effect/apache/bin/apxs line 86.&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;问题原因是新版本的perl里面, &lt;code&gt;[&lt;/code&gt; 不能用于变量名了, 修改 /effect/apache/bin/apxs 源码, 把&lt;code&gt;$[&lt;/code&gt; 替换成 &lt;code&gt;$a&lt;/code&gt;(vi 中可以用 &lt;code&gt;%s/$\[/\$a/g&lt;/code&gt; 命令全局替换), 保存并重新执行 &lt;code&gt;perl Makefile.PL MP_AP_PREFIX=/effect/apache&lt;/code&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;增加www用户组和用户&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;/usr/sbin/groupadd www
/usr/sbin/useradd -m -g www www&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;替换配置文件, 直接用作者的配置&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;wget "http://www.effectgames.com/install/httpd.conf"
mv /effect/apache/conf/httpd.conf /effect/apache/conf/httpd.conf.bak
mv httpd.conf /effect/apache/conf/&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_8" class="h16"&gt;配置项目&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;先下载项目代码下来&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;wget "https://github.com/jhuckaby/Effect-Games/tarball/master"
tar zxf jhuckaby-Effect-Games-*.tar.gz
rm jhuckaby-Effect-Games-*.tar.gz
mv jhuckaby-Effect-Games-*/* /effect
ln -s /effect/htdocs /effect/apache/htdocs/effect&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;做一些必要配置如域名等, 具体项直接参照 &lt;a class="md_compiled" href="https://github.com/jhuckaby/Effect-Games/wiki/Installation-Guide"&gt;安装文档&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;Effect Game的主要配置文件在 &lt;code&gt;/effect/conf/Effect.xml&lt;/code&gt;, 基本上都不需要修改&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;启动测试一下是否正常&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;/effect/apache/bin/apachectl start
/effect/apache/bin/apachectl stop&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_9" class="h16"&gt;初始化各种环境&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;创建数据存储目录和配置权限&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;mkdir -p /data/effect/storage
chown www:www /data/effect/storage

mkdir -p /data/effect/cleanup
chown www:www /data/effect/cleanup&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;创建日志的目录&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;mkdir -p /logs/effect
chmod 777 /logs/effect

mkdir -p /logs/apache
chmod 777 /logs/apache&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;创建初始数据, 执行这个脚本就行, 数据的配置在 &lt;code&gt;/effect/conf/initial_data_setup.xml&lt;/code&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;/effect/bin/setup_db.pl&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;启动图片服务进程, Effect Game是使用了个后台进程来优化图片, 配置文件在 &lt;code&gt;/effect/conf/image_service.xml&lt;/code&gt;, 用下面的命令启动&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;mkdir -p /data/effect/queue
chmod 777 /data/effect/queue

/effect/bin/imageservicectl.sh start
/effect/bin/imageservicectl.sh stop&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;配置定时任务, 这个任务用来处理日志文件和数据文件, 命令行敲入 &lt;code&gt;crontab -e&lt;/code&gt;, 输入&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;00 * * * * /effect/bin/maint.pl hourly
30 00 * * * /effect/bin/maint.pl daily&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;定时任务的log输出在 &lt;code&gt;/logs/effect/maint.log&lt;/code&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;过时的日志文件会被打包存储, 默认配置下存在 &lt;code&gt;/backup/effect/logs/CATEGORY/YYYY/MM/DD/HH.gz&lt;/code&gt;, 路径可以在 &lt;code&gt;/effect/conf/Effect.xml&lt;/code&gt; 中修改&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;创建备份目录&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;mkdir -p /backup/effect
chmod 777 /backup/effect&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_10" class="h16"&gt;All Done&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;现在可以启动 Effect Game 啦&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;/effect/bin/imageservicectl.sh start
/effect/apache/bin/apachectl start&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;然后访问 &lt;code&gt;http://127.0.0.1/effect/&lt;/code&gt;, 默认用户名和密码都是 &lt;code&gt;admin&lt;/code&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;如果要配置域名, 可以在 &lt;code&gt;/effect/apache/conf/httpd.conf&lt;/code&gt; 中修改 &lt;code&gt;ServerName&lt;/code&gt; &lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;So, enjoy it!&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>谈前端工程师的职业规划</title>

    <link href="http://imatlas.com/post/talk-about-the-front-end-engineering-career-planning"  rel="alternate"></link>

    <updated>2015-04-17T08:57:50Z</updated>
    <id>talk-about-the-front-end-engineering-career-planning</id>

    <author>
      <name>iAzrael</name>

    </author>
    <summary type="html">&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;在敲下这个标题的时候，心里好虚。话说我一直不太喜欢发表这些看上去很假大空的文字，每个人的职业规划都是独有的，不具有太大的可复制性，把自己的经历放出去，容易误人子弟。只是最近很多师弟们（别问我为什么都是师弟，我想静静……也不要问我静静是谁！）问起这个，也就根据自己的经历发表一下对前端工程师的看法吧，“我说的都是错的”，仅供参考。另：本篇是纯文字，密集恐惧症换成勿入！&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;从我接收第一份前端需求开始，到现在也有五个年头了。自己也从一个愣头青变成一个快到而立之年的大叔，时间真的是哗啦哗啦的快。这五年里，其实可以分成三部分：1~2, 3~4, 5。more&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_0" class="h16"&gt;1~2 吸吸吸，疯狂的吸取知识&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;刚毕业时满腔热情，一门心思只往前端事业发展。刚从学校出来，看到什么都是新鲜十足，什么都想学。不断的买书看书垫枕头，最疯狂的时候一个礼拜晚上看完正本犀牛书+做笔记，后来再也达不到这种速度了。很幸运我能加入到AlloyTeam，依靠WebQQ，使得我的编码能力、项目经验duang duang duang的上去了。同时也搞了很多奇形怪状的业余项目，基本上无论遇到什么跟JS相关的“新”技术（新是对于我自己来说的），我都想去尝一尝。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;对于刚毕业的初学者来说，头两年真的真的是非常重要，学习的激情、速度以及熬夜的能力可以发挥的淋漓尽致。在这个阶段，通过大量的编码提升JS能力，同时尝试各种JS框架和库，寻找适合自己的框架，甚至自己也写了一个JS库和构建工具。“不要重复的造轮子”这句话，初学者都应该无视。你不造轮子，怎么知道别的轮子好不好用？怎么知道造一个轮子有多难？怎么知道如何改进轮子？我不认为一个新手去看jQuery的源码能看懂，反正我当时就晕晕乎乎的。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;在这个时间点里，其实还没怎么考虑以后的发展，而且也仅认为前端工程师，学好JS/CSS/HTML就够了，其他的没兴趣也没意愿去学。&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_1" class="h16"&gt;3~4 大大大，扩展知识面&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;在JS/CSS/HTML里探索了2年后，突然发现越学越不懂了。出了HTML5，看了WebSocket，想学会，结果要看网络协议、要看HTTP/TCP，还要学Server开发等。顿时感觉分身10个也不一定能学好。为了跟上潮流，也得硬着头皮上。好不容易Server、网络、前端、浏览器各种知识都多少了解的时候，移动潮流来了！OMG，Android、iOS还有WP……生命不止，学习不休。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;其实到了这个阶段，多少也算是个有经验的攻城师了。开发一般需求不在话下，偶尔还能承担个架构设计。在提升JS能力的同时，开始要往多方面发展。前端工程师远远不仅是JS而已。制作一个性能高、交互好、视觉美的页面，需要从前端框架选型、架构设计、构建工具，到后端通信机制、设计与交互、网络和浏览器优化等各方面的知识。一专多长才是前端工程师的终极目标。有个人说得对：一专是指你不可替代，多长标示你可以替代别人。这样你在团队在公司的地位才更加牢固，公司也会给你提供更多的资源。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;同时还要开始提升自己的名气，可以通过发表技术博客，提交和参与开源项目，做部门级公司级还有业界分享，参加业界会议等等。在这个信息瞬息万变的互联网时代，保持交流才会让自己不落伍。同时名气大了，能找到更多志同道合的人一起研究技术（探讨生命的起源也不是不可能的），甚至想跳槽，也是放个屁的事儿（意思是简单-_-|| 这都什么比喻）。&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_2" class="h16"&gt;5~ 摸摸摸，摸清前方的路&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;这个时候，如无意外，你也应该成为高级工程师了。编码在工作中比例已经不算太高，更多的工作是承担技术评审、架构设计和项目管理等事情。工作中除了完成自己的事情，可能还需要指导新人，做新人培训，带领新人完成项目。同时还会有一个抉择摆在眼前：继续深入研究技术 or 往管理方向进发。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;技术 or 管理，这里没有对错之分，只有合不合适。有的人就不善于交流，同时喜欢专研，可以继续走技术的路，发展成专家；有的人则可能有比较强的领导力，可以带领一群人完成项目，那可以转向管理，成为Team Leader等。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;不管选哪个方向，你都已经是个优秀的人，而且应该把这种优秀传承下去。成为导师，使新人变得优秀；成为面试官，挖掘优秀的人；成为讲师，让更多人学习到优秀，等等。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;总的来说，头两年一定要打好基础，找准自己的G点，深攻下去；高潮之后，往广度发展，掌握其他相关和不相关的配套知识（这不是矛盾么？Σ( ° △ °|||)︴）；然后摸到自己的目标，发售大胆的爱爱（老了，手抖打多了）吧。不仅自己爱（前端），也要让更多人一起爱（前端）哦。&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>在浏览器端用JS创建和下载文件</title>

    <link href="http://imatlas.com/post/download-file-with-js"  rel="alternate"></link>

    <updated>2014-01-02T15:31:00Z</updated>
    <id>download-file-with-js</id>

    <author>
      <name>iAzrael</name>

    </author>
    <summary type="html">&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;前端很多项目中，都有文件下载的需求，特别是JS生成文件内容，然后让浏览器执行下载操作（例如在线图片编辑、在线代码编辑、&lt;a class="md_compiled" href="http://www.ipresst.com"&gt;iPresst&lt;/a&gt;等）。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;但受限于浏览器，很多情况下我们都只能给出个链接，让用户点击打开-》另存为。如下面这个链接：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_html  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;file.js&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;file.js&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;用户点击这个链接的时候，浏览器会打开并显示链接指向的文件内容，显然，这并没有实现我们的需求。more&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;HTML5中给a标签增加了一个download属性，只要有这个属性，点击这个链接时浏览器就不在打开链接指向的文件，而是改为下载（目前只有chrome、firefox和opera支持）。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_dom_embed md_line_start md_line_end"&gt;&lt;a class="md_compiled" href="/uploads/2014-01-01/QQ20140102-2.png"&gt;&lt;img class="md_compiled " src="/uploads/2014-01-01/QQ20140102-2.png" alt="" title="" &gt;&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;下载时会直接使用链接的名字来作为文件名，但是是可以改的，只要给download加上想要的文件名即可，如：download=“not-a-file.js”。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_dom_embed md_line_start md_line_end"&gt;&lt;a class="md_compiled" href="/uploads/2014-01-01/QQ20140102-3.png"&gt;&lt;img class="md_compiled " src="/uploads/2014-01-01/QQ20140102-3.png" alt="" title="" &gt;&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_0" class="h16"&gt;Not enough！&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;但是这样还不够，以上的方法只适合用在文件是在服务器上的情况。如果在浏览器端js生成的内容，想让浏览器进行下载要如何办到呢？&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;其实还是有办法办到的，相信很多人都多少听过了DataURI这个词，比较常见的就是图片的src，如：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_html  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;`data:image/gif;base64,R0lGOXXXXX&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;`
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;DataURI的解释可以移步&lt;a class="md_compiled" href="http://sjolzy.cn/What-is-the-data-URI-scheme-and-how-to-use-the-data-URI-scheme.html"&gt;这里&lt;/a&gt;，本人就不在解释了。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;那么，现在要将js生成的内容进行下载就有法可依了。封装成一个方法如下：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_js  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;downloadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aLink&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;aLink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;download&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;aLink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;data:text/plain,&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;调用downloadFile之后，用户点击链接，就能触发浏览器下载。&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_1" class="h16"&gt;Not enough！&lt;/h2&gt;
&lt;p class="md_block md_block_as_opening md_has_block_below md_has_block_below_ol"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;但是，还不够，上面的办法有两个硬伤，会导致流失很多懒人美眉：&lt;/span&gt;
&lt;/p&gt;


&lt;ol&gt;
&lt;li class="md_li"&gt;&lt;span&gt; 下载的文件类型限制死了，美眉要下载处理后的果照怎么办？
&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span&gt; 下载还要再点击一下，太麻烦啦。
&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;要解决文件类型的问题，可以用浏览器的新API（&lt;a class="md_compiled" href="https://developer.mozilla.org/en-US/docs/Web/API/URL.createObjectURL"&gt;URL.createObjectURL&lt;/a&gt;）来解决问题，URL.createObjectURL通常都是用来创建图片的DataURI用来显示图片，这里用来下载文件，让浏览器来帮我们设定好文件类型。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;URL.createObjectURL的参数是File对象或者Blob对象，File对象也就是通过input[type=file]选择的文件，Blob对象是二进制大对象，详细说明可参考&lt;a class="md_compiled" href="https://developer.mozilla.org/en-US/docs/Web/API/Blob"&gt;这里&lt;/a&gt;。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;现在，我们只要用content创建一个ObjectURL并赋值给aLink即可解决文件类型的限制问题。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;文件的自动下载也挺好办，自己构建一个UI点击事件，再自动触发下，就能实现自动下载啦。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;现在来看看最终代码：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_js  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;downloadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;aLink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;blob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;HTMLEvents&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;initEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;aLink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;download&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;aLink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;aLink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;现在，只要一调用downloadFile，文件就自动下载了，是不是很爽咧，^_^。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;&lt;strong&gt;注：&lt;/strong&gt;目前（2014-01-02）Blob和URL.createObjectURL在标准浏览器里面都不再需要加私有前缀，可以放心使用啦啦啦～～如果你不放心，可以查查&lt;a class="md_compiled" href="http://caniuse.com/#search=Blob"&gt;Can I Use&lt;/a&gt;。&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>千方百计加速Web之加速DNS解析</title>

    <link href="http://imatlas.com/post/make-dns-resolve-fast-than-web-fast"  rel="alternate"></link>

    <updated>2013-10-30T07:54:00Z</updated>
    <id>make-dns-resolve-fast-than-web-fast</id>

    <author>
      <name>iAzrael</name>

    </author>
    <summary type="html">&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;通常情况下，做移动开发时，如果要向后台请求数据，都会直接使用TCP通信。但实际上一来HTTP比TCP简单易用多了，二来有很多现有CGI如果要进行改造得花很大功夫。还是会有使用HTTP请求来拉取数据。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening md_has_block_below md_has_block_below_ol"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;在做Android QQ二维码时，扫描到二维码字符串，就是把该字符串用HTTP传给后台，后台解析后返回给客户端，客户端再进行下一步处理。在提交测试后，测试同事发现，在移动网络上，DNS解析会经常失败，导致二维码扫描功能不可用。功能测试不通过，导致无法发布。同时测试喜欢在清空DNS缓存和屏蔽了DNS解析的情况下，二维码解析功能仍然可用。因此这里增加了如下处理：&lt;/span&gt;
&lt;/p&gt;


&lt;ol&gt;
&lt;li class="md_li"&gt;&lt;span&gt; 进入“扫一扫”的界面时，客户端就开始对CGI所在域名进行解析，并把解析结果缓存到本地文件；
&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span&gt; 发起CGI请求时，还是使用原域名进行请求，如果DNS解析失败，则用第一步缓存的IP替换掉CGI中的域名再发起一次请求。
&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;由于国内有好几个网络运营商，公司在不同的网络环境都有不一样的出口IP，因此选择最近的IP才能快速访问CGI。所以缓存域名结果时，需要区分网络分别保存。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;more&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;这样，当用户的手机上至少成功使用了一次二维码扫描时，CGI对应的IP就保存下来了（至少有一个出口IP）。下次访问（同一次登录或者关闭手机QQ后再打开）时，即使DNS解析失败，还是能使用上一次保存的IP进行访问，可能会相应比较慢（用户从A网络切换到了B网络），但起码保证了功能的可用性。实现起来也不难，Java都有现成的接口了。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;主动发起DNS解析只要调用InetAddress的接口即可，把获取到的结果保存到SharedPreferences供下次使用：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;lookupIP&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
     &lt;span class="n"&gt;SharedPreferences&lt;/span&gt; &lt;span class="n"&gt;preferences&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSharedPreferences&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;host&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
     &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
     &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;InetAddress&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;InetAddress&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
          &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHostAddress&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
          &lt;span class="n"&gt;SharedPreferences&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Editor&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;preferences&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;edit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
          &lt;span class="n"&gt;editor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
          &lt;span class="n"&gt;editor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
          &lt;span class="n"&gt;QLog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TAG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;lookup address: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;, ip: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
     &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UnknownHostException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
     &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;然后在HTTP请求出现DNS解析错误的时候，用IP替换掉URL中的域名即可：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;HttpResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
     &lt;span class="c1"&gt;//DNS错误改用ip重新发一次&lt;/span&gt;
     &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getIP&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
     &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
          &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
     &lt;span class="o"&gt;}&lt;/span&gt;
     &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;这里之所以不直接用上次保存的IP来替换域名进行访问，是因为在正常情况下，进入“扫一扫”的界面时，已经预先对所用域名进行了预解析，如果解析成功，调用openRequest时就不用DNS查询了；而如果预解析失败了，openRequest的时候还能再尝试一次，失败时才使用IP访问。同时，很多用户都会在移动网络和WIFI网络中切换，如果直接用IP替换域名，会出现用户当前是移动网络，而是用的域名IP是在教育网IP（上一次使用的是教育网WIFI）的情况，导致CGI响应变得更慢。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;当然，更好的解决方法是：先检测当前用户的网络环境，如果本地保存了对应网络的IP，直接使用IP请求；如果没有，再改用域名来请求。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;还有更进阶的方案：第一次登陆时，从服务器拉取一份host列表（每个域名包括各个网络环境的出口IP），把所有HTTP请求的域名都替换成相应IP，这样就能完美解决DNS不可用、DNS解析失败的情况了。之后维护host文件的更新即可。&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>【代码分享】根据类型智能提取参数</title>

    <link href="http://imatlas.com/post/get-arguments-by-type"  rel="alternate"></link>

    <updated>2013-09-10T09:39:00Z</updated>
    <id>get-arguments-by-type</id>

    <author>
      <name>iAzrael</name>

    </author>
    <summary type="html">&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;如果你是个Javascript程序员，那一定经常写下面的代码：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_js  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;funcA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="c1"&gt;//funcA(url, callback);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;function&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="nx"&gt;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//funcA(url, params);&lt;/span&gt;
            &lt;span class="c1"&gt;//......&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//......&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;当参数变化形式比较少的时候还没问题，当你的方法想对多种传参形式进行容错时，一堆的if else判断就变得很难看了。这时不妨尝试下这个 getArguments 方法。more&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_js  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;toString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;getArguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;argus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type3&lt;/span&gt; &lt;span class="cm"&gt;/*...*/&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;srcTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;targetTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;argus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;srcTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;argus&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;targetTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;srcTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;targetTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;]){&lt;/span&gt;
            &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;argus&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
            &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;使用方法如下：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_js  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;funcB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;argus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getArguments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;String&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Object&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Function&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Object&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;argus&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;argus&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;argus&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;argus&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;argus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;运行结果如下：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_js  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;funcB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){})&lt;/span&gt;
&lt;span class="c1"&gt;//console: [&amp;quot;a&amp;quot;, null, function, null]&lt;/span&gt;
&lt;span class="nx"&gt;funcB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;//console: [&amp;quot;a&amp;quot;, null, function, Object]&lt;/span&gt;
&lt;span class="nx"&gt;funcB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;//console: [&amp;quot;a&amp;quot;, Object, null, null]&lt;/span&gt;
&lt;span class="nx"&gt;funcB&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;//console: [null, Object, null, null]&lt;/span&gt;
&lt;span class="nx"&gt;funcB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){})&lt;/span&gt;
&lt;span class="c1"&gt;//console: [null, null, function, null]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;怎么样，是不是简单很多咧？^_^&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>Compiler@NodeJS（三）- 自定义命令</title>

    <link href="http://imatlas.com/post/nodejs-compiler-custom-cmd"  rel="alternate"></link>

    <updated>2013-03-20T15:11:00Z</updated>
    <id>nodejs-compiler-custom-cmd</id>

    <author>
      <name>iAzrael</name>

    </author>
    <summary type="html">&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;_接上篇：&lt;a class="md_compiled" href="/nodejs-compiler-pipe/" title="Compiler@NodeJS（二）- 强大的管道"&gt;Compiler@NodeJS（二）- 强大的管道&lt;/a&gt;_&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;本来早就应该写这篇文章的，只是忙的时候忙，闲的时候懒，导致拖了这么久。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;不管内置多少命令，需求总是千变万化的，这时候内置命令就不够用了，需要使用者自己编写一些命令。现在来看看怎么做。more&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_0" class="h16"&gt;一、内置命令&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;先来看看内置命令的文件结构是怎样的：&lt;/span&gt;
&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;+--- compiler
    +--- cmds
        +--- copy
        +--- concat
            --- index.js
            --- README.md&lt;/code&gt;&lt;/pre&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;每个命令都是cmds下面的一个单独目录，如copy、concat等等。每个命令下面都必须有一个index.js文件，作为这个命令的入口。index.js需要export一个属性（async）和一个方法（execute)，这里拿concat命令来说明，如下：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_js  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;path&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//指示该命令是异步执行的，默认为false，命令结束后会自动调用 nextTask；&lt;/span&gt;
&lt;span class="c1"&gt;//如果为true，则需在本命令执行完成之后主动调用 nextTask&lt;/span&gt;
&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;async&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//命令的入口函数&lt;/span&gt;
&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;execute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;compileConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nextTask&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;//省略……&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;当concat命令被调用的时候，compiler会找到concat目录下的index.js，require之后执行它的execute方法，execute的参数说明如下：&lt;/span&gt;
&lt;/p&gt;


&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数名&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;task&lt;/td&gt;
&lt;td&gt;Object，这次命令调用要执行的任务，一个task包括任务id、任务要执行的命令（cmd）、任务的输入（source）、任务执行的输出目录（target）、任务的参数（params，也就是在config.json中配置的对应的params，比如下面示例代码中的custA_html中的params）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;compileConfig&lt;/td&gt;
&lt;td&gt;Object，执行compiler时传入的配置，也就是config.json内容&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;runOptions&lt;/td&gt;
&lt;td&gt;Object，执行该任务时的运行时信息，包括compiler的目录、命令的目录（concat的绝对路径）、命令的文件名（index.js的目录+名字）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nextTask&lt;/td&gt;
&lt;td&gt;Function，告诉compiler继续执行下一个命令，在设置了exports.async=true时，需要该命令主动调用，如：nextTask()。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="toc_1" class="h16"&gt;二、自定义命令&lt;/h2&gt;
&lt;p class="md_block md_block_as_opening md_has_block_below md_has_block_below_ol"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;自定义命令的写法很简单：&lt;/span&gt;
&lt;/p&gt;


&lt;ol&gt;
&lt;li class="md_li"&gt;&lt;span&gt; 只要建立一个目录，比如custA（这里我放到了项目根目录下的custom_cmds），创建index.js文件，并提供execute方法；
&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span&gt; 在config.json中配置该命令，让compiler知道哪里可以找到该命令。
&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;有了自定义命令的config.json的样子应该是类似这样的：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_json  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;sourceRoot&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;./&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;targetRoot&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;./build&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;fileFormat&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;js,css,html,htm,png,gif,jpg,jpeg,wav,json&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;cmds&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;custA&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;//配置自定义命令&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;custA&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;quot;root&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;./custom_cmds/custA/&amp;quot;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;rules&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;custA_html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;quot;cmd&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;custA&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;//使用自定义命令&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;quot;target&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;./&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;quot;source&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;./&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;quot;params&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
                 &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;如代码所示，只要在cmds项中，添加一个custA的json描述，给出id和根目录（root），其他事情就不用管了。&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_2" class="h16"&gt;三、组合命令&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;在&lt;a class="md_compiled" href="/nodejs-compiler-pipe/" title="Compiler@NodeJS（二）- 强大的管道"&gt;上一篇&lt;/a&gt;讲到，compiler最强大的是管道特性，可以用来将命令串联组合。有时候，一些任务可能需要很多个命令来组合完成，但是在每个rule里面写又不是很方便。这时候可以使用自定义命令的另外一种形式，组合命令。使用很简单，只要在config.json配置就行。&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_json  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;sourceRoot&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;./&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;targetRoot&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;./build&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;fileFormat&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;js,css,html,htm,png,gif,jpg,jpeg,wav,json&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;cmds&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;custB&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;translate|copy,compress&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;custC&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;custB|ispriter&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;rules&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;translate_html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;quot;cmd&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;custB&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;quot;parmas&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;/*..*/&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="err"&gt;｝&lt;/span&gt;
    &lt;span class="err"&gt;｝&lt;/span&gt;
&lt;span class="err"&gt;｝&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;其实组合命令就是把原有命令串、并联在一起，方便之后使用，同时组合命令还能再次被组合，是不是很神奇咧？哈哈。命令的组合原则可以看&lt;a class="md_compiled" href="/nodejs-compiler-pipe/"&gt;上一篇&lt;/a&gt;介绍。不过有点需要注意的，在使用组合命令时，传入的params需要一一对应，比较不顺手。如果是多次组合过的命令，params将变得更加复杂，不过暂时只能这样了。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;嗯，到这里，自定义命令的教程就结束了。如果你还是不太明白，可以到&lt;a class="md_compiled" href="https://github.com/iazrael/compiler"&gt;github&lt;/a&gt;中查看内置命令的实现，如：&lt;a class="md_compiled" href="https://github.com/iazrael/compiler/blob/master/cmds/template-picker/index.js"&gt;template-picker&lt;/a&gt;、&lt;a class="md_compiled" href="https://github.com/iazrael/compiler/blob/master/cmds/ioffline/index.js"&gt;ioffline&lt;/a&gt;、&lt;a class="md_compiled" href="https://github.com/iazrael/compiler/blob/master/cmds/concat/index.js"&gt;concat&lt;/a&gt;、&lt;a class="md_compiled" href="https://github.com/iazrael/compiler/blob/master/cmds/copy/index.js"&gt;copy&lt;/a&gt;等等，毕竟千言万语不及代码两行嘛，哈哈。有任何问题也可在本文留言，或者邮件给我，欢迎试用，^_^。&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>让Java跟Javascript更加亲密</title>

    <link href="http://imatlas.com/post/make-java-communicate-with-javascript-easily"  rel="alternate"></link>

    <updated>2013-02-19T08:28:00Z</updated>
    <id>make-java-communicate-with-javascript-easily</id>

    <author>
      <name>iAzrael</name>

    </author>
    <summary type="html">&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;在移动App开发中，为了快速迭代，通常都会使用Native+Web的模式开发。具体来说就是使用Java提供接口，使用WebView控件嵌套Web页面来实现UI和交互。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;在Android中，Java可以很方便的提供接口给WebView中的Js进行调用，只要以下一行代码就能搞定：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;mWebView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addJavascriptInterface&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;JavascriptInterface&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;custom_name&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;这样，JavascriptInterface的所有声明为public的方法，都能被mWebView中的Js通过以下方式调用：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_javascript  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;custom_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;xxx&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="c1"&gt;//xxx为JavascriptInterface的公有方法&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;而Java需要调用Js时，则是通过WebView实例的loadUrl方法调用：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;mWebView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;javascript:xxx(yyy)&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;这其实跟你在浏览器的地址栏敲下“&lt;code&gt;javascript：alert（1）&lt;/code&gt;”的原理是一样的。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;一切看起来都是那么的美好，只是……&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;当Java需要传递大量字符串给Js时，URL就力不从心了。另外，从URL执行的Js，在页面没加载完成时，是有可能导致页面出现undefined错误（因为要执行的那个方法可能还没有声明呢），会引发各种奇形怪状的错误。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;more&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;那要怎么办呢？&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;再回看上面Js调用Java接口的地方，可以发现，Js是可以直接调用Java方法并取得Java给的返回值的（必须是可序列化的数据）。那么，为何不试试把Java需要执行的Js方法，保存起来，让Js来读取、执行、并把结果写回？&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening md_has_block_below md_has_block_below_ol"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;步骤如下：&lt;/span&gt;
&lt;/p&gt;


&lt;ol&gt;
&lt;li class="md_li"&gt;&lt;span&gt; Java把Js调用（命令）和回调缓存，如保存到ArrayList；
&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span&gt; Js定时轮询Java提供的getCommandList接口；
&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span&gt; Js读取到要执行命令，执行它，并把结果通过setResult写回给Java；
&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span&gt; Java把对应命令的回调取出并执行。
&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;如此即完成了Java调用Js的流程。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;为了方便使用，简单的封装了下，名为&lt;a class="md_compiled" href="https://github.com/iazrael/AndroidJavascriptBridge"&gt;AndroidJavascriptBridge&lt;/a&gt;，可移步到&lt;a class="md_compiled" href="https://github.com/iazrael/AndroidJavascriptBridge"&gt;Github&lt;/a&gt;查看源码和示例（MainActivity.java和test.js ）。&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_0" class="h16"&gt;使用方法&lt;/h2&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;Android端调用, 加入com.imatlas.jsb 和 com.imatlas.util包, 按如下步骤调用&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;//1. 创建JavascriptBridge实例  &lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;JavascriptBridge&lt;/span&gt; &lt;span class="n"&gt;jsb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;JavascriptBridge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webView&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 

&lt;span class="c1"&gt;//2. 调用Javascript方法&lt;/span&gt;
&lt;span class="n"&gt;Bundle&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Bundle&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;asdfasdf&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;123123&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;jsb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;require&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;alert&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;JavascriptBridge&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Callback&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onComplate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JSONObject&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bundle&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;i&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;js response&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;//3. 提供Java方法给Javascript调用&lt;/span&gt;
&lt;span class="c1"&gt;//添加个 messagebox 方法给js&lt;/span&gt;
&lt;span class="n"&gt;jsb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addJavaMethod&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;messagebox&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;JavascriptBridge&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JSONObject&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Toast&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;makeText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getApplicationContext&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;Toast&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LENGTH_LONG&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;{\&amp;quot;ret\&amp;quot;:123}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;Javascript端的调用, 须先引入web/js/jsb.js, 之后按如下方式调用&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_javascript  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;//1. 调用Java方法&lt;/span&gt;
&lt;span class="nx"&gt;jsb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;messagebox&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;text&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;你好, messagebox!&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;调用messagebox回来啦\n&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;//2. 提供Javascript方法给Java调用&lt;/span&gt;
&lt;span class="nx"&gt;jsb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addJavascriptMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;alert&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;------\n&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;\n========\n&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;text&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;alert ok&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;IOS的话就要反过来了，要改成由Objective-C来轮询Js，来实现Js对Native的调用。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;嗯，等改天有时间了，就把IOS也封装进来，用起来就简单多了。&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>从网页监听Android设备的返回键</title>

    <link href="http://imatlas.com/post/monitoring-the-back-button-of-android-from-web"  rel="alternate"></link>

    <updated>2013-02-04T09:52:00Z</updated>
    <id>monitoring-the-back-button-of-android-from-web</id>

    <author>
      <name>iAzrael</name>

    </author>
    <summary type="html">&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;最近搞Android项目的时候，遇到一个比较蛋疼的需求，需要从Client App调用系统浏览器打开一个页面，进行杂七杂八的一些交互之后，返回到App。如何打开浏览器和如何返回App这里就不说了，有兴趣的童鞋可私下交流。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;之所以说这个需求蛋疼，是因为Android有个物理返回键啊……返回键啊……键啊……啊……&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;用户按下返回键后，预期应该跟点击页面上的返回键一样——返回App。然而这个返回键的被按下的时候网页完全不知道啊（onbeforeunload不算），找不到直接的办法去监听，愁死我们这全苦逼程序员鸟～&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;虽然啊不能直接监听，曲线救国的办法，还是有滴。more&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening md_has_block_below md_has_block_below_ol"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;经过艰苦卓绝的寻找，发现使用HTML5的History可以稍微模拟到返回键的按下事件。原理如下：&lt;/span&gt;
&lt;/p&gt;


&lt;ol&gt;
&lt;li class="md_li"&gt;&lt;span&gt; 页面加载完成时，调用history.pushState写入一个指定状态STATE，并监听window.onpopstate；
&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span&gt; 当onpopstate被触发时，检查event.state是否等于STATE，如果相等，表示页面发生了后退（按下返回键或者浏览器的后退按钮），则把这次行为当作是返回键被按下了（把点击浏览器的后退按钮也误算进来了，不过没啥好法子了呀）。
&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;嗯，为了方便调用，把这个逻辑稍微封装了下，代码见这里（&lt;a class="md_compiled" href="https://github.com/iazrael/xback"&gt;https://github.com/iazrael/xback&lt;/a&gt;），使用方法如下：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_javascript  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;XBack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;oh! you press the back button&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;XBack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ah, press press press&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening md_has_block_below md_has_block_below_ol"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;不过这个方法有些缺陷：&lt;/span&gt;
&lt;/p&gt;


&lt;ol&gt;
&lt;li class="md_li"&gt;&lt;span&gt; 如果项目本身使用了pushState，则历史记录会有瑕疵（多了一个历史）；
&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span&gt; 浏览器的后退按钮点击以及调用history.back()也会被当成按下了返回键。
&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;But anyway，对于结构和逻辑比较简单的跳转页来说（就是为了返回App用的），这个方法还是蛮实用的，对不对？嘻嘻～&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


</feed>