<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>写意生活 &#187; 前端开发</title>
	<atom:link href="http://x1989.com/category/webdev/frontend/feed" rel="self" type="application/rss+xml" />
	<link>http://x1989.com</link>
	<description>小谢的Blog — 认真生活 快乐工作 专注Web前后端开发&#124;移动平台</description>
	<lastBuildDate>Mon, 30 Apr 2012 11:29:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>阻止浏览器滚动条事件</title>
		<link>http://x1989.com/a/489.html</link>
		<comments>http://x1989.com/a/489.html#comments</comments>
		<pubDate>Sun, 26 Feb 2012 06:31:46 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[Web开发]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[mousewheel]]></category>
		<category><![CDATA[天猫]]></category>
		<category><![CDATA[购物袋]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=489</guid>
		<description><![CDATA[标题党。

在开发天猫迷你购物袋的过程当中，交互设计师要求当购物袋元素内的滚动条滚动到底（或顶部）并继续滚动，应不会影响到窗口滚动条的滚动，就像facebook的聊天窗口那样：



<span class="readmore"><a href="http://x1989.com/a/489.html" title="阻止浏览器滚动条事件">阅读全文——共709字</a></span>]]></description>
			<content:encoded><![CDATA[<p>标题党。</p>
<p>在开发天猫迷你购物袋的过程当中，交互设计师要求当购物袋元素内的滚动条滚动到底（或顶部）并继续滚动，应不会影响到窗口滚动条的滚动，就像facebook的聊天窗口那样：</p>
<p><img src="http://img04.taobaocdn.com/tps/i4/T1rV1VXfXaXXXXXXXX-243-575.jpg" alt="facebook聊天窗口" /></p>
<p>一开始以为在元素的onscroll事件里阻止默认事件就可以了，后来查阅资料发现原来要阻止的应该是onmousewheel事件（Firefox下的DOMMouseScroll）。</p>
<p>代码挺简单的</p>
<pre lang="javascript">
//mousewheel兼容处理
function mw_handler(ele, ev){
    var height = DOM.height(ele),
        scrollHeight = ele.scrollHeight,
        delta;
    //firefox除外的浏览器
    if(ev.wheelDelta) delta = ev.wheelDelta / 120;
    //firefox
    if(ev.detail) delta = -ev.detail / 3;
    //当存在滚动条时 一旦滚动到最顶或者最底 则阻止默认事件
    if(DOM.css(ele, 'overflowY') == 'scroll' &#038;&#038; ( (ele.scrollTop == (scrollHeight - height) &#038;&#038; delta < 0) || (ele.scrollTop ==0 &#038;&#038; delta > 0) )){
        ev.preventDefault();
    }
}
//firefox
if(S.UA.gecko){
    Event.on(conEl, 'DOMMouseScroll', function(e){
        mw_handler(this, e);
    });
}else{
    Event.on(conEl, 'mousewheel', function(e){
        mw_handler(this, e);
    });
}
</pre>
<p>
<img src="http://img02.taobaocdn.com/tps/i2/T1aMuUXbtvXXXXXXXX-387-331.png" alt="天猫购物袋" /></p>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/489.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>对IE6&#124;7浏览器提供localStorage支持</title>
		<link>http://x1989.com/a/484.html</link>
		<comments>http://x1989.com/a/484.html#comments</comments>
		<pubDate>Thu, 23 Feb 2012 02:45:21 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[Web开发]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[ie6]]></category>
		<category><![CDATA[ie7]]></category>
		<category><![CDATA[localStorage]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=484</guid>
		<description><![CDATA[localStorge是IE8以上版本和其他高级浏览器才具有的功能，本文通过在Window环境下对UserData进行封装，对IE6和IE7浏览器提供了与其他浏览器localStorage原生API兼容的方法，包括：setItem、getItem、removeItem以及clear。（tips:请在原生IE中测试，在IEtester中会引起IEtester崩溃）

源码：



<span class="readmore"><a href="http://x1989.com/a/484.html" title="对IE6&#124;7浏览器提供localStorage支持">阅读全文——共1397字</a></span>]]></description>
			<content:encoded><![CDATA[<p>localStorge是IE8以上版本和其他高级浏览器才具有的功能，本文通过在Window环境下对UserData进行封装，对IE6和IE7浏览器提供了与其他浏览器localStorage原生API兼容的方法，包括：setItem、getItem、removeItem以及clear。（tips:请在原生IE中测试，在IEtester中会引起IEtester崩溃）</p>
<p>源码：</p>
<pre lang="javascript">
/**
 * 对IE6|7浏览器提供localStorage支持
 * fanyu.xhy@tmall.com 2012-2-20
 */
;(function(){
    var S = KISSY, DOM = S.DOM,
        isIE67 = (S.UA.ie < <img src='http://x1989.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> ? true: false,
        _userDataEl,
        _saveFileName,
        _expires;
    if(isIE67 &#038;&#038; !window['localStorage']){
        var IELocalStorage = function(config){

            var _config = S.mix({
                'saveFileName': 'IELocalStorage',
                'expires': 365
            }, config);

            _saveFileName = _config.saveFileName;
            var _expires = new Date();

            _expires.setDate(_expires.getDate() + _config.expires);

            try{
                var _userDataEl = document.createElement('input');
                _userDataEl.type = 'hidden';
                _userDataEl.addBehavior('#default#userData');
                document.body.appendChild(_userDataEl);
                _userDataEl.expires = _expires.toUTCString();
            }catch(e){
                return false;
            }

            return {
                'setItem': function(key, value){
                    _userDataEl.load(_saveFileName);
                    _userDataEl.setAttribute(key, value);
                    _userDataEl.save(_saveFileName);
                },
                'getItem': function(key){
                    _userDataEl.load(_saveFileName);
                    return _userDataEl.getAttribute(key);
                },
                'removeItem': function(key){
                    _userDataEl.load(_saveFileName);
                    _userDataEl.removeAttribute(key);
                    _userDataEl.save(_saveFileName);
                },
                'clear': function(){
                    _userDataEl.load(_saveFileName);
                    var d = new Date();
                    d.setDate(d.getDate() - 1);
                    _userDataEl.expires = d.toUTCString();
                    _userDataEl.save(_saveFileName);
                }
            }

        }
        window['localStorage'] = IELocalStorage();
    }
})(KISSY);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/484.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uncaught TypeError: Property &#8216;submit&#8217; of object # is not a function</title>
		<link>http://x1989.com/a/476.html</link>
		<comments>http://x1989.com/a/476.html#comments</comments>
		<pubDate>Tue, 14 Feb 2012 11:00:42 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[Web开发]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[submit]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=476</guid>
		<description><![CDATA[今天在项目中遇到，如果一个表单元素内部含有name属性为submit的表单元素，如

&#60;input type="hidden" name="submit" /&#62;

那么当你用js提交该表单，即：

<span class="readmore"><a href="http://x1989.com/a/476.html" title="Uncaught TypeError: Property &#8216;submit&#8217; of object # is not a function">阅读全文——共287字</a></span>]]></description>
			<content:encoded><![CDATA[<p>今天在项目中遇到，如果一个表单元素内部含有name属性为submit的表单元素，如</p>
<pre lang="html">&lt;input type="hidden" name="submit" /&gt;</pre>
<p>那么当你用js提交该表单，即：<br />
form1.submit();<br />
会出现报错：<br />
Uncaught TypeError: Property &#8216;submit&#8217; of object #<HTMLFormElement> is not a function<br />
原因是form.xx 是会优先取得同名input元素，即那个元素，而DOM元素是不能被执行的，所以报错了。<br />
在国外网站上找到了吊爆的解决方案：</p>
<pre lang="javascript">document.createElement('form').submit.call(form1);</pre>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/476.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于一些编程语言的运算符“优先级”</title>
		<link>http://x1989.com/a/436.html</link>
		<comments>http://x1989.com/a/436.html#comments</comments>
		<pubDate>Tue, 12 Jul 2011 11:35:06 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web开发]]></category>
		<category><![CDATA[其他文章]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[运算符优先级]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=436</guid>
		<description><![CDATA[Tips:这个问题是铁军师兄发现并提出的，我写篇博客梳理一下。

当我们在学习一门编程语言的时候，我们经常会看到类似这样的一句话：运算符优先级是一套规则。该规则在计算表达式时控制运算符执行的顺序。具有较高优先级的运算符先于较低优先级的运算符执行。

那么事实是不是果真如此呢，下面让我们用Javascript等几门语言为例来验证一下。

<span class="readmore"><a href="http://x1989.com/a/436.html" title="关于一些编程语言的运算符“优先级”">阅读全文——共1627字</a></span>]]></description>
			<content:encoded><![CDATA[<p>Tips:这个问题是<a href="http://www.yigle.net/" title="铁军" target="_blank">铁军</a>师兄发现并提出的，我写篇博客梳理一下。<br />
当我们在学习一门编程语言的时候，我们经常会看到类似这样的一句话：运算符优先级是一套规则。该规则在计算表达式时控制运算符执行的顺序。具有较高优先级的运算符先于较低优先级的运算符执行。<br />
那么事实是不是果真如此呢，下面让我们用Javascript等几门语言为例来验证一下。<br />
首先，在官方的ECMA-262/Core JavaScript手册以及权威的MDN Docs中，分别是这样介绍Javascript运算符优先级的：</p>
<blockquote><p>
All operators have a pre-defined execution priority or precedence. Within a given complex expression, operations will be performed in order of priority.
</p></blockquote>
<blockquote><p>
Operator precedence determines the order in which operators are evaluated. Operators with higher precedence are evaluated first.
</p></blockquote>
<p>两段介绍的意思大致是一样的，都是说运算符优先级决定了运算符执行的先后顺序。运算符优先级高的运算符会被先执行（计算）。我们以往的编程经验似乎也在告诉我们这是真理，然而请先看下面一段代码：</p>
<pre>
var a=1;
function fn(){
    console.log(a);
}
var b = a++ + fn();
</pre>
<p>按照Javascript官方手册上对运算符优先级的定义以及的运算符优先级表（如图所示或参考http://rx4ajax-jscore.com/ecmacore/operator/predence.html），我们可以推算运行结果：在最后一行代码中，由于函数调用的括号运算符“()”优先级比自增运算符“++”和算术运算符“+”都要高，所以会先被执行。所以在控制台中被log的a的值应该是1。而事实上，结果是2。这说明了什么？——虽然“()”运算符的优先级比“++”要来得高，但a++却先于fn()被执行。<br />
<a href="http://x1989.com/wp-content/uploads/2011/07/javascriptPrecedence.png" target="_blank"><img src="http://x1989.com/wp-content/uploads/2011/07/javascriptPrecedence-300x98.png" alt="javascript优先级" title="javascriptPrecedence" width="300" height="98" class="alignnone size-medium wp-image-441" /></a><br />
图节选自Javascript运算符优先级表（http://rx4ajax-jscore.com/ecmacore/operator/predence.html）<br />
那么在Javascript中是这种状况，在其他语言中又会是什么情况呢？随后，我们分别测试了PHP、C/C++、Java以及C#版本的代码（Python和Ruby中没有自增运算符）。猜猜结果各是什么？<br />
PHP版：</p>
<pre>
$a=1;
function fn($a1){
    echo $a1;
}
$b = $a++ + fn($a);
</pre>
<p>C++版：</p>
<pre>
#include "stdafx.h"
#include &lt;iostream&gt;
using namespace std;
int fn(int a1)
{
	cout&lt;&lt;a1;
	return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
	int a = 1;
	int b = a++ + fn(a);
	int i;
	cin&gt;&gt;i;
	return 0;
}
</pre>
<p>揭晓答案：<br />
只有C/C++输出了1，其他语言都输出了2。<br />
这样看来似乎最传统的编译型语言C/C++能得出与其运算符优先级定义相符合的结果。而事实上关于运算符优先级，PHP手册是这样定义的：</p>
<blockquote><p>
The precedence of an operator specifies how “tightly” it binds two expressions together.
</p></blockquote>
<p>意思是运算符优先级决定了两个表达式之间“紧密程度”——也就是说代码的组合方式。这么一来PHP为什么输出2就能解释了。而C#和Java的代码，如果这么解释也能解释得清楚。不过在Java的运算符中，并没有函数调用的“()”运算符。C#当中却是有的。更有趣的是，在C/C++中，前自增/减运算符“++/&#8211;”的优先级居然排在了函数调用运算符“()”的前面，仅次于“::”运算符。<br />
结论：混乱啊。。</p>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/436.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一道Javascript面试题</title>
		<link>http://x1989.com/a/432.html</link>
		<comments>http://x1989.com/a/432.html#comments</comments>
		<pubDate>Mon, 11 Jul 2011 07:05:27 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[Web开发]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[面试题]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=432</guid>
		<description><![CDATA[var n = 2;

var showNumber = function(){

    n = 1;

<span class="readmore"><a href="http://x1989.com/a/432.html" title="一道Javascript面试题">阅读全文——共96字</a></span>]]></description>
			<content:encoded><![CDATA[<pre lang="javascript">
var n = 2;
var showNumber = function(){
    n = 1;
    alert(n);
}
(function(){
    n=3;
    alert(n);
})()
</pre>
<p>你能说出alert出的内容并解释其原因吗？</p>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/432.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>事件委托在jQuery和KISSY内核中的应用</title>
		<link>http://x1989.com/a/459.html</link>
		<comments>http://x1989.com/a/459.html#comments</comments>
		<pubDate>Mon, 11 Jul 2011 02:50:50 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[Web开发]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Kissy]]></category>
		<category><![CDATA[事件委托]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=459</guid>
		<description><![CDATA[一直觉得jQuery中的 .live() 方法很神奇，居然可以对动态加入的元素进行绑定。今天终于弄明白了，原来这是通过使用事件委托实现的。



   $('a').live('click', function(){

<span class="readmore"><a href="http://x1989.com/a/459.html" title="事件委托在jQuery和KISSY内核中的应用">阅读全文——共673字</a></span>]]></description>
			<content:encoded><![CDATA[<p>   一直觉得jQuery中的 .live() 方法很神奇，居然可以对动态加入的元素进行绑定。今天终于弄明白了，原来这是通过使用事件委托实现的。</p>
<pre>
   $('a').live('click', function(){
      //code block1
   })
   </pre>
<p>   上面的这段代码可以约等于（但不完全等于，总结中说明了为什么）：</p>
<pre>
   $(document).bind('click', function(e){
      if(e.srcElement.tagName == 'a'){
         //code block1
      }
   })
   </pre>
<p>   此外，jQuery还有一个 .delegate() 方法，可以实现接近 .live() 的效果：</p>
<pre>
   $('#container').delegate('a','click',function(){
      //code block2
   })
   </pre>
<p>   jQuery在文档中查找#container，并使用click事件和&#8217;a'这一CSS选择器作为参数，把函数绑定到$(&#8216;#container&#8217;)上。任何时候只要有事件冒泡到$(&#8216;#container&#8217;)上，它就查看该事件是否是click事件，以及该事件的目标元素是否与CSS选择器相匹配。如果两种检查的结果都为真的话，它就执行绑定的函数。<br />
   在KISSY 1.2版本中也引入了 .delegate() 方法。<br />
   <strong>这两种方法中，个人觉得还是 .delegate() 方法效率高。因为 .live() 方法需要把选择器匹配到的元素都包装成jQuery对象；而 .delegate() 方法只在委托的节点上监听冒泡事件。感觉用 .live() 方法进行事件委托比较鸡肋啊，可能这也是为什么其他js框架没有类似方法的原因吧。</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/459.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>javascript元编程创建DOM节点</title>
		<link>http://x1989.com/a/407.html</link>
		<comments>http://x1989.com/a/407.html#comments</comments>
		<pubDate>Fri, 06 May 2011 02:53:31 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[Web开发]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[元编程]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=407</guid>
		<description><![CDATA[在使用javascript创建DOM节点的过程中，难免要使用document.createElement、setAttribute、document.createTextNode等冗长、还有浏览器兼容性问题的节点操作方法，虽然有人提议使用字符串拼接后，再使用.innerHTML=可以降低创建节点的成本，而且还有更好的性能，但在我印象中innerHTML并不能适应所有需求（具体神马需求我也忘了），所以下面给大家介绍一种使用javascript元编程技巧来动态创建节点的方法。

那么什么是元编程呢？了解Ruby的同学知道，Ruby的风靡离不开Ruby on Rails(RoR)框架的推动。RoR框架通过魔幻实现质朴的方式，把很多需要用其他语言实现的功能用Ruby来实现，最经典当属RoR框架的ActiveRecord。让我们看一下下面这段代码：

<span class="readmore"><a href="http://x1989.com/a/407.html" title="javascript元编程创建DOM节点">阅读全文——共3522字</a></span>]]></description>
			<content:encoded><![CDATA[<p>在使用javascript创建DOM节点的过程中，难免要使用document.createElement、setAttribute、document.createTextNode等冗长、还有浏览器兼容性问题的节点操作方法，虽然有人提议使用字符串拼接后，再使用.innerHTML=可以降低创建节点的成本，而且还有更好的性能，但在我印象中innerHTML并不能适应所有需求（具体神马需求我也忘了），所以下面给大家介绍一种使用javascript元编程技巧来动态创建节点的方法。<br />
那么什么是元编程呢？了解Ruby的同学知道，Ruby的风靡离不开Ruby on Rails(RoR)框架的推动。RoR框架通过魔幻实现质朴的方式，把很多需要用其他语言实现的功能用Ruby来实现，最经典当属RoR框架的ActiveRecord。让我们看一下下面这段代码：</p>
<pre lang="ruby">
person = Person.find_by_email('xxx@x1989.com')
person.age = 23
person.save
</pre>
<p>上述代码可以用SQL语句替换，如下所示：</p>
<pre lang="SQL">
SELECT * FROM person WHERE email = 'xxx@x1989.com'
UPDATE person SET age = 23 WHERE email = 'xxx@x1989.com'
</pre>
<p>即使不会Ruby和SQL的人也可以看出，采用Ruby语法方式更自然。而正是Rails通过元编程技巧，让我们无须在一个程序中混用两种不同的语言。维基百科上元编程的定义：</p>
<blockquote><p>编写一些程序来提前生成一些数据或代码供运行时使用，用来生成这些数据信息或代码的程序称为元程序（MetaProgram），编写这种程序就称为元编程（MetaProgramming）。</p></blockquote>
<p>另一种说法：</p>
<blockquote><p>元编程是指某类计算机程序的编写，这类计算机程序编写或者操纵其它程序（或者自身）作为它们的数据，或者在运行时完成部分本应在编译时完成的工作。</p></blockquote>
<p>那么，我希望用javascript实现”create_”+任意HTML5标签名的动态节点生成函数，比如用create_form、create_div、create_input来生成对应名称的节点，使用下面的api：</p>
<pre>
//①创建只含有文本的节点
var span = create_span('hello world');
或不含文本的节点
var br = create_br();

//②可以在参数1中以对象字面量来定义属性
var input = create_input({
    'type': 'text',
    'size': 20,
    'value': '123'
})

//③用参数2定义文本节点
var a = create_a({
    'href': 'http://www.google.com.hk',
    'title': '谷歌搜索',
    'target': '_blank',
    'rel': 'xxxxx',
    'costom_attr': '自定义属性',
}, '搜索');

//④参数2可以是节点 参数3（可选）是文本节点
var div = create_div({}, create_img({'src': 'http://www.google.com.hk/intl/zh-CN/images/logo_cn.png'}), '这是logo')

//⑤参数2也可以是节点构成的数组
var ul = create_ul({
	'class': 'list1'
}, [create_li('项目1'), create_li('项目2'), create_li('项目3')]);
</pre>
<p>实现方式：</p>
<pre lang="javascript">
void function() {
    //支持以"create_"+任意HTML5标签名的动态节点生成函数
    var doc = document, win = window,
    //HTML5标签:
    tags = ["a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdo", "big", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "command", "datagrid", "datalist", "datatemplate", "dd", "del", "details", "dialog", "dir", "div", "dfn", "dl", "dt", "em", "embed", "event-source", "fieldset", "figure", "font", "footer", "form", "frame", "frameset", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hr", "html", "i", "iframe", "img", "input", "ins", "isindex", "kbd", "label", "legend", "li", "link", "m", "map", "menu", "meta", "meter", "nav", "nest", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "pre", "progress", "q", "rule", "s", "samp", "script", "section", "select", "small", "source", "span", "strike", "strong", "style", "sub", "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "tt", "u", "ul", "var", "video", "xmp"];
    for (var i = 0; tags[i]; i++) {
        //闭包是个好东东
        win['create_' + tags[i]] = function(tag) {
            return function(attrs, childNode, textNode) {
                return createNode(tag, attrs, childNode, textNode)
            }
        } (tags[i]);
    }
    var createNode = function (tagName, attrs, childNode, textNode) {
        //创建以tagName命名的节点
        var node = doc.createElement(tagName);

        //处理attrs参数 设置节点属性
        typeof attrs === 'string' ? createTextNode(node, attrs) : createAttributeNode(node, attrs); //创建并设置属性节点
        //处理childNode参数 添加子节点
        if (typeof childNode === 'string') {
            createTextNode(node, childNode);
        } else if (childNode &#038;&#038; childNode.nodeName) {
            node.appendChild(childNode)
        } else if (childNode instanceof Array) {
            for (var i = 0; childNode[i]; i++) {
                node.appendChild(childNode[i])
            }
        }

        //处理文本节点
        if (textNode &#038;&#038; typeof textNode === 'string') {
            createTextNode(node, textNode);
        }
        return node;
    }
    var createAttributeNode = function(node, attrs) {
        for (var i in attrs) {
            //下面这种方式适用于原生的节点属性
            //node[i] = attrs[i];
            //在IE下setAttribute设置某些原生属性会有兼容性问题
            //node.setAttribute(i, attrs[i]);
            //document.createAttribute在IE下设置原生属性会不带引号
            var a = doc.createAttribute(i);
            a.value = attrs[i];
            node.setAttributeNode(a);
        }
    }
    var createTextNode = function (node, text) {
        node.appendChild(doc.createTextNode(text))
    }
} ();
</pre>
<p><b><a href="http://x1989.com/demos/nodecreator/source.html" target="_blank">Demo</a></b><br />
文档？足够的注释不需要文档！</p>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/407.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Javascript惰性函数函数的应用</title>
		<link>http://x1989.com/a/391.html</link>
		<comments>http://x1989.com/a/391.html#comments</comments>
		<pubDate>Mon, 18 Apr 2011 10:41:25 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[Web开发]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[惰性函数]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=391</guid>
		<description><![CDATA[function addEvent(element, type, func) {

	if (document.addEventListener)

		element.addEventListener(type, func);

<span class="readmore"><a href="http://x1989.com/a/391.html" title="Javascript惰性函数函数的应用">阅读全文——共633字</a></span>]]></description>
			<content:encoded><![CDATA[<pre lang="javascript">
function addEvent(element, type, func) {
	if (document.addEventListener)
		element.addEventListener(type, func);
	else
		element.attachEvent(type, func);
}
</pre>
<p>上面的函数在每次调用的时候都会检测document.addEventListener是否存在，并用它绑定一个事件，如果不存在，就使用ie的方式绑定事件。<br />
这个函数工作得很好，尽管它在浏览器的兼容性检测上还不够完善。但从性能的角度出发上，我们可以做得更好：只执行一次检测，就是在函数第一次被调用的时候。<br />
为了达到这个目的，我们使用一个javascript的惰性加载特性（http://peter.michaux.ca/articles/lazy-function-definition-pattern）</p>
<pre lang="javascript">
function addEvent(element, type, func) {
	if (document.addEventListener) {
		addEvent = function(element, type, func) {
			element.addEventListener(type, func)
		}
	}else{
		addEvent = function(element, type, func) {
			element.attachEvent(type, func)
		}
	}
	return addEvent(element, type, func)
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/391.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Kissy中jsonp api的bug</title>
		<link>http://x1989.com/a/387.html</link>
		<comments>http://x1989.com/a/387.html#comments</comments>
		<pubDate>Fri, 15 Apr 2011 11:56:57 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[Web开发]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jsonp]]></category>
		<category><![CDATA[Kissy]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=387</guid>
		<description><![CDATA[在相邻的代码里多次调用Kissy的jsonp方法，调用十次大概会出现六次的：Uncaught ReferenceError: jsonp1302852733609 is not defined(anonymous function).同事仙羽查看源码发现，是kissy的jsonp api是调用太快了，产生了同一个时间戳。。两次请求返回的都是同个函数调用，但是kissy里面的jsonp有个垃圾收集的处理，结果把这个函数给删了，第二次再调用的时候就调用不到了。算是kissy的bug吧，应该用guid的。出错代码如下

<span class="readmore"><a href="http://x1989.com/a/387.html" title="Kissy中jsonp api的bug">阅读全文——共263字</a></span>]]></description>
			<content:encoded><![CDATA[<p>在相邻的代码里多次调用Kissy的jsonp方法，调用十次大概会出现六次的：Uncaught ReferenceError: jsonp1302852733609 is not defined(anonymous function).同事仙羽查看源码发现，是kissy的jsonp api是调用太快了，产生了同一个时间戳。。两次请求返回的都是同个函数调用，但是kissy里面的jsonp有个垃圾收集的处理，结果把这个函数给删了，第二次再调用的时候就调用不到了。算是kissy的bug吧，应该用guid的。出错代码如下</p>
<pre>
for(var i=0;i<10;i++){
    KISSY.jsonp('http://110.75.14.39/home/recommendTmallSpu.htm?appID=87&#038;num=4&#038;key=110202',function(data){
        console.log(data);
    })
}
</pre>
<p>问题就出现在ajax模块下的这行代码：</p>
<pre>
jsonp = c['jsonpCallback'] || JSONP + S.now();
</pre>
<p>贴一段jQuery源码中的实现：</p>
<pre>
// 默认的发起jsonp请求的设置 即url中callback=?的情况 回调函数也是"jsonp_"+时间错
jQuery.ajaxSetup({
	jsonp: "callback",
	jsonpCallback: function() {
		return jQuery.expando + "_" + ( jsc++ );
	}
});

// 装载jsonp的callback函数
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {

	var dataIsString = ( typeof s.data === "string" );

	if ( s.dataTypes[ 0 ] === "jsonp" ||
		originalSettings.jsonpCallback ||
		originalSettings.jsonp != null ||
		s.jsonp !== false &#038;&#038; ( jsre.test( s.url ) ||
				dataIsString &#038;&#038; jsre.test( s.data ) ) ) {
                //响应容器
		var responseContainer,
			jsonpCallback = s.jsonpCallback =
				jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
			previous = window[ jsonpCallback ],
			url = s.url,
			data = s.data,
			replace = "$1" + jsonpCallback + "$2",
			cleanUp = function() {
				window[ jsonpCallback ] = previous;
				// 当有请求时调用callback
				if ( responseContainer &#038;&#038; jQuery.isFunction( previous ) ) {
					window[ jsonpCallback ]( responseContainer[ 0 ] );
				}
			};

		if ( s.jsonp !== false ) {
			url = url.replace( jsre, replace );
			if ( s.url === url ) {
				if ( dataIsString ) {
					data = data.replace( jsre, replace );
				}
				if ( s.data === data ) {
					// Add callback manually
					url += (/\?/.test( url ) ? "&#038;" : "?") + s.jsonp + "=" + jsonpCallback;
				}
			}
		}

		s.url = url;
		s.data = data;

		// 装载callback
		window[ jsonpCallback ] = function( response ) {
			responseContainer = [ response ];
		};

		// Install cleanUp function
		jqXHR.then( cleanUp, cleanUp );
</pre>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/387.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>受doctype影响的内嵌img标签的td高度</title>
		<link>http://x1989.com/a/355.html</link>
		<comments>http://x1989.com/a/355.html#comments</comments>
		<pubDate>Thu, 24 Mar 2011 05:50:09 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[Web开发]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[doctype]]></category>
		<category><![CDATA[img]]></category>
		<category><![CDATA[td]]></category>
		<category><![CDATA[高度]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=355</guid>
		<description><![CDATA[在工作中遇到一个问题，在html5页面下，使用table布局，td包含img标签，如果td内还含有空白字符，那么td的高度就会出错，导致页面出现空白/间隙，设置了img的vertical-align:top问题依然存在。google了一下，发现stack exchange上有人早就在一年多以前发现doctype在XHTML 1.0 strict下存在该问题并有了解决方案：把空白字符去掉或者设置line-height:1px，img{display:block;}也可以。
原因是在块级元素中单个字符（包括空格）都要占用一个单行，所以块级元素至少要暂用一行的高度，把行高设置成1px就了。]]></description>
			<content:encoded><![CDATA[<p>在工作中遇到一个问题，在html5页面下，使用table布局，td包含img标签，如果td内还含有空白字符，那么td的高度就会出错，导致页面出现空白/间隙，设置了img的vertical-align:top问题依然存在。google了一下，发现stack exchange上有人早就在一年多以前发现doctype在XHTML 1.0 strict下存在该问题并有了解决方案：把空白字符去掉或者设置line-height:1px，img{display:block;}也可以。<br />
原因是在块级元素中单个字符（包括空格）都要占用一个单行，所以块级元素至少要暂用一行的高度，把行高设置成1px就了。<br />
<a href="http://stackoverflow.com/questions/1450274/why-td-height-not-equal-to-img-height-inside-of-it-when-doctype-is-xhtml-1" target="_blank" rel="nofollow">http://stackoverflow.com/questions/1450274/why-td-height-not-equal-to-img-height-inside-of-it-when-doctype-is-xhtml-1</a></p>
<blockquote><p>The size of block-level element (td, div, etc) if not specified will only be as big as needed, according to the space taken by its content. If specified, it will try to expand accordingly, except if the content is bigger, in which case it will expand as necessary.<br />
In your example, the cell contains a single character (the non-breaking space), which take the size of single line. Hence, the block element must be at least 1 line-height high; it can&#8217;t assume any smaller size. This is why your height declaration was ignored.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/355.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

