当一次将事件绑定到多个元素时,每个元素都有新的实例

When binding event to multiple elements at once, new instance for each element?

本文关键字:元素 实例 一次 绑定 事件      更新时间:2023-09-26

我有100按钮在我的页面(他们每个人都有='btn')。

我也有一个单个按钮,其中准备所有其他 100个按钮。

<input type='button' onclick='bindTheClickevent()' />

当按下时,-它调用bindTheClickevent() -(它将点击事件绑定到所有其他100个事件)。

在Script部分我放了:

function bindTheClickevent ()
{
        $(".btn").bind('click',function () {
          $(this).css('color','red');
         });
}

1)在内存中,匿名函数创建了多少实例 ?

2)在内存中,bindTheClickevent()函数是否会空闲(GC)?-请注意,Bind在 bindTheClickevent函数中被称为

3) ,最终- bindTheClickevent函数将被GC ?

让我们做一个改变

function bindTheClickevent ()
    {
            $(".btn").bind('click',function () {
              changeColor($(this));
             });
    }
function changeColor(obj)
{
 $(obj).css('color','red');
}

现在-更改后

1)如果我这样做有什么不同吗?

2)在内存中,匿名函数创建了多少实例 ?

3) bindTheClickevent()函数是否永远是空闲的(GC) ?-请注意,Bind在 bindTheClickevent函数中被称为

"1)在内存中,创建了多少个匿名函数的实例?"

哪个匿名函数?

对于内联onclick,您将获得一个分配给元素onclick属性的函数,如下所示:

function(event) {
    bindTheClickevent();
}

…或者类似,取决于实现。当元素被解引用或函数从onclick属性解引用时,该函数将被GC释放。

对于jQuery代码:

$(".btn").bind('click',function () {
    $(this).css('color','red');
});

…虽然匿名函数是共享的,但您没有看到的是,如果相关元素还没有绑定jQuery处理程序,jQuery将在内部为每个元素创建一个唯一的函数。

内部处理程序是实际绑定到元素的,当元素接收到事件时,调用该处理程序,分析事件,并调用您最初传递的处理程序(如果需要)。

这意味着100个jQuery绑定元素等于101个唯一的函数实例

为了确保使用jQuery绑定的任何处理程序都被GC,您需要确保始终使用jQuery删除DOM元素。如果不这样做,存储在jQuery.cache中的所有数据(包括处理程序)都不会被清理,因此它们将始终通过全局jQuery命名空间被引用。


编辑:

假设有100元素有btn类,没有任何jQuery绑定的处理程序,那么这段代码:

$(".btn").bind('click',function () {
    $(this).css('color','red');
});

…将创建101唯一的Function实例。

为什么是101 ?

jQuery所做的是当你第一次绑定一个处理程序到一个元素时,它会在内部为每个元素创建一个唯一的通用处理程序。这是在事件发生时实际调用的处理程序,并处理所有事件类型。

你的处理函数是从来没有实际绑定到元素。

因此,调用通用内部处理程序时将分析发生的事件,并查看是否有任何处理程序与使用.bind()匹配该事件类型的给定元素相关联。如果是,则调用传递的处理程序。

现在假设你绑定了另一个处理程序:

$(".btn").bind('mouseenter',function () {
    $(this).css('color','blue');
});

…因为我们绑定了相同的元素,它们已经有了必需的内部处理程序,所以不需要再创建另一个。因此,所发生的一切就是您传递的函数在内部被引用,并在需要时由泛型内部处理程序调用。

因此,根据上面的代码片段,现在存在102唯一的Function实例。

看起来在这两种情况下只创建了一个函数的实例。似乎对匿名函数的引用被附加为每个元素的事件处理程序。

示例 -使用闭包来显示按钮事件处理程序之间的范围共享。

注意如果涉及到闭包,这会导致有趣的行为,因为所有元素将共享相同的函数(和闭包作用域)。

不,你声明的函数不会被GC,因为它们的全局作用域。

另外

要独立附加它们(而不是通过引用),使用.each()遍历所选元素并单独附加函数。

$('.btn').each(function() {
    $(this).bind('click',function() {
        // each '.btn' has it's own copy of
        // this anonymous function
    }
});

如果您这样做:

for (someiterations)
{
    $(myobj).bind("click",function()
    {
        // ...bla...
    });
}

在这种情况下,每次迭代都创建一个新函数。在你的函数中,这不会发生,因为你将函数传递给一个参数,所以有一个地方存储了它的引用(是的,函数参数),它会做这样的事情:

for (iterations)
{
    myob.addEventHandler(event, funcref);
}

现在应该没问题了:

  1. 不这么认为,但是不确定语法。
  2. 不,因为它在全局作用域中,没有分配给实例,你可以把它看作常量,而不是变量

注意:匿名函数不会被释放,它被事件处理程序引用。