问题小提琴:
点击查看(尝试 #1,使用委托事件)
点击查看(尝试#2,暴力破解方法如下)
点击查看(尝试#3,重构,有我要解决的问题)
在我正在处理的一个项目中,我正在探索一种相当动态的形式。除了一些静态元素外,还有各种交互元素,可以从隐藏的“模板”标记集中克隆,并添加到业务流程的各个点。
由于动态特性,我的可靠方法是在加载时设置 jQuery 元素缓存和事件处理程序,然后让用户做任何不可行的事情,因为这种动态特性;我发现我的动态添加的元素没有点击事件。
为了解决这个问题,我为每个有问题的脚本元素手动设置了重新绑定方法。重新绑定过程涉及 A) 重新获取给定描述性选择器的元素集,B) 删除该缓存上的任何现有事件,因为这些事件适用于不完整的元素集,以及 C) 调用绑定方法以应用新的事件到整个集合。
我得到的蛮力,工作方式是这样的:
var $elementCache = $('.some-class');
function rebindSomeLink() {
// Re-acquire the element cache...
$elementCache = $('.some-class');
// Drop all existing events on the cache...
$elementCache.unbind();
// Call a bind function to establish new events.
bindSomeLink();
}
function bindSomeLink() {
$elementCache.click(function (e) {
// ...Behavior...
});
}
// There are four other links with a similar rebind/bind function relationship set up.
自然地,我抓住了使用几乎完全相同的代码如此频繁地重复重新绑定的机会——重构的时机已经成熟。我们有一个公共库命名空间,我在其中添加了一个rebindEvents
函数......
var MyCommon = function () {
var pub = {};
pub.rebindEvents = function($elementCache, selector, bindFunction) {
$elementCache = $(selector);
$elementCache.unbind();
bindFunction();
};
return pub;
}();
在尝试调用它并运行该站点时,我立即将脚趾撞到了UncaughtTypeError: method click cannot be called on object undefined.
事实证明,似乎当我调用以下命令时:
MyCommon.rebindEvents($elementCache, '.some-class', bindSomeLink);
$elementCache
没有被传递给方法rebindEvents
;当我在调试器中进入它时, $elementCache 里面rebindEvents
是undefined
.
一些方便的 StackOverflow 研究向我揭示了 JavaScript没有引用传递,至少在我熟悉的 C/C++/C# 意义上,这导致了我的两个问题:
A)我什至可以使用某种缓存引用传递重构此重新绑定功能吗?
B)如果我可以将我的重新绑定函数重构到我的公共命名空间,我将如何去做?