修正IE6 IE7的window.resize bug

应该是一个非常著名的bug了,在IE6 IE7中对window进行resize,此事件会执行多次,或者有时夸张地不断重复此回调函数,陷入死循环,造成假死现象。具体可参看这一篇文章《window.onresize hangs IE6 and IE7》。在这篇文章给出的方法是给出一个记数器,用来判断其是否撞上这倒霉事,当i被重复了100次马上移除resize事件进行自救。

在jQuery中的许多插件中,我看到另一种方法,利用setTimeout进行延时操作,目的是让浏览器有个喘息的机会。但治根不治本。

在外国论坛中,我无意看到第三种方法。那高手建用创建一个与视口等大的DIV,把onsize事件转移到这个DIV。不过我想他应该漏了一些东西没有说,我在这里补充一下。原例子的body基本为空,实质上我们操作的页面不可能是这个样子。我们应该让这个页面透明并绝对化。


        var mask = document.createElement("div");
        mask.style.cssText = "width:100%;height:100%;position:absolute;top:0px;left:0px;filter:alpha(opacity=50)";
        document.body.appendChild(mask);
        mask.onresize = resizeHandle;

这是一个比较完美的解决办法,但如何知道执行完resize事件呢?总是有一个层罩在上面,其他mousemove,click都用不了。MSDN提供了一个onresizeend事件,但是用不了。可能给VBScript使用的。用定时器判定吗?或者在回调函数的底部添加一个钩子吗?觉得都不好。我想,与其用一个麻烦的即用即弃的元素,不如看看页面上的元素能帮得上忙否。页面上,只要是HTML,总有几个元素都是少不了的。一个HTML元素,一个BODY元素。试了一下HTML,发现不起作用,真见鬼。不过心想,微软总是搞混HTML与BODY,这事没什么大不了,就绑定到body上吧。


      window.onload = function(){
        if(!+"\v1" && !document.querySelector) { // for IE6 IE7
          document.body.onresize = resize;
        } else { 
          window.onresize = resize;
        }
        var text =  document.getElementById("text")
        function resize() {
          text.innerHTML = getWindowSize().join(" : ");
        }
      }
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta content="IE=6" http-equiv="X-UA-Compatible"/> <title>fix ie6 resize bug by 司徒正美</title> <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> <title>Resize</title> <script type="text/javascript"> if(!Array.prototype.map) Array.prototype.map = function(fn,scope) { var result = [],ri = 0; for (var i = 0,n = this.length; i < n; i++){ if(i in this){ result[ri++] = fn.call(scope ,this[i],i,this); } } return result; }; var getWindowSize = function(){ return ["Height","Width"].map(function(name){ return window["inner"+name] || document.compatMode === "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] }); } window.onload = function(){ if(!+"\v1" && !document.querySelector) { // for IE6 IE7 document.body.onresize = resize; } else { window.onresize = resize; } var text = document.getElementById("text") function resize() { text.innerHTML = getWindowSize().join(" : "); } } </script> </head> <body> <h1>修正IE6 IE7中window.onresize 被多次执行的bug</h1> <div id="text">这里是用来显示窗口大小</div> </body> </html>

运行代码


        if(dom.ie){
            dom.events.special.resize = {
                setup: function() {
                    var el = this,
                    caller = dom.isWindow(el) ? dom.body(el) : el,
                    args = slice.call( arguments, 1 ),
                    event = dom.events.fix(window.event);
                    event.type = "resize";
                    args.unshift(event);
                    caller.οnresize=function(){
                        dom.events.handle.apply( el, args );
                    }
                },
                teardown: function() {
                    var caller = dom.isWindow(this) ? dom.body(this) : this;
                    caller.onresize = null;
                }
            }
        }

第二版


            dom.events.special.resize = (function(){
                var size = function() {
                    var el = dom(window);
                    return {
                        w:el.width(),
                        h:el.height()
                    };
                },
                lock_ = 0, size_, use_,
                setup = function() {
                    if (!this.setTimeout)
                        return false;
                    size_ = size();
                    use_ = true;
                    (function loop() {
                        if (!lock_++) {
                            var now = size();
                            if (size_.w !== now.w || size_.h !== now.h) {
                                size_ = now;
                                var evt = dom.Event("resize");
                                evt.target = evt.originalTarget = evt.currentTarget = window;
                                dom.events.handle.call(this, evt);
                            }
                            setTimeout(function() {
                                lock_ = 0;
                            }, 0);
                        }
                        if (use_) {
                            setTimeout(loop, 100);
                        }
                    })();
                },
                teardown=function () {
                    if (!this.setTimeout)
                        return false;
                    use_ = false;
                }
                return {
                    setup:setup,
                    teardown:teardown
                }
            })();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值