<!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?有没有精确点的总结和分析?
6 个解决方案
#1
#2
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。
alert(e.type);
})
测试的是,这个在IE5.5下都可以弹出event.type。
也就是说attachEvent可以传入Event对象。
但是this指向的是window。
而
htmlElement.onclick = function(e){}IE就不能传入Event对象了,而this指向的是htmlElement。
#3
就像你说的,事实就是: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绑定,散分。
#4
#5
行,那我把你的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>
#6
你看下不同的结果
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Untitled 1</title>
<script type="text/javascript">
function clickHandle(e) {
alert(e.type);
}
window.onload = function() {
document.getElementById("red").onclick = function(event) {
alert(event);
}
document.getElementById("red").attachEvent("onmouseover",function(e) {alert(e.type);});
};
</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>
#1
#2
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。
alert(e.type);
})
测试的是,这个在IE5.5下都可以弹出event.type。
也就是说attachEvent可以传入Event对象。
但是this指向的是window。
而
htmlElement.onclick = function(e){}IE就不能传入Event对象了,而this指向的是htmlElement。
#3
就像你说的,事实就是: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绑定,散分。
#4
#5
行,那我把你的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>
#6
你看下不同的结果
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Untitled 1</title>
<script type="text/javascript">
function clickHandle(e) {
alert(e.type);
}
window.onload = function() {
document.getElementById("red").onclick = function(event) {
alert(event);
}
document.getElementById("red").attachEvent("onmouseover",function(e) {alert(e.type);});
};
</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>