下面一段代码是cloudgamer的JavaScript简易拖放效果<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>简易拖放效果</title>
</head><body>
<script>var isIE = (document.all) ? true : false;var $ = function (id) {
return "string" == typeof id ? document.getElementById(id) : id;
};var Class = {
create: function() {
return function() { this.initialize.apply(this, arguments); }
}
}var Extend = function(destination, source) {
for (var property in source) {
destination[property] = source[property];
}
}var Bind = function(object, fun) {
return function() {
return fun.apply(object, arguments);
}
}var BindAsEventListener = function(object, fun) {
return function(event) {
return fun.call(object, (event || window.event));
}
}function addEventHandler(oTarget, sEventType, fnHandler) {
if (oTarget.addEventListener) {
oTarget.addEventListener(sEventType, fnHandler, false);
} else if (oTarget.attachEvent) {
oTarget.attachEvent("on" + sEventType, fnHandler);
} else {
oTarget["on" + sEventType] = fnHandler;
}
};function removeEventHandler(oTarget, sEventType, fnHandler) {
    if (oTarget.removeEventListener) {
        oTarget.removeEventListener(sEventType, fnHandler, false);
    } else if (oTarget.detachEvent) {
        oTarget.detachEvent("on" + sEventType, fnHandler);
    } else { 
        oTarget["on" + sEventType] = null;
    }
};//拖放程序
var SimpleDrag = Class.create();
SimpleDrag.prototype = {
  //拖放对象,触发对象
  initialize: function(drag) {
this.Drag = $(drag);
this._x = this._y = 0;
this._fM = BindAsEventListener(this, this.Move);
this._fS = Bind(this, this.Stop);
this.Drag.style.position = "absolute";
addEventHandler(this.Drag, "mousedown", BindAsEventListener(this, this.Start));
  },
  //准备拖动
  Start: function(oEvent) {
this._x = oEvent.clientX - this.Drag.offsetLeft;
this._y = oEvent.clientY - this.Drag.offsetTop;
addEventHandler(document, "mousemove", this._fM);
addEventHandler(document, "mouseup", this._fS);
  },
  //拖动
  Move: function(oEvent) {
this.Drag.style.left = oEvent.clientX - this._x + "px";
this.Drag.style.top = oEvent.clientY - this._y + "px";
  },
  //停止拖动
  Stop: function() {
removeEventHandler(document, "mousemove", this._fM);
removeEventHandler(document, "mouseup", this._fS);
  }
};</script><div id="idDrag" style="border:5px solid #0000FF; background:#C4E3FD; width:50px; height:50px;"></div><script>
new SimpleDrag("idDrag");
</script></body>
</html>
然后我将initialize改成:initialize: function(drag) {
this.Drag = $(drag);
this._x = this._y = 0;
this._fM = Bind(this, this.Move);
this._fS = Bind(this, this.Stop);
this.Drag.style.position = "absolute";
addEventHandler(this.Drag, "mousedown", Bind(this, this.Start));
  },不用BindAsEventListener了,用Bind。本以为这样改动后,在IE下是无法拖动的,结果是正常运行。就这个问题求解!
我的理解是:
使用Bind(this, this.Start),事件触发的时候就直接执行Start(oEvent)。如果是FF,由于是DOM事件模型,那么事件发生时,系统会自动给该函数的第一个参数传入一个Event对象,也就是说oEvent就是event对象。但是如果是IE的话,事件发生不会给函数传递event对象,要使用window.event获取。这也正是BindAsEventListener做的,传入了正确的event。
可是事实是,FF和IE都能运行。
另个问题:
这里用BindAsEventListener和Bind来绑定this,本质是通过call和apply去修改this。这里不绑定,那么Move和Start里面的this指向就肯定出错。那么都有哪些地方需要绑定this?有没有精确点的总结和分析?

解决方案 »

  1.   

    document.getElementById('sss').attachEvent('onclick',function(e){
    alert(e.type);
    })
    测试的是,这个在IE5.5下都可以弹出event.type。
    也就是说attachEvent可以传入Event对象。
    但是this指向的是window。

    htmlElement.onclick = function(e){}IE就不能传入Event对象了,而this指向的是htmlElement。
      

  2.   

    就像你说的,事实就是:attachEvent可以传入Event对象。我贴的例子也说明了这个,但是我记得attachEvent的事件函数不该可以传Event对象的啊?
    下面是我做的小测试。<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
    <title>Untitled 1</title>
    <script type="text/javascript">
    window.onload=function()
    {
    var redObj=document.getElementById("red");
    redObj.attachEvent("onclick",clickHandle);
    redObj.attachEvent("onmouseout",mouseoutHandle("mouseout"));
    }
    function clickHandle()
    {
    try{
    alert(arguments[0].type);
    }catch(e){
    alert(e.name+":"+e.message);
    }
    }
    function mouseoutHandle(type)
    {
    return function(){
    alert(type);
    alert(arguments.length);
    };
    }
    </script>
    </head>
    <body>
      <div id="red" style="width:50px;height:50px;background-color:red"></div>
      <div id="black" style="width:50px;height:50px;background-color:black" onclick="clickHandle()"></div>
    </body>
    </html>欢迎讨论啊,疑惑着呢,还有关于this绑定,散分。
      

  3.   

    行,那我把你的demo修改下 你再看看<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
    <title>Untitled 1</title>
    <script type="text/javascript">
    window.onload=function()
    {
        var redObj=document.getElementById("red");
        redObj.attachEvent("onclick",clickHandle);
        redObj.attachEvent("onmouseout",mouseoutHandle("mouseout"));
    }
    function clickHandle()
    {
        try{
            alert(arguments[0].type);
        }catch(e){
            alert(e.name+":"+e.message);
        }
    }
    function mouseoutHandle(type)
    {
        return function(){
            alert(type);
            alert(arguments.length);    
        };
    }
    </script>
    </head>
    <body>
      <div id="red" style="width:50px;height:50px;background-color:red"></div>
      <div id="black" style="width:50px;height:50px;background-color:black" onclick="clickHandle(event)"></div>
    </body>
    </html>