<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.yigle.net/styles/feedsky0.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link href="http://feed.yigle.net" type="application/rss+xml" rel="self"></atom:link><fs:self_link href="http://feed.feedsky.com/yigle" type="application/rss+xml"></fs:self_link><lastBuildDate>Mon, 14 Nov 2011 15:16:20 GMT</lastBuildDate><title>一阁</title><description>学习,生活,追求与梦想</description><link>http://www.yigle.net</link><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><language>en</language><pubDate>Fri, 24 Feb 2012 12:49:14 GMT</pubDate><item><title>2维平面相交（一）：两矩形区域相交</title><link>http://www.yigle.net/2011/11/2d-cross-two-regions/</link><content:encoded>&lt;p&gt;最近遇到几种相交问题，看似简单的逻辑，却有多种不同的算法，不知你是否考虑过所用的算法好不好的问题。&lt;/p&gt;
&lt;h2&gt;两矩形区域相交&lt;/h2&gt;
&lt;p&gt;在写&lt;a href=&quot;/demo/randshow.html&quot; target=&quot;_blank&quot;&gt;随机展示&lt;/a&gt;的一个模块时,需要判断随机生成的区域与原有区域是否相交&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.yigle.net/yigle.net/wp-content/uploads/2011/11/cross-region1.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-37426&quot; title=&quot;cross-region&quot; src=&quot;http://www.yigle.net/yigle.net/wp-content/uploads/2011/11/cross-region1.png&quot; alt=&quot;cross-region&quot; width=&quot;431&quot; height=&quot;226&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最初想到的方法是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;算法一：如果一个区域有一点在另一区域中，那么两个区域一定相交&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;js实现代码：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;// 判断点在矩形内
function _inRegion(point, region) {

    return point[0] &amp;lt; region.right &amp;amp;&amp;amp; point[0] &amp;gt; region.left
        &amp;amp;&amp;amp; point[1] &amp;lt; region.top &amp;amp;&amp;amp; point[1] &amp;gt; region.bottom;

}
// 判断矩形1是否有点在矩形2中
function _isCross(region1, region2) {

    return  _inRegion([region1.left,region1.top], region2) ||
        _inRegion([region1.right,region1.top], region2) ||
        _inRegion([region1.right,region1.bottom], region2) ||
        _inRegion([region1.left,region1.bottom], region2);

}

function isCross(region1, region2) {

    return _isCross(region1, region2) || _isCross(region2, region1);

}&lt;/pre&gt;
&lt;p&gt;看到上面的代码觉得实现太麻烦了吧，再来看一种算法：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;算法二：如果两个矩形相交，则必然存在线条交叉，而能交叉的线条只有横线和竖线，两根横线或两根竖线都不可能交叉。所以，这个问题就转化成寻找是否存在交叉的横线与竖线。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;实现代码：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;// 判断横线1是否与竖线2相交
function _crossLine(line1, line2) {
    return line1.from[1] &amp;lt; line2.from[1] &amp;amp;&amp;amp; line1.to[1] &amp;gt; line2.to[1] &amp;amp;&amp;amp;
        line1.from[0] &amp;lt; line2.from[0] &amp;amp;&amp;amp; line1.to[0] &amp;gt; line2.to[0];
}
//判断矩形1横线是否与矩形2竖线相交
function _isCross(r1, r2) {
    return _crossLine({from:[r1.left,r1.top],to:[r1.right,r1.top]},
        {from:[r2.left,r2.top],to:[r2.left,r2.bottom]}) ||
        _crossLine({from:[r1.left,r1.bottom],to:[r1.right,r1.bottom]},
            {from:[r2.left,r2.top],to:[r2.left,r2.bottom]}) ||
        _crossLine({from:[r1.left,r1.top],to:[r1.right,r1.top]},
            {from:[r2.right,r2.top],to:[r2.right,r2.bottom]}) ||
        _crossLine({from:[r1.left,r1.bottom],to:[r1.right,r1.bottom]},
            {from:[r2.right,r2.top],to:[r2.right,r2.bottom]});
}
function isCross(region1, region2) {
    return _isCross(region1, region2) || _isCross(region2, region1);
}&lt;/pre&gt;
&lt;p&gt;这种看起来也不简单，但至少是一种思路，还有其他算法吗？有&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;算法三：如果两个矩形相交，相交区域一定是个点或者矩形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;实现代码：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function isCross(region1, region2) {
    var left = Math.max(region1.left, region2.left),
        right = Math.min(region1.right, region2.right),
        top = Math.min(region1.top, region2.top),
        bottom = Math.max(region.bottom, region.bottom);
    return left &amp;lt; right &amp;amp;&amp;amp; bottom &amp;gt; top;
}&lt;/pre&gt;
&lt;p&gt;我靠，代码瞬间减少了很多，再看一种算法：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;算法四：如果矩形1的一边距离到矩形2对应边的距离小于等于矩形1的宽度或高度 =&amp;gt;两矩形相交&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;实现代码：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function isCross(region1, region2) {
    return (region2.left &amp;gt; region1.left &amp;amp;&amp;amp;
            region2.left - region1.left &amp;lt; region1.right - reigon1.left) ||
        (region2.top &amp;gt; region1.top &amp;amp;&amp;amp;
            region2.top - region1.top &amp;lt; region2.top - region2.bottom) ||
        (region1.left &amp;gt; region2.left &amp;amp;&amp;amp;
            region1.left - region2.left &amp;lt; region2.right - reigon2.left) ||
        (region1.top &amp;gt; region2.top &amp;amp;&amp;amp;
            region1.top - region2.top &amp;lt; region1.top - region1.bottom);
}&lt;/pre&gt;
&lt;p&gt;貌似代码有优化的空间，先不管，考虑还有没有更简练的算法？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;算法五：如果一个矩形在另一矩形所形成的四个区间外 &amp;lt;=&amp;gt; 两个矩形不想交&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;实现代码：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function isCross(region1, region2) {
    return !(region1.left &amp;gt; region2.right || region1.right&amp;lt;region2.left||
        region1.bottom &amp;gt; region2.top || region1.top &amp;lt; region2.bottom);
}&lt;/pre&gt;
&lt;p&gt;看到这种算法时，我震惊了，无论从代码量还是性能上都优于上面的算法，当然如果需要获取相交区域，算法3更好。&lt;/p&gt;
&lt;p&gt;回头看看上面5种算法，从不同的角度出发得到不同的算法：算法1从点的角度触发，算法2从线的角度，&lt;br /&gt;
算法3从区域的角度，算法4从一维距离角度，算法5从区间的角度；思量一下，前4种算法都是正向思维，第5种逆向思维；&lt;br /&gt;
逆向思维，也许自己太多过程式编程脑子秀逗了，好的算法醍醐灌顶。&lt;/p&gt;
&lt;p&gt;结束，下一篇关于如何判断两个线段是否相交，你如何实现？&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/609431516/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/11/2d-cross-two-regions/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.yigle.net/2011/11/2d-cross-two-regions/feed/</wfw:commentRss><slash:comments>8</slash:comments><description>最近遇到几种相交问题，看似简单的逻辑，却有多种不同的算法，不知你是否考虑过所用的算法好不好的问题。
两矩形区域相交
在写随机展示的一个模块时,需要判断随机生成的区域与原有区域是否相交&lt;img src=&quot;http://www1.feedsky.com/t1/609431516/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/11/2d-cross-two-regions/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>算法</category><category>相交</category><category>Javascript</category><pubDate>Mon, 14 Nov 2011 23:16:20 +0800</pubDate><author>Tiejun</author><comments>http://www.yigle.net/2011/11/2d-cross-two-regions/#comments</comments><guid isPermaLink="false">http://www.yigle.net/?p=37422</guid><dc:creator>Tiejun</dc:creator><fs:srclink>http://www.yigle.net/2011/11/2d-cross-two-regions/</fs:srclink><fs:srcfeed>http://www.yigle.net/feed</fs:srcfeed><fs:itemid>feedsky/yigle/~7882683/609431516/5992322</fs:itemid></item><item><title>使用IE selection 两个问题</title><link>http://www.yigle.net/2011/08/two-problems-with-ie-selection/</link><content:encoded>&lt;p&gt;最近用到IE的document.selection，遇到两个问题：&lt;/p&gt;
&lt;h3&gt;1.selection.clear file表单 导致form 无法 submit&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;/demo/selection-clear-form-submit.html&quot; target=&quot;_blank&quot;&gt;demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;第一次点击提交按钮无法提交表单&lt;br /&gt;
&lt;strong&gt;说明：&lt;/strong&gt;ie浏览器不允许直接通过value=“”方式情空文件控件，所以尝试使用selection.clear清除，就会引发这个问题&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决方法：&lt;/strong&gt;使用form的原生reset清空&lt;/p&gt;
&lt;h3&gt;2.selection.emtpy 触发 window.blur&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;/demo/ie-selection-empty-fire-blur.html&quot; target=&quot;_blank&quot;&gt;demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;选择一段文字后，在空白处点击，浏览器默认清除选择，触发window blur&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;说明：&lt;/strong&gt;ie8-以下才会这样，ie9其他标准浏览器都不触发；显示调用 selection.empty方法，及浏览器默认改变选择都触发&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决方法：&lt;/strong&gt;mousedown中延时注册blur，因为是在mousedown 之后触发的，通过延时注册，让其先触发&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/609431517/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/08/two-problems-with-ie-selection/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.yigle.net/2011/08/two-problems-with-ie-selection/feed/</wfw:commentRss><slash:comments>1</slash:comments><description>最近用到IE的document.selection，遇到两个问题：
1.selection.clear file表单 导致form 无法 submit
demo
第一次点击提交按钮无法提交表单&lt;img src=&quot;http://www1.feedsky.com/t1/609431517/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/08/two-problems-with-ie-selection/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>blur</category><category>submit</category><category>selection</category><category>bug</category><category>Javascript</category><pubDate>Tue, 09 Aug 2011 17:08:12 +0800</pubDate><author>Tiejun</author><comments>http://www.yigle.net/2011/08/two-problems-with-ie-selection/#comments</comments><guid isPermaLink="false">http://www.yigle.net/?p=37391</guid><dc:creator>Tiejun</dc:creator><fs:srclink>http://www.yigle.net/2011/08/two-problems-with-ie-selection/</fs:srclink><fs:srcfeed>http://www.yigle.net/feed</fs:srcfeed><fs:itemid>feedsky/yigle/~7882683/609431517/5992322</fs:itemid></item><item><title>JS简单拖放程序</title><link>http://www.yigle.net/2011/08/simple-drag-and-drop-program/</link><content:encoded>&lt;p&gt;在大学做web应用时，就搞过拖放，当时从网上搜索的相关程序，感觉代码很复杂，最终效果还不好，自己也没调通，所以在脑子里总感觉拖放是很复杂的东西。最近正好有时间，再写下这种程序。&lt;/p&gt;
&lt;p&gt;要实现拖放，基本思路就是：鼠标点下时监听移动，抬起时停止监听。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;        var x,y;
        function move(e) {
            el.style.left = e.clientX - x + 'px';
            el.style.top =  e.clientY - y + 'px';
        }

        function stop() {
            E.detach(document, 'mousemove', move);
            E.detach(document, 'mouseup', stop);
        }
        E.on(el, 'mousedown', function(e) {

            x = e.clientX - el.offsetLeft;
            y = e.clientY - el.offsetTop;
            E.on(document, 'mousemove', move);
            E.on(document, 'mouseup', stop);

        });&lt;/pre&gt;
&lt;p&gt;这样拖放就实现了，当然还有一些问题：&lt;/p&gt;
&lt;h3&gt;拖放禁止&lt;/h3&gt;
&lt;p&gt;1.当第一次拖放后，再次拖放元素就会发现会出现拖放禁止图标，是因为第一次拖放时点击拖放元素，拖放元素被选择，第二次拖放时使用了浏览器默认拖放。浏览器对于 image，link，selection默认是可以拖放的。&lt;/p&gt;
&lt;p&gt;2.拖放过程中移动到其他元素时，其他元素被选择，再次拖放也会出现拖放禁止图标，原因同上。&lt;/p&gt;
&lt;p&gt;解决这个问题:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方法一：preventDefault&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;问题1，在mousedown中阻止默认动作，防止元素被选择；问题2，在mousemove中阻止默认动作，防止其他元素被选择(opera貌似无效)。&lt;/p&gt;
&lt;p&gt;这个方法有点体验不足：在ie9，ff等现代浏览器将 “清除之前选择”的默认动作也阻止了，如果之前有选择内容，拖放时原选择不会被清除。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方法二：清空 selection&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;mousedown,mousemove的时候清空一下selection即可解决上面两个问题&lt;/p&gt;
&lt;p&gt;有的程序也通过setCapture来阻止默认事件，并且扩大捕获，兼容性不好不考虑；&lt;/p&gt;
&lt;p&gt;综合考虑，采用清空selection比较好。&lt;/p&gt;
&lt;h3&gt;异常终止问题&lt;/h3&gt;
&lt;p&gt;1.窗口失去焦点时（如：alt+tab切换，alert等），无法触发mouseup（chrome 可以触发），导致拖放不终止，回到窗口时继续拖放，体验不好&lt;/p&gt;
&lt;p&gt;2.页面中存在iframe时，鼠标移动到iframe中事件传递到iframe的document中，无法到达原来的document导致无法触发mouseup，mousemove等&lt;/p&gt;
&lt;p&gt;解决第一个问题，可以监听下window blur事件，终止拖放；但这里有个问题：ie通过document.selection.empty()方法清除selection，当selection有内容时，&lt;a href=&quot;http://www.yigle.net/2011/08/two-problems-with-ie-selection/&quot; target=&quot;_blank&quot;&gt;导致window触发blur事件&lt;/a&gt;，拖放终止。这个触发是在mousedown处理完之后触发的，即window blur注册之后再触发，解决可以考虑setTimeout延时注册下。&lt;/p&gt;
&lt;p&gt;解决第二个问题，考虑将事件仍传递到本页面document，可以建个遮罩层将iframe遮挡(为了简洁，这里不实现)。&lt;/p&gt;
&lt;p&gt;这样简单的拖放程序就出来了，&lt;a href=&quot;/demo/drag.html&quot; target=&quot;_blank&quot;&gt;demo&lt;/a&gt;，code：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function Drag(el) {
    this.el = el;
    this._initEvents();
}

Drag.prototype = {
    moveTo : function(x, y) {
        var el = this.el;
        el.style.left = x + 'px';
        el.style.top = y + 'px';
    },
    _initEvents : function() {

        var x,y,self = this,el = this.el;

        function move(e) {
            // 防止移动过程中选择其他元素，保证体验一致
            util.clearSelection();
            self.moveTo(e.clientX - x, e.clientY - y);
        }

        function stop() {
            E.detach(document, 'mousemove', move);
            E.detach(document, 'mouseup', stop);
            E.detach(window, 'blur', stop);
        }

        E.on(this.el, 'mousedown', function(e) {

            // 清除之前选择，防止拖拽时禁止
            util.clearSelection();

            var style = util.getComputeStyle(el);
            x = e.clientX - el.offsetLeft + (parseInt(style.marginLeft) || 0);
            y = e.clientY - el.offsetTop + (parseInt(style.marginTop) || 0);

            E.on(document, 'mousemove', move);
            E.on(document, 'mouseup', stop);
            // 失去焦点时终止   document.selection.empty() 会触发blur，延时注册
            setTimeout(function(){E.on(window, 'blur', stop);},0);
        });
    }
};&lt;/pre&gt;
&lt;p&gt;如果要做成组件，当然还需要考虑全面一些，如：iframe情况，移动范围，非绝对定位元素，移动元素和控制元素不同，相关事件支持等等。现在回头看看实现不复杂，只是遇到问题时自己跑偏了，之前看过&lt;a href=&quot;http://www.cnblogs.com/cloudgamer/archive/2008/11/17/1334778.html&quot; target=&quot;_blank&quot;&gt;《JavaScript 拖放效果》&lt;/a&gt;这篇文章，觉得很多问题需要处理，然后写的时候遇到问题就去看文中的介绍，而并没真正从问题本身和解决方法上入手，结果严重影响了效率，而且弄的晕头转向，不知在为了解决什么问题而加代码。有参考固然是好的，但是需要更多的独立思考，理清思路，关注本质，这样程序才能得心应手，才是自己的程序。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/609431518/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/08/simple-drag-and-drop-program/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.yigle.net/2011/08/simple-drag-and-drop-program/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>在大学做web应用时，就搞过拖放，当时从网上搜索的相关程序，感觉代码很复杂，最终效果还不好，自己也没调通，所以在脑子里总感觉拖放是很复杂的东西。最近正好有时间，再写下这种程序。
要实现拖放，基本思路就是：鼠标点下时监听移动，抬起时停止监听。
        var x,y;
        function move(e) {&lt;img src=&quot;http://www1.feedsky.com/t1/609431518/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/08/simple-drag-and-drop-program/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>selection</category><category>setCapture</category><category>preventDefault</category><category>Javascript</category><pubDate>Tue, 09 Aug 2011 16:07:54 +0800</pubDate><author>Tiejun</author><comments>http://www.yigle.net/2011/08/simple-drag-and-drop-program/#comments</comments><guid isPermaLink="false">http://www.yigle.net/?p=37380</guid><dc:creator>Tiejun</dc:creator><fs:srclink>http://www.yigle.net/2011/08/simple-drag-and-drop-program/</fs:srclink><fs:srcfeed>http://www.yigle.net/feed</fs:srcfeed><fs:itemid>feedsky/yigle/~7882683/609431518/5992322</fs:itemid></item><item><title>web中的字符编码</title><link>http://www.yigle.net/2011/07/character-encoding-on-web/</link><content:encoded>&lt;p&gt;web开发中经常遇到各种乱码问题，原因都是编码不一致造成的。字符编码究竟起什么作用，如何运作的呢？先来了解一些基本概念：&lt;/p&gt;
&lt;h3&gt;字符集、编码字符集、字符编码&lt;/h3&gt;
&lt;h4&gt;&lt;strong&gt;字符集&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;字符集就是一些字符的集合，比如我们使用的中文就可以看成一种字符集&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;编码字符集&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;是指每个字符都有唯一数字与之对应的字符集，每个单元编码字符被称作码点。码点的值表示着字符所在字符集中的位置，这样我们就可以通过具体的数字根据编码字符集找到相应的字符。&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;字符编码&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;字符编码表示这编码字符集码点值如何被映射成计算机中的字节。对于编码字符集，虽然对每个字符有了唯一的索引，但是要表示在计算机中，必须以字节的形式表示，而字符编码，正是表示这一映射过程。这样计算机就可以跟进字节和码点值的映射关系跟进字符集找到相应的字符。当然我们可以简单的将码点值直接转换成对应的计算机字节，码点值是65在计算机中也用65表示，这种编码方式最简单，ISO 8859系列字符集就是采用这种编码方式；但是为了优化之一映射过程还有其他编码方式，同一编码字符集也可以有多种编码方式，比如我们熟悉的Unicode字符集，就有UTF-8, UTF-16, and UTF-32编码方式，不同编码方式映射到计算机表示的字节就有可能不同。&lt;/p&gt;
&lt;p&gt;字符编码就是计算机找到对应字符的钥匙，钥匙指定错了，计算机找到字符也就不正确了，这就是我们遇到乱码的原因。&lt;/p&gt;
&lt;p&gt;在web中又是如何指定字符编码的呢？我们再来看下HTTP Header中关于字符的几个字段：&lt;/p&gt;
&lt;h3&gt;HTTP Header&lt;/h3&gt;
&lt;h4&gt;&lt;strong&gt;Accept-Charset&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Accept-Charset 字段表示可以响应采用哪些字符集编码是可以接受。服务器可以跟据这个字段了解客户端接受字符集的能力。当服务器不能提供相应字符集编码的数据时，就会返回406状态码，或者一个unacceptable response。这个字段平常打交道比较少，再看另一个非常重要的字段：&lt;/p&gt;
&lt;h4&gt;Content-Type&lt;/h4&gt;
&lt;p&gt;content-type字段标识着响应正文的media-type，已经采用的字符集编码。charset非常重要，因为接收端正是根据这一信息来对响应正文进行解码。设置一个和文档实际编码一致的charset就可以保证接受端能够正确的解码，也就是不会出现乱码。另外，需要注意的是，在html，css中这一参数声明会覆盖文档内的字符编码声明。&lt;/p&gt;
&lt;p&gt;好了，了解了这些基本知识，我们具体看看html中设置编码问题：&lt;/p&gt;
&lt;h3&gt;HTML&lt;/h3&gt;
&lt;p&gt;html中我们可以通过meta 标签设置文档字符编码如：&amp;lt;meta charset=”gbk”/&amp;gt;,浏览器确定文档编码的过程简化说是这样的&lt;sup&gt;&lt;a href=&quot;#zhu1&quot;&gt;[1]&lt;/a&gt;&lt;sup&gt;：&lt;/sup&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果用户在客户端明确指定了字符编码，客户端可以确定编码，停止检测（这一步可选）&lt;/li&gt;
&lt;li&gt;如果http header指定字符编码，客户端确定编码，停止检测(正如上面所说，content-type charset会覆盖文档内的字符声明)&lt;/li&gt;
&lt;li&gt;客户端查找文件编码信息meta charset/&lt;code title=&quot;&quot;&gt;http-equiv/content，如果找到&lt;code title=&quot;&quot;&gt;确定编码为相应值，&lt;/code&gt;停止解析&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;最终如果无法确定编码，使用用户的默认编码,用户默认字符编码和本地语言相关，如中文语言默认编码使用GB18030&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以指定content-type或者meta charset情况下，并且和文件本身编码一致，浏览器就可以解析出正确字符。如果没用明确指定字符编码，就会产生乱码的风险，虽然浏览器也做了一些检测工作。&lt;/p&gt;
&lt;p&gt;html文件中编码我们一般不会遇到乱码，再来看看比较常见的外链css/script中确定编码的过程：&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;css/script&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;外链css文件可以在文件开始设置@charset “charset”来指定字符编码，外链script可以设置script标签的charset属性指定字符编码，script具体确定过程是这样的&lt;sup&gt;&lt;a href=&quot;#zhu2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果content-type指定，使用相应编码，停止检测&lt;/li&gt;
&lt;li&gt;如果charset属性指定，使用相应编码，停止检测&lt;/li&gt;
&lt;li&gt;最终如果无法确定编码使用当前文档的编码作为文件编码&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;css应该和script确定过程大致相同，一般情况下我们保证外链样式编码和文档一致即可或者手动设置@charset，script在动态请求时遇到乱码的情况会比较常见，尤其在请求内容不可控的情况下，如果响应方没用指定content-type，需要手动设置动态创建script的charset属性&lt;/p&gt;
&lt;p&gt;再来看看最常见乱码的情况ajax中编码：&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;xmlHttpRequest&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;xhr请求数据并解析响应，在发送数据和接受数据时都可能会遇到乱码的问题，分开看一下：&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;send(data)&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;首先&lt;code title=&quot;&quot;&gt;xhr提供了setRequestHeader方法，我们可以设定请求头，因此可以设定content-type,发送数据字符编码过程&lt;sup&gt;&lt;a href=&quot;#zhu3&quot;&gt;[3]&lt;/a&gt;&lt;sup&gt;：&lt;/sup&gt;&lt;/sup&gt;&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果data是 document，mime将使用&lt;code&gt;application/xml;charset=文档的编码&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果data是 string，将会对字符转码成utf8，mime使用 “&lt;code&gt;text/plain;charset=UTF-8&lt;/code&gt;“&lt;/li&gt;
&lt;li&gt;如果通过&lt;code title=&quot;&quot;&gt;setRequestHeader设置了mime，那么charset参数会被设成utf-8，type保留&lt;/code&gt;，否则使用前面的mime type&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;可见发送数据，xhr保证了字符编码和实际编码一致（都为utf-8），这样接收端可以正确的解析字符，接收端出现乱码一般都没用按照正确的编码解析，或者又按另一种编码输出，而没有转换编码&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Response&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;首先说下xhr的overrideMineType方法，允许覆盖相应的mine type，（目前仅ff，chrome支持），接收数据的编码大致&lt;sup&gt;&lt;a href=&quot;#zhu3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;采用 overideMineType设置的编码 ，结束&lt;/li&gt;
&lt;li&gt;如果响应设置了&lt;code&gt;Content-Type 采用对应编码，结束&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果mine type是 text/html 采用 html的编码确定方式&lt;/li&gt;
&lt;li&gt;采用UTF-8&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由于overideMineType兼容性问题，让服务端输出正确的content-type是比较简单有效的方法，当然还有其他一下方法，这里不讨论了&lt;/p&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;保证设定的字符编码和文件真实编码一致，即可保证计算机解析出正确的字符；这也是产生乱码问题的根源；设定http content-type 即可指定数据的编码，客户端确定编码的优先级最高；如果没用设置content-type，对于html、css、script都有相应的指定编码的方式，对于xhr，发送的数据总是以utf-8编码，发送与实际字符编码一致（和文档编码无关），接收数据如果没用指定content-type，“最终”会以utf-8处理。总之，必须指定文件真实编码一致的字符编码，来保证计算机能够正确识别字符，避免乱码。&lt;/p&gt;
&lt;h3&gt;其他一些参考：&lt;/h3&gt;
&lt;p&gt;W3C处理html字符编码的文章： &lt;a href=&quot;http://www.w3.org/International/tutorials/tutorial-char-enc/&quot; target=&quot;_blank&quot;&gt;http://www.w3.org/International/tutorials/tutorial-char-enc/&lt;/a&gt;&lt;br /&gt;
overideMineType兼容方案：&lt;a href=&quot;http://www.cnblogs.com/cuixiping/archive/2008/03/22/1118226.html&quot; target=&quot;_blank&quot;&gt;http://www.cnblogs.com/cuixiping/archive/2008/03/22/1118226.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;zhu1&quot;&gt;注1&lt;/span&gt;：具体步骤参见：&lt;a href=&quot;http://dev.w3.org/html5/spec/parsing.html#determining-the-character-encoding&quot; target=&quot;_blank&quot;&gt;http://dev.w3.org/html5/spec/parsing.html#determining-the-character-encoding&lt;/a&gt;&lt;span id=&quot;zhu1&quot;&gt;&lt;br /&gt;
注2&lt;/span&gt;：具体步骤参见&lt;a href=&quot;http://dev.w3.org/html5/spec/scripting-1.html#the-script-block-s-source&quot; target=&quot;_blank&quot;&gt;http://dev.w3.org/html5/spec/scripting-1.html#the-script-block-s-source&lt;/a&gt;&lt;span id=&quot;zhu1&quot;&gt;&lt;br /&gt;
注3&lt;/span&gt;：具体步骤参见&lt;a href=&quot;http://www.cnblogs.com/cuixiping/archive/2008/03/22/1118226.html&quot; target=&quot;_blank&quot;&gt;http://www.w3.org/TR/XMLHttpRequest/&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/609431519/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/07/character-encoding-on-web/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.yigle.net/2011/07/character-encoding-on-web/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>web开发中经常遇到各种乱码问题，原因都是编码不一致造成的。字符编码究竟起什么作用，如何运作的呢？先来了解一些基本概念：
字符集、编码字符集、字符编码
字符集
字符集就是一些字符的集合，比如我们使用的中文就可以看成一种字符集&lt;img src=&quot;http://www1.feedsky.com/t1/609431519/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/07/character-encoding-on-web/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>HTTP</category><category>charset</category><category>overrideMimeType</category><category>Other</category><pubDate>Thu, 14 Jul 2011 02:00:47 +0800</pubDate><author>Tiejun</author><comments>http://www.yigle.net/2011/07/character-encoding-on-web/#comments</comments><guid isPermaLink="false">http://www.yigle.net/?p=37371</guid><dc:creator>Tiejun</dc:creator><fs:srclink>http://www.yigle.net/2011/07/character-encoding-on-web/</fs:srclink><fs:srcfeed>http://www.yigle.net/feed</fs:srcfeed><fs:itemid>feedsky/yigle/~7882683/609431519/5992322</fs:itemid></item><item><title>[JS基础]运算符优先级及运算顺序</title><link>http://www.yigle.net/2011/07/javascript-operator-precedence-and-order-of-execluate/</link><content:encoded>&lt;p&gt;不知什么时候形成一种认识：运算符的优先级越高就越先执行，前两天在群里写了段代码：&lt;/p&gt;
&lt;pre class=&quot;brush:applescript&quot;&gt;var a =1;
function fn(){alert(a);}
var b = a++ + fn();&lt;/pre&gt;
&lt;p&gt;alert出的值是是怎么呢？&lt;/p&gt;
&lt;p&gt;按照我之前的认识应该是 1,()优先级最高最先被执行此时a=1，可事实在各个浏览器都是 2&lt;/p&gt;
&lt;p&gt;不得不怀疑之前的认识&lt;/p&gt;
&lt;p&gt;又测试了下其他语言， php，java也都一样的结果：2，c和c++输出：1&lt;/p&gt;
&lt;p&gt;参考了下犀牛书还有语言的官方，基本都表述：运算符优先级决定被运算的顺序，像&lt;a href=&quot;https://developer.mozilla.org/en/JavaScript/Reference/Operators/Operator_Precedence&quot; target=&quot;_blank&quot;&gt;MDN&lt;/a&gt;：“Operator precedence determines the order in which operators are evaluated”，但&lt;a href=&quot;http://php.net/manual/en/language.operators.precedence.php&quot; target=&quot;_blank&quot;&gt; PHP&lt;/a&gt; ：“The precedence of an operator specifies how “tightly” it binds two expressions together”。&lt;/p&gt;
&lt;p&gt;按php的说法就很好理解上面的问题了，优先级表示着运算符结合能力的强弱&lt;/p&gt;
&lt;p&gt;但是真是那些说 “evaluate order”的错了？？？咨询了好几个同事，终于算是有个自己满意的解释&lt;/p&gt;
&lt;p&gt;表达式的运算顺序和运算符优先级根本是两个概念：运算符的优先级只表示着对于&lt;strong&gt;运算时&lt;/strong&gt;哪个运算符先被结合（也可以说执行），至于怎么个顺序运算和它无关，而表达式的&lt;strong&gt;运算顺序和各个语言的规范有关&lt;/strong&gt;，比如java中就明确定义&lt;a href=&quot;http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.7&quot; target=&quot;_blank&quot;&gt;evaluate order：Left To Right&lt;/a&gt;，看了下JS的ECAM规范，虽然没用像java那么明确说明运算顺序，但是跟据各个运算符的运算顺序可以看出也是 从左向右 运算的（包括函数调用，参数计算）。&lt;/p&gt;
&lt;h4&gt;上面 b = a++ + fn()运算过程：&lt;/h4&gt;
&lt;p&gt;1.运算b是个ref&lt;br /&gt;
2.运算=右边部分，a++，此时a=2&lt;br /&gt;
3.运算fn()&lt;/p&gt;
&lt;p&gt;具体过程可以这样理解：&lt;/p&gt;
&lt;p&gt;1.扫描到=操作符，先运算b&lt;br /&gt;
2.扫描到++(尽可能多的结合)，后面是+，++的优先级高于+，运算a++，此时a++会产生副作用（a+=1）,js会先算完子表达式再执行，a=2&lt;br /&gt;
3.接着扫描到()执行函数运算&lt;/p&gt;
&lt;h4&gt;C语言又怎吗输出1呢？&lt;/h4&gt;
&lt;p&gt;C语言可能为了编译器可以灵活的优化程序，并没用明确确定运算顺序以及副作用处理，所以不同编译器运算结果也可能不同，比如：&lt;/p&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;int i =1;
int m = (i++) +(i++)+(i++)&lt;/pre&gt;
&lt;p&gt;有的编译器是6，有的编译器(MSC,TurboC)编译出来是3；还有函数实参运算顺序的问题也一样。&lt;/p&gt;
&lt;h3&gt;总之：&lt;/h3&gt;
&lt;p&gt;表达式的运算顺序由语言规范定义和运算符的优先级“无关”，运算符的优先级及结合性只在运算时判断那个运算符先被运算（这样说，MDN的解释也没错只是自己理解错了），更好理解些优先级结合性表示运算符谁先被结合使用;Javascript中 跟据ECAM中对各个操作符的运算顺序的规范，Javascript的运算顺序应该是：&lt;strong&gt;从左到右，副作用运算先执行再继续表达式运算&lt;/strong&gt;(不知有没有特例，没看到明确说明,-_-)&lt;/p&gt;
&lt;h3&gt;相关的讨论：&lt;/h3&gt;
&lt;p&gt;JavaEye关于java和c运算顺序的问答：&lt;a href=&quot;http://www.iteye.com/problems/20258&quot; target=&quot;_blank&quot;&gt;http://www.iteye.com/problems/20258&lt;/a&gt;&lt;br /&gt;
StackOverflow Javascript运算顺序的讨论：&lt;a href=&quot;http://stackoverflow.com/questions/5944593/javascript-evaluation-order&quot; target=&quot;_blank&quot;&gt; http://stackoverflow.com/questions/5944593/javascript-evaluation-order&lt;/a&gt;&lt;br /&gt;
一篇讨论c#，java,c运算顺序的blog：&lt;a href=&quot;http://rednaxelafx.iteye.com/blog/132187&quot; target=&quot;_blank&quot;&gt;http://rednaxelafx.iteye.com/blog/132187&lt;/a&gt; &lt;span style=&quot;color: #999999;&quot;&gt;//added 2011-07-13&lt;/span&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/609431520/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/07/javascript-operator-precedence-and-order-of-execluate/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.yigle.net/2011/07/javascript-operator-precedence-and-order-of-execluate/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>不知什么时候形成一种认识：运算符的优先级越高就越先执行，前两天在群里写了段代码：
var a =1;
function fn(){alert(a);}
var b = a++ + fn();&lt;img src=&quot;http://www1.feedsky.com/t1/609431520/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/07/javascript-operator-precedence-and-order-of-execluate/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>operator-precedence</category><category>JS基础</category><category>evaluate-order</category><category>Javascript</category><pubDate>Wed, 13 Jul 2011 00:47:43 +0800</pubDate><author>Tiejun</author><comments>http://www.yigle.net/2011/07/javascript-operator-precedence-and-order-of-execluate/#comments</comments><guid isPermaLink="false">http://www.yigle.net/?p=37357</guid><dc:creator>Tiejun</dc:creator><fs:srclink>http://www.yigle.net/2011/07/javascript-operator-precedence-and-order-of-execluate/</fs:srclink><fs:srcfeed>http://www.yigle.net/feed</fs:srcfeed><fs:itemid>feedsky/yigle/~7882683/609431520/5992322</fs:itemid></item><item><title>[JS基础]prototype谁是谁祖宗</title><link>http://www.yigle.net/2011/07/prototype-who-is-ancestors/</link><content:encoded>&lt;p&gt;先看一段代码：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var a = function() {},
    b = new a();
Function.prototype.isPrototypeOf(a);
Object.prototype.isPrototypeOf(a);
Object.prototype.isPrototypeOf(b);
Function.prototype.isPrototypeOf(b);
Object.prototype.isPrototypeOf(Function);
Function.prototype.isPrototypeOf(Object);
Object.constructor === Function;
Function.constructor === Function;&lt;/pre&gt;
&lt;p&gt;上面3-10行各返回的是true还是false？&lt;span style=&quot;text-decoration: underline;&quot; title=&quot;只有第7行为false&quot;&gt;答案&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;如果你都想对了，就别浪费时间继续看了-_-&lt;/p&gt;
&lt;p&gt;理解上面的问题，就要搞清谁是原型链的顶级及继承关系,参考ECMA5规范：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“The value of the [[Prototype]] internal property of the Object prototype object is null, the value of the [[Class]]internal property is “Object”, and the initial value of the [[Extensible]] internal property is true.”&lt;/p&gt;
&lt;p&gt;“The Function prototype object is itself a Function object (its [[Class]] is  “Function”) that, when invoked,accepts any arguments and returns undefined.The value of the [[Prototype]] internal property of the Function prototype object is the standard built-in Object prototype object (15.2.4). The initial value of the [[Extensible]] internal property of the Function prototype object is true.”&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Object prototype object 标准内置对象（这里简称OPO） 是所有原型链的鼻祖，再向上就是null了&lt;br /&gt;
Function prototype object 标准内置对象（这里简成FPO） 是函数的原型对象，其__proto__为OPO&lt;/p&gt;
&lt;p&gt;Function prototype及__proto__都指向FPO&lt;br /&gt;
所有其他内置构造函数其__proto__为FPO，prototype指向OPO，如：Object 构造函数 __proto__指向内置FPO，prototype指向OPO&lt;/p&gt;
&lt;p&gt;函数实例也是一个实例对象（通过 new Function而来），和Object一样，内部prototype指向构造函数的protype属性，即FPO，prototype属性是创建时被添加（为OPO）用来作为构造函数而创建的 。&lt;/p&gt;
&lt;p&gt;说的比较乱，画张图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://farm6.static.flickr.com/5115/5911420237_0c05b79ac4.jpg&quot; alt=&quot;2011-07-06_193220&quot; width=&quot;500&quot; height=&quot;289&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Function 用于实例函数对象，其prototype 为FPO，这样保证所有其他函数的继承FPO的属性方法&lt;br /&gt;
其他函数 用于实例普通对象，其prototype为OPO，保证每个对象实现都继承OPO的属性方法。&lt;/p&gt;
&lt;p&gt;再来看看代码中用到的isPrototypeOf方法：&lt;/p&gt;
&lt;h3&gt;isPrototypeOf方法&lt;/h3&gt;
&lt;p&gt;O.isPrototypeOf(V)方法用于检查V的构造函数的原型是不是O，根据ECMA5规范&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre style=&quot;font-family: tahoma;&quot;&gt;Object.prototype.isPrototypeOf (V)
When the isPrototypeOf method is called with argument V, the following steps are taken:
1.  If V is not an object, return false.
2.  Let O be the result of calling ToObject passing the this value as the argument.
3.  Repeat
    a.  Let V be the value of the [[Prototype]] internal property of V.
    b.  if V is null, return false
    c.  If O and V refer to the same object, return true.&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;在检查时会有个向上遍历的过程，即：检测V的构造函数的原型是不是O，如果不是，接着检查V的构造函数的原型 的 构造函数原型 是不是O，直至原型为null，返回false。&lt;/p&gt;
&lt;p&gt;理解了上面，再来看看开始的那段代码：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var a = function() {},
    b = new a();
Function.prototype.isPrototypeOf(a); // a的__proto__为 FPO，返回true
Object.prototype.isPrototypeOf(a); // a的__proto__为 FPO，向上查找，FPO的 __proto__ === Object.prototype,返回true
Object.prototype.isPrototypeOf(b); // b的__proto__为OPO，返回true
Function.prototype.isPrototypeOf(b); // b的__proto__为OPO，向上查找，OPO的__proto__为null，返回false
Function.prototype.isPrototypeOf(Object); // F的__proto__为FPO,返回true
Object.prototype.isPrototypeOf(Function); // F的__proto__为FPO，向上查找，FPO的 __proto__ === Object.prototype,返回true
Object.constructor === Function; // true
Function.constructor === Function; // true&lt;/pre&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/609431521/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/07/prototype-who-is-ancestors/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.yigle.net/2011/07/prototype-who-is-ancestors/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>先看一段代码：
var a = function() {},
    b = new a();
Function.prototype.isPrototypeOf(a);&lt;img src=&quot;http://www1.feedsky.com/t1/609431521/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/07/prototype-who-is-ancestors/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>JS基础</category><category>Javascript</category><category>prototype</category><pubDate>Fri, 08 Jul 2011 21:24:57 +0800</pubDate><author>Tiejun</author><comments>http://www.yigle.net/2011/07/prototype-who-is-ancestors/#comments</comments><guid isPermaLink="false">http://www.yigle.net/?p=37310</guid><dc:creator>Tiejun</dc:creator><fs:srclink>http://www.yigle.net/2011/07/prototype-who-is-ancestors/</fs:srclink><fs:srcfeed>http://www.yigle.net/feed</fs:srcfeed><fs:itemid>feedsky/yigle/~7882683/609431521/5992322</fs:itemid></item><item><title>脚本的加载执行及优化</title><link>http://www.yigle.net/2011/05/script-load-execution-and-optimization/</link><content:encoded>&lt;h2&gt;Javascript及UI Render的单线程&lt;/h2&gt;
&lt;p&gt;讨论之前，首先需要理解的是js的单线程机制，即在同一时刻js只能执行一个任务，另外实际上浏览器的渲染也和js共用同一线程，这就意味着js在处理代码时浏览器会停止解析，如图所示：&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;alignnone&quot; src=&quot;http://farm6.static.flickr.com/5304/5745379353_9fd9988fa3_z.jpg&quot; alt=&quot;js single thread&quot; width=&quot;580&quot; height=&quot;206&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当遇到js代码时js引擎会解析执行代码，此时浏览器渲染停止，直到脚本解析完毕才继续。当脚本执行耗时过长，尤其当引入外部脚本时加上脚本的加载时间，对ui渲染的阻塞更为严重，这是性能优化的一个方面，也是这篇文章为什么讨论脚本加载执行顺序的主要原因。&lt;/p&gt;
&lt;h2&gt;两种嵌入方式&lt;/h2&gt;
&lt;h3&gt;解析嵌入（Parser-inserted）&lt;/h3&gt;
&lt;p&gt;指在html源代码中通过&amp;lt;script src=”XXX”&amp;gt;等方式引入（术语上这类脚本成为 Parser-inserted script），这种方式下浏览器会以&amp;lt;script&amp;gt;标签在页面中出现的顺序加载和执行，即同步加载执行。正如前面讨论的，这种方式会阻塞页面其他元素的加载，及页面渲染。&lt;/p&gt;
&lt;h3&gt;脚本嵌入（script-inserted）&lt;/h3&gt;
&lt;p&gt;通过脚本动态载入方式（术语上这类脚本成为Parser-inserted script），动态载入脚本的方式有很多中如：document.write,xhr eval,script document Element等&lt;sup&gt;&lt;a href=&quot;#zs2&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;，其中通过动态创建script标签是被广泛应用推荐的一种，这里只讨论这种情况。&lt;/p&gt;
&lt;p&gt;通过动态创建script元素可以实现无阻塞加载，但这意味着什么？一个脚本阻塞是从开始加载到执行完毕才结束，大体有三个步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;加载脚本&lt;/li&gt;
&lt;li&gt;解析&lt;/li&gt;
&lt;li&gt;执行&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在这个过程中通常#1耗时最长，通过这种方式意味着不必等待脚本的#1(也许还有#2)过程，浏览器ui线程可以不受干扰继续执行，但是由于js单线程机制对于#3过程无可避免的会对ui线程阻塞。当然，浏览器解析通常很快的（尤其是新的js引擎），通常这部分影响几乎察觉的到，但是如果脚本性能不好，执行需要较长时间这也会产成性能瓶颈。&lt;/p&gt;
&lt;p&gt;总之，无阻塞加载使浏览器不必等待脚本加载而继续渲染，两者异步执行，但脚本执行仍会阻塞渲染。&lt;/p&gt;
&lt;h2&gt;并行加载&lt;/h2&gt;
&lt;p&gt;根据上面的无阻塞方式加载多个脚本文件，这些文件是并行加载的，这样相对传统方式带来的好处是，使浏览器更快更早的请求文件并且不会阻塞浏览器渲染，但是这里仅仅是并行“加载”，并不意味着会并行执行，还是那个原因js是单线程的，同一时间只有一个js会被执行！另外带来的一个问题是，脚本并行加载其执行顺序又是怎样的呢？&lt;/p&gt;
&lt;p&gt;对于脚本的执行顺序，目前各个浏览器执行情况还有些差异：&lt;/p&gt;
&lt;p&gt;1.opera and firefox3.6-&lt;/p&gt;
&lt;p&gt;执行的顺序会按照脚本被动态插入的顺序执行&lt;/p&gt;
&lt;p&gt;2.ie，Safari，chorme and firefox4&lt;sup&gt;&lt;a href=&quot;#zs2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;脚本加载完毕即会执行，不会保持他们被插入的顺序&lt;/p&gt;
&lt;h2&gt;浏览器的努力：defer &amp;amp; async&lt;/h2&gt;
&lt;p&gt;对于无阻塞脚本加载，浏览器也给出了一定的方案，包括早期ie实现（后来被firefox3.1引入）的defer属性以及HTML5定义的async属性&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;defer&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;脚本下载不会阻塞浏览器渲染，直到文档解析完成时才会执行，&lt;code title=&quot;event-DOMContentLoaded&quot;&gt;DOMContentLoaded触发之前&lt;/code&gt;（兼容性不好）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;async&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个属性由html5新引入的标准属性，这是个布尔属性，当被定义时，脚本会无阻塞加载，脚本文件加载完成立即执行（不顾及脚本出现的先后顺序），如果需要脚本保持引入的先后顺序需要显示的设置.async = false(对于script-created 脚本默认为true，目前仅firefox4支持false)。&lt;/p&gt;
&lt;h2&gt;开发者的努力：LABjs&lt;/h2&gt;
&lt;p&gt;labjs项目主要特性能够实现脚本并行加载和顺序执行，已经被多个大型网站采用，看个例子：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;   $LAB
   .script(&quot;a1.js&quot;).wait()
   .script(&quot;a2.js&quot;)
   .script(&quot;a3.js&quot;).wait()
   .script(&quot;a4.js&quot;);&lt;/pre&gt;
&lt;p&gt;这样,a1a2a3a4脚本会被并行加载，但是执行顺序还是会按照a1-&amp;gt;a2a3||a3a2-&amp;gt;a4的顺序执行。由于前面提到的对于动态创建script元素，不同浏览器两种不同的执行顺序，其实现进行了browser sniff：opera and old firefox直接动态插入即可保证执行顺序；对于IE chrome sarfari方面通过一个trick： 预加载script文件（通过设置script type为不能识别的值，保证浏览器只加载不执行），然后按照需要的顺序插入正确的script元素，这些元素就会立刻执行并且保持顺序：&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;alignnone&quot; src=&quot;http://farm6.static.flickr.com/5229/5745379409_01ccaa0fa0_z.jpg&quot; alt=&quot;LABjs 并行下载的实现&quot; width=&quot;580&quot; height=&quot;99&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当然，还有许多其他项目的实现如 requireJS 的&lt;a href=&quot;http://requirejs.org/docs/api.html#order&quot;&gt;order pluigin&lt;/a&gt;，&lt;a rel=&quot;nofollow&quot; href=&quot;http://headjs.com/&quot; target=&quot;_blank&quot;&gt;HeadJS&lt;/a&gt; ，&lt;a rel=&quot;nofollow&quot; href=&quot;http://stevesouders.com/controljs/&quot; target=&quot;_blank&quot;&gt;ControlJS&lt;/a&gt;&amp;#8230;&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;由于javascript及ui render的单线程机制，采用无阻塞加载脚本来提高页面性能，同时看到浏览器及开发者对于这方面的努力及实现，但请注意无阻塞加载仅仅是“加载”而已，执行过程仍然会阻塞渲染，进一步的优化需要我们回归到代码本身，减少其执行时间，以获得更快的响应。&lt;/p&gt;
&lt;p&gt;注：&lt;/p&gt;
&lt;ol&gt;
&lt;li id=&quot;zs1&quot;&gt;Steve提出了各种实现方式&lt;a href=&quot;http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/&quot; target=&quot;_blank&quot;&gt; loading scripts without blocking&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;zs2&quot;&gt;firefox4 pre7之前仍是按照原来的方式顺序执行，为了符合html5的规范改为无序执行，这里还有&lt;a href=&quot;http://blog.getify.com/2010/10/ff4-script-loaders-and-order-preservation/&quot; target=&quot;_blank&quot;&gt;labjs的作者和火狐开发者的一个故事&lt;/a&gt;，最终firefox4通过设置async=false来保持这种执行顺序。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;参考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.whatwg.org/specs/web-apps/current-work/#the-script-element&quot; target=&quot;_blank&quot;&gt;http://www.whatwg.org/specs/web-apps/current-work/#the-script-element&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nczonline.net/blog/2010/08/10/what-is-a-non-blocking-script/&quot; target=&quot;_blank&quot;&gt; http://www.nczonline.net/blog/2010/08/10/what-is-a-non-blocking-script/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/En/HTML/Element/Script&quot; target=&quot;_blank&quot;&gt; https://developer.mozilla.org/En/HTML/Element/Script&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.getify.com/2010/10/ff4-script-loaders-and-order-preservation/&quot; target=&quot;_blank&quot;&gt; &lt;/a&gt;Update：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;添加defer脚本执行的确切时间 2011-05-24&lt;/li&gt;
&lt;/ol&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/609431522/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/05/script-load-execution-and-optimization/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.yigle.net/2011/05/script-load-execution-and-optimization/feed/</wfw:commentRss><slash:comments>3</slash:comments><description>Javascript及UI Render的单线程
讨论之前，首先需要理解的是js的单线程机制，即在同一时刻js只能执行一个任务，另外实际上浏览器的渲染也和js共用同一线程，这就意味着js在处理代码时浏览器会停止解析，如图所示：

当遇到js代码时js引擎会解析执行代码，此时浏览器渲染停止，直到脚本解析完毕才继续。当脚本执行耗时过长，尤其当引入外部脚本时加上脚本的加载时间，对ui渲染的阻塞更为严重，这是性能优化的一个方面，也是这篇文章为什么讨论脚本加载执行顺序的主要原因。&lt;img src=&quot;http://www1.feedsky.com/t1/609431522/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/05/script-load-execution-and-optimization/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>Javascript</category><pubDate>Sun, 22 May 2011 18:05:04 +0800</pubDate><author>Tiejun</author><comments>http://www.yigle.net/2011/05/script-load-execution-and-optimization/#comments</comments><guid isPermaLink="false">http://www.yigle.net/?p=37275</guid><dc:creator>Tiejun</dc:creator><fs:srclink>http://www.yigle.net/2011/05/script-load-execution-and-optimization/</fs:srclink><fs:srcfeed>http://www.yigle.net/feed</fs:srcfeed><fs:itemid>feedsky/yigle/~7882683/609431522/5992322</fs:itemid></item><item><title>cnBeta月光宝盒</title><link>http://www.yigle.net/2011/04/cnbeta-yueguangbaohe/</link><content:encoded>&lt;p&gt;&lt;img class=&quot;alignnone&quot; title=&quot;cnBeta月光宝盒&quot; src=&quot;https://static.addons.mozilla.net/en-US/firefox/images/addon_icon/306072-64.png?modified=1302444139&quot; alt=&quot;cnBeta月光宝盒&quot; width=&quot;64&quot; height=&quot;64&quot; /&gt;&lt;/p&gt;
&lt;p&gt;小谢的&lt;a href=&quot;http://x1989.com/a/375.html&quot; target=&quot;_blank&quot;&gt;一个想法&lt;/a&gt;，觉得挺实用，就写了下火狐版的扩展&lt;/p&gt;
&lt;p&gt;“&lt;br /&gt;
不知从何时开始，cnBeta上的评论有了48小时的保鲜期，过了48小时，任何曾停留在页面上的喧嚣，都会消隐不见。cnBeta月光宝盒——轻轻一点，昨日重现（甚至都不用点）。&lt;br /&gt;
”&lt;/p&gt;
&lt;p&gt;firefox扩展地址：&lt;a href=&quot;https://addons.mozilla.org/zh-CN/firefox/addon/cnbeta_yueguangbaohe/&quot; target=&quot;_blank&quot;&gt;https://addons.mozilla.org/zh-CN/firefox/addon/cnbeta_yueguangbaohe/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Chrome扩展地址：&lt;a href=&quot;https://chrome.google.com/extensions/detail/nkgjnkanhkhlallldojlbekikmeefcje&quot; target=&quot;_blank&quot;&gt;https://chrome.google.com/extensions/detail/nkgjnkanhkhlallldojlbekikmeefcje&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;if u like,try!&lt;/strong&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/609431523/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/04/cnbeta-yueguangbaohe/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.yigle.net/2011/04/cnbeta-yueguangbaohe/feed/</wfw:commentRss><slash:comments>3</slash:comments><description>小谢的一个想法，觉得挺实用，就写了下火狐版的扩展
“
不知从何时开始，cnBeta上的评论有了48小时的保鲜期，过了48小时，任何曾停留在页面上的喧嚣，都会消隐不见。cnBeta月光宝盒——轻轻一点，昨日重现（甚至都不用点）。
”&lt;img src=&quot;http://www1.feedsky.com/t1/609431523/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/04/cnbeta-yueguangbaohe/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><pubDate>Sun, 10 Apr 2011 22:21:30 +0800</pubDate><author>Tiejun</author><comments>http://www.yigle.net/2011/04/cnbeta-yueguangbaohe/#comments</comments><guid isPermaLink="false">http://www.yigle.net/?p=37266</guid><dc:creator>Tiejun</dc:creator><fs:srclink>http://www.yigle.net/2011/04/cnbeta-yueguangbaohe/</fs:srclink><fs:srcfeed>http://www.yigle.net/feed</fs:srcfeed><fs:itemid>feedsky/yigle/~7882683/609431523/5992322</fs:itemid></item><item><title>Netbeans解决中文乱码</title><link>http://www.yigle.net/2011/04/chinese-garbled-netbeans-solution/</link><content:encoded>&lt;p&gt;最近&lt;a href=&quot;http://www.jetbrains.com/idea/&quot; target=&quot;_blank&quot;&gt;idea&lt;/a&gt;把我小本蹂躏的不行，几千行的js改动一下就要等好几秒，只好考虑其他ide，先试用一段&lt;a href=&quot;http://netbeans.org/&quot; target=&quot;_blank&quot;&gt;NetBeans&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;原来就有接触，因为字体问题，遂放弃，这次研究了下，终于解决，netbeans 乱码一般有两种情况：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;菜单界面乱码&lt;/li&gt;
&lt;li&gt;文件内容乱码&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下面是解决方法：&lt;/p&gt;
&lt;h3&gt;一、菜单界面乱码：&lt;/h3&gt;
&lt;p&gt;很容易解决，找到{Netbeans安装目录}/etc/netbeans.conf文件，在netbeans_default_options 后添加启动参数-J-Dfile.encoding=UTF-8(别忘了加空格)&lt;/p&gt;
&lt;h3&gt;二、文件内容乱码：&lt;/h3&gt;
&lt;p&gt;首先确定项目编码是否与文件编码一致，可在 &lt;span style=&quot;text-decoration: underline;&quot;&gt;项目属性对话框&lt;/span&gt;中的 编码里设置。&lt;/p&gt;
&lt;p&gt;如果编码一致，一般就是字体原因引起，查看下 &lt;span style=&quot;text-decoration: underline;&quot;&gt;工具-选项-字体和颜色&lt;/span&gt;中所选字体，如果为英文字体，中文内容就会出现方块类似的乱码&lt;/p&gt;
&lt;p&gt;可以尝试选择包含英文的中文字体（如微软雅黑）即可解决，如果又想使用英文字体显示英文，中文字体也能正常显示，需要&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1.改变下jre的字体查找顺序&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;{jre 安装目录}/lib/fontconfig.properties (没有的话将fontconfig.properties.src 文件复制重名成fontconfig.properties)，打开后更改里面这一行：&lt;/p&gt;
&lt;pre class=&quot;brush:shell&quot;&gt;sequence.monospaced.GBK=chinese-ms936,alphabetic,dingbats,symbol,chinese-ms936-extb&lt;/pre&gt;
&lt;p&gt;调整下字体查找顺序，先查找英文再查找中文，即：&lt;/p&gt;
&lt;pre class=&quot;brush:shell&quot;&gt;sequence.monospaced.GBK=alphabetic,chinese-ms936,dingbats,symbol,chinese-ms936-extb&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2. netbeans中工具-选项-字体和颜色 选择为继承的，即：Monospaced&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;重启下netbeans 应该就ok了。&lt;/p&gt;
&lt;p&gt;当然也可以不更改jre配置，选择一种包含你想要的英文字体和中文字体的混合字体也行，比如：&lt;a href=&quot;http://www.cnblogs.com/RobertLee/archive/2006/12/25/602646.html&quot;&gt;雅黑-Consolas&lt;/a&gt;，可惜我习惯了 courier new ~，尝试用 fontcreator 合并 雅黑和courier new 效果也不好，好像是因为字体 类型不同所致，不管了反正感觉不靠谱，有兴趣的可以自己合并试试。&lt;/p&gt;
&lt;p&gt;上下配色截图,hh&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;alignnone&quot; title=&quot;netbeans 主题&quot; src=&quot;http://farm6.static.flickr.com/5188/5602019393_418362d2de_z.jpg&quot; alt=&quot;netbeans 主题&quot; width=&quot;580&quot; height=&quot;246&quot; /&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/609431524/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/04/chinese-garbled-netbeans-solution/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.yigle.net/2011/04/chinese-garbled-netbeans-solution/feed/</wfw:commentRss><slash:comments>2</slash:comments><description>最近idea把我小本蹂躏的不行，几千行的js改动一下就要等好几秒，只好考虑其他ide，先试用一段NetBeans。
原来就有接触，因为字体问题，遂放弃，这次研究了下，终于解决，netbeans 乱码一般有两种情况：

菜单界面乱码&lt;img src=&quot;http://www1.feedsky.com/t1/609431524/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/04/chinese-garbled-netbeans-solution/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><pubDate>Sat, 09 Apr 2011 14:38:11 +0800</pubDate><author>Tiejun</author><comments>http://www.yigle.net/2011/04/chinese-garbled-netbeans-solution/#comments</comments><guid isPermaLink="false">http://www.yigle.net/?p=37252</guid><dc:creator>Tiejun</dc:creator><fs:srclink>http://www.yigle.net/2011/04/chinese-garbled-netbeans-solution/</fs:srclink><fs:srcfeed>http://www.yigle.net/feed</fs:srcfeed><fs:itemid>feedsky/yigle/~7882683/609431524/5992322</fs:itemid></item><item><title>IE的两个问题</title><link>http://www.yigle.net/2011/03/ie-two-problem/</link><content:encoded>&lt;p&gt;上次提到&lt;a href=&quot;http://www.yigle.net/posts/2011/03/window-defined-by-the-variable-ie-bug/&quot;&gt;IE下通过window属性定义变量的bug&lt;/a&gt;，最近又遇到两个问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#ieDom&quot;&gt;IE dom方法赋值变量调用错误&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ieBorder&quot;&gt;IE 的&amp;lt;html&amp;gt;元素border问题&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;ieDom&quot;&gt;IE dom方法赋值变量调用错误&lt;/h3&gt;
&lt;p&gt;如下代码：&lt;/p&gt;
&lt;pre class=&quot;brush:javascript&quot;&gt;    var s = document.getElementById;
    alert(typeof s);
    var el = s.call(document, 'test');
    el.innerHTML = &quot;ok&quot;;&lt;/pre&gt;
&lt;p&gt;应该alert出什么？el里的文字是？&lt;/p&gt;
&lt;p&gt;按道理应该alert出 function，文字是ok，但在ie下却alert 出 object，IE7/8下文字是ok，ie6下却报错&lt;/p&gt;
&lt;p&gt;&lt;cite&gt;“object doesn&amp;#8217;s support this property or method”&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/demo/show/ie-dom-fn-refer.html&quot; target=&quot;_blank&quot;&gt;test demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;因此应避免将dom方法直接付给变量，再来看看另一问题&lt;/p&gt;
&lt;h3 id=&quot;ieBorder&quot;&gt;IE 的&amp;lt;html&amp;gt;元素border问题&lt;/h3&gt;
&lt;p&gt;在计算元素offset时经常用到docuementElement.offsetHeight,documentElement.scrollTop&lt;/p&gt;
&lt;p&gt;比如要实现一个元素固定居于浏览器右下角，ie6下通过脚本实现：&lt;/p&gt;
&lt;pre class=&quot;brush:applescript&quot;&gt;    var el = document.getElementById('test'),
        htmlEl = document.documentElement;
    function rb() {
        el.style.top = htmlEl.scrollTop + (window.innerHeight||htmlEl.offsetHeight) - 50+'px';
    }
    window.onscroll=rb;
    window.onresize=rb;&lt;/pre&gt;
&lt;p&gt;offsetHeight是指整个元素的高度(border box)，在ie下html元素错误的box模型，offsetHeight返回的也是窗的高度&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/demo/show/ie-html-element-2px-border.html&quot; target=&quot;_blank&quot;&gt;test demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;看下测试demo发现ie无限向下滚动，原因在ie下html元素有2px的border，而元素定位是相对body的这样每次计算都多出2px&lt;/p&gt;
&lt;p&gt;将offsetHeight改为clientHeight ok！clientheight是元素内容区域的高度（padding box）&lt;/p&gt;
&lt;p&gt;以后处理基于&amp;lt;html&amp;gt;元素定位问题时需要留意这2px的box&lt;/p&gt;
&lt;p&gt;最后看看jquery offset方法的实现也是对这个问题进行了处理，&lt;a href=&quot;https://github.com/jquery/jquery/blob/master/src/offset.js&quot; target=&quot;_blank&quot;&gt;offset.js&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;alignnone&quot; title=&quot;jquery offset.js&quot; src=&quot;http://farm4.static.flickr.com/3050/5747291812_d766532c85_z.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/609431525/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/03/ie-two-problem/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.yigle.net/2011/03/ie-two-problem/feed/</wfw:commentRss><slash:comments>1</slash:comments><description>上次提到IE下通过window属性定义变量的bug，最近又遇到两个问题：

IE dom方法赋值变量调用错误
IE 的&amp;#60;html&amp;#62;元素border问题&lt;img src=&quot;http://www1.feedsky.com/t1/609431525/yigle/feedsky/s.gif?r=http://www.yigle.net/2011/03/ie-two-problem/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>Javascript</category><pubDate>Wed, 23 Mar 2011 00:17:59 +0800</pubDate><author>Tiejun</author><comments>http://www.yigle.net/2011/03/ie-two-problem/#comments</comments><guid isPermaLink="false">http://www.yigle.net/?p=37245</guid><dc:creator>Tiejun</dc:creator><fs:srclink>http://www.yigle.net/2011/03/ie-two-problem/</fs:srclink><fs:srcfeed>http://www.yigle.net/feed</fs:srcfeed><fs:itemid>feedsky/yigle/~7882683/609431525/5992322</fs:itemid></item></channel></rss>
