javascript中使用attachEvent添加了匿名函数事件,如何用detachEvent移除这个事件?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript中使用attachEvent添加了匿名函数事件,如何用detachEvent移除这个事件?相关的知识,希望对你有一定的参考价值。

具体情况是这样,我想做一个可以用鼠标拖动的元素,当onmousedown的时候添加事件,让元素跟随鼠标,当onmouseup的时候移除这个事件。
var g = function(o) return document.getElementById(o);
window.onload = function()
bar = g("dragBox");
bar.attachEvent("onmousedown",function(e) startDrag(e););
bar.attachEvent("onmouseup",function(e) endDrag(e););
function startDrag(e)
if(e.button == 1)
bar.attachEvent("onmousemove",function(e) followMouse(e););


function endDrag(e)
if(e.button == 1)
bar.detachEvent("onmousemove",function(e) followMouse(e););


function followMouse(e)
var mousex = e.clientX;
var mousey = e.clientY;
var ele = e.srcElement?e.srcElement:e.target;
window.status = mousex+", "+mousey+" - "+ele.id;



其实我想知道的就是:
如果用attachEvent或者addEventListener添加的事件函数是匿名函数,如何用detachEvent或者removeEventListener删除?

做这种东西,建议你用js库去做,
或者你不想用jQuery这种体积庞大的库(也不算大,最新版本80多k,可以压缩到50多k)
可以用CJL这种小库,对原生的js做了些基本的兼容.体积只有6k不到.
再或者你自己封装些常用的兼容,方法.
看下我这个爱墙的拖动怎么样?
http://shirne.com/love
下面是我以前写的拖动插件,不明白的地方随时找我.
//用法$("id1").startDrag($("id2"));
//id1为鼠标启用效果的元素,id2为移动的元素
//例如,有一个div元素,内有一个h2标签作为这个div版块的标题.就可以在h2上启用拖动来移
//动div元素,而在div内的其它地方则不启用拖动
var d=document;
d.addListener=function(e,f,b)
this.attachEvent?this.attachEvent('on'+e,f):this.addEventListener(e,f,b);

d.removeListener=function(e,f,b)
this.detachEvent?this.detachEvent('on'+e,f):this.removeEventListener(e,f,b);

function $()
var o=document.getElementById(arguments[0]);
o.addListener=function(e,f,b)
this.attachEvent?this.attachEvent('on'+e,f):this.addEventListener(e,f,b);

o.removeListener=function(e,f,b)
this.detachEvent?this.detachEvent('on'+e,f):this.removeEventListener(e,f,b);

o.startDrag=function(obj)
var obj=obj?obj:o;
var sx,sy;
o.style.cursor="move";
o.addListener("mousedown",function(e)
e||event;
if(e.button==1||e.button==0)
sx=e.clientX-obj.offsetLeft;sy=e.clientY-obj.offsetTop;
d.addListener("mousemove",move,false);
d.addListener("mouseup",stopDrag,false);

,false);

var stopDrag=function()
d.removeListener("mousemove",move,false);
d.removeListener("mouseup",stopDrag,false);

var move=function(e)
e||event;
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
if(e.preventDefault)e.preventDefault();
with (obj.style)
position="absolute"
left=e.clientX-sx+"px";
top=e.clientY-sy+"px";



return o;


要移除事件监听,除了用函数名外,还可以用索引。
如:delete element.events[type][0]
除非你十分确定,否则用索引删除可能会出问题追问

d.addListener("mousemove",move,false);
这个我明白,如果参数中的move函数换成匿名函数function(),也就是:
d.addListener("mousemove",function() move();alert("------");,false);
问题:
1.这样可以remove掉么?
2.可以的话怎么做?
3.如果不可以的话是不是就说明匿名函数不适合在事件的绑定与移除中使用?

追答

1,可以remove掉,但你要有索引,没有索引或不准确可能移除错误或出错
2,应该是在绑定的时候记下索引,就用那句
delete element.events['mousemove'][0]
3,不方便,最好使用函数名,不会对性能有什么影响.
最后,这种方法我没测试过,只是看一些js库里这样用,我这样理解的

参考技术A 如果不考虑你要的效果,有方法可以删除匿名函数的方法
那就是使用
arguments.callee;
代码如下:(注:EventUtil为我自己写的工具类)

EventUtil.addHandler(btn, 'click', function()
var fnName = arguments.callee;//保存
EventUtil.task(function()
alert('输出');
EventUtil.removeHandler(btn, 'click', fnName);//移除单击绑定
, 5000);
);
参考技术B 好像没有移除 匿名函数事件的功能吧。
除非是 abc.onclick=function() 这样的形式 那还有办法
这样的直接就 abc.onclick= null 就OK了

你可以这样整理代码 ,把这些函数放进 数组里。 如下

var funcs = [];
funcs[0] = function(e) startDrag(e);;
funcs[1] = function(e) endDrag(e);;
funcs[2] = function(e) followMouse(e);;

那你使用就方便了呀,
bar.attachEvent("onmousemove", funcs[2]);
bar.detachEvent("onmousemove",funcs[2]);
参考技术C 记录事件名称,detachEvent的时候把名称传入就行了

以上是关于javascript中使用attachEvent添加了匿名函数事件,如何用detachEvent移除这个事件?的主要内容,如果未能解决你的问题,请参考以下文章

javascript中attachEvent事件 跟 addEventListener 事件

JavaScript中的attachEvent和addEventListener

Javascript添加事件跨浏览器功能实现:使用attachEvent/addEventListener vs inline events

Javascript IE8没有在attachEvent中传递'this'

javascript绑定事件addEventListener与attachEvent

JavaScript之元素绑定事件