0

问题小提琴:

点击查看(尝试 #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 里面rebindEventsundefined.

一些方便的 StackOverflow 研究向我揭示了 JavaScript没有引用传递,至少在我熟悉的 C/C++/C# 意义上,这导致了我的两个问题

A)我什至可以使用某种缓存引用传递重构此重新绑定功能吗?

B)如果我可以将我的重新绑定函数重构到我的公共命名空间,我将如何去做?

4

1 回答 1

1

使用 Jquery On 在始终存在的 DOM 中的高层元素处绑定事件。 http://api.jquery.com/on/

这是将事件绑定到动态创建的元素的最简单方法。

这是一个显示示例的jsfiddle 。

$('#temp').on('click', 'button', function(){
   alert('clicked'); 
});

$('#temp').append('<button>OK</button>');

该事件绑定到一个 div,该 div 稍后会动态添加一个按钮。因为按钮没有点击事件,所以事件“冒泡”到 DOM 树的父元素,它确实有一个按钮的点击事件,所以它处理它并且事件不再“冒泡”。

于 2013-09-04T19:38:30.063 回答