今天在做项目的过程中,为了绑定事件方便,采用将事件句柄定义为HTML属性的方式来绑定事件。一开始是这个样子的:
HTML
JS
var action = {}; window.action = action; action.removeTr = function(ele){ $(ele).parent().parent().remove(); };
我为什么这样写呢,因为我不想将太多的事件句柄直接放到window作用域中去,以免事件太多了,容易冲突,也不方便管理。于是我把HTML属性事件全都放到对象action里面去,然后再将此对象扩展到window里。这应该算是一个不错的想法,我之前也这样做过,都没问题的,但今天情况有所不同。总是报错:action.removeTr is not a function。
经过我不懈的努力!我找到了应外一种结局此问题的方法。有些非主流..(虽然后来我用了其他方法,但我还是不明白这种方法为什么能行)
JS
setTimeout(function(){ var action = {}; window.action = action; action.removeTr = function(ele){ $(ele).parent().parent().remove(); }; }, 10000);
我只是让刚才那段代码延时执行了一会,注:这段代码是放在jQuery的document.ready函数中执行的哦!
太诡异了!!
不过我还不死心,就拿出《JavaScript权威指南》随手翻翻,希望能找到答案,果然没让我失望。P397有关于事件句柄作用域的章节。
定义为HTML属性的事件句柄 拥有与其它函数不同的作用域链。它的作用域链的头是调用对象(这意味着this指向该元素),并且事件句柄的作用域链中的下一个对象仍不是window,事件句柄的作用域会随定义句柄的对象终止,它还会延伸到包容层级,而且至少包括包含该元素的HTML<form>元素和包含表单的Document对象。作用域链终止对象才是window。
这就找到我之前出错的原因了,因为我的<a>标签是包含在表单之中的,onclick中的代码所访问的action对象不是我定义在window中的,而是表单的form.action。所以报错action.removeTr is not a function,因为form.action根本就没有removeTr这个函数。正确的写法只要该改个名字就可以了。
var customAction = {}; window.customAction = customAction; customAction.removeTr = function(ele){ $(ele).parent().parent().remove(); };