jQuery.unbind删除使用$ .proxy创建的错误处理程序

时间:2012-02-06 07:54:56

标签: javascript javascript-events jquery microsoft-ajax

我有JavaScript类:

<html>

<head>
    <script src="MicrosoftAjax.js" type="text/javascript"></script>
    <script src="jquery-1.6.4.min.js" type="text/javascript"></script>

</head>

<body>

<script type="text/javascript">

var ClientControl = function () {
    //some instance-specific code here
};

ClientControl.prototype = {
    initialize: function () {
        this.documentClickedDelegate = $.proxy(this.documentClicked, this);
        //this.documentClickedDelegate = Function.createDelegate(this, this.documentClicked); // from MicrosoftAjax
    },

    bind: function() {
        $(document).bind("click", this.documentClickedDelegate);
    },

    unbind: function() {
        $(document).unbind("click", this.documentClickedDelegate);
    },

    documentClicked: function() {
        alert("document clicked!");
    }
};

var Control1 = new ClientControl();
Control1.initialize();
var Control2 = new ClientControl();
Control2.initialize();

Control1.bind();
Control2.bind();

Control1.unbind();
//Control2`s documentClickedDelegate handler, if created with $.proxy, already is unbound!

</script>
</body>
</html>

所以问题是,当调用FIRST Control1 对象的 unbind()方法时,它取消绑定两个对象的两个 documentClickedDelegate 处理程序,如果它们是使用 $。proxy()方法创建的。 所以jquery事件系统认为这些处理程序是相同的,尽管传递给$ .proxy()方法的上下文不同。

如果 documentClickedDelegate 处理程序是使用 Function.createDelegate - MicrosoftAjax Library的方法创建的,那么一切正常。处理程序不同。

原来, $。proxy 为传递的不同上下文创建了相同的代理函数。来自官方网站:

  

“请注意,jQuery的事件绑定子系统会分配一个   每个事件处理函数的唯一ID,以便在它时跟踪它   用于指定要解除绑定的函数。功能   由jQuery.proxy()表示的单个函数由   事件子系统,即使它用于绑定不同的上下文。至   避免取消绑定错误的处理程序,使用唯一的事件命名空间   绑定和解除绑定(例如,“click.myproxy1”)而不是指定   解除绑定时的代理功能。 “

在我的情况下,这是完成的,因为名称空间分隔特定于类型的事件,而不是特定于实例的事件。

以下是截图,您可以看到, $。proxy 创建的处理程序具有相同的 GUID = 1 Function.createDelegate 创建具有不同GIUD的处理程序: guid = 1且guid = 2

enter image description here

enter image description here

enter image description here

enter image description here

因此,当在第一种情况下删除一个时,它会删除两者,这不应该完成!

我的问题是:在J.quateDelegate的jquery中是否有任何模拟?我不想使用另一个MicrosoftAjax库只有一个功能。 或者也许是这个问题的任何一般解决方案 - 如何告诉jquery处理程序是不同的。谢谢你的回答。

1 个答案:

答案 0 :(得分:6)

您需要命名事件的命名空间。简单的例子:

var counter = 0;

ClientControl.prototype = {
    initialize: function () {
        this.documentClickedDelegate = $.proxy(this.documentClicked, this);
        this.num = counter++;
    },
    bind: function() {
        $(document).bind("click.proxy" + this.num, this.documentClickedDelegate);
    },
    unbind: function() {
        $(document).unbind("click.proxy" + this.num, this.documentClickedDelegate);
    },
    documentClicked: function() {
        alert("document clicked!");
    }
}

这里是working version。单击文档上的任意位置,您将收到一个警报。没有命名空间,你得到2。