一次性将事件附加到多个元素上

52

假设我有以下内容:

var a = $("#a");
var b = $("#b");

//I want to do something as such as the following : 

$(a,b).click(function () {/* */}); // <= does not work

//instead of attaching the handler to each one separately

显然,上述方法不可行,因为在$函数中,第二个参数是context,而不是另一个元素。

那么我该如何一次性将事件附加到这两个元素上呢?


[更新]

peirix发布了一个有趣的代码片段,其中他使用&符号组合元素。但我注意到了这个问题:

$(a & b).click(function () { /* */ }); // <= works (event is attached to both)

$(a & b).attr("disabled", true); // <= doesn't work (nothing happens)

从上面可以看到,显然只有在附加事件时使用&符号的组合才有效吗?


未能与jQuery 1.7配合使用。 - drogon
什么不对了?我在问题中提供的代码片段都是无效的。请看一下Gareth的答案,那个是正确的。 - Andreas Grech
9个回答

88

jQuery add方法是您需要的:

将与给定表达式匹配的更多元素添加到匹配元素集合中

var a = $("#a");
var b = $("#b");
var combined = a.add(b)

7
想要添加多于一个元素,所以我写了 var combined = a.add(b,c,d),但是它没有生效,你需要这样写:a.add(b).add(c).add(d)。请注意,不要改变原来的意思。 - Immutable Brick

38

不要忘记,jQuery选择器支持CSS逗号语法。如果你需要合并两个任意的集合,其他人的建议都是正确的,但如果只是对具有ID ab的元素执行某些操作,那么使用 $('#a,#b')即可。


3
我知道那个,但我的问题是当它们已经在变量中时。 - Andreas Grech

16

这个问题已经有了答案,但我认为更简单、更流畅的方法是依赖于jQuery和CSS选择器模型之间的相似之处,并只需执行以下操作:

$("#a, #b").click(function () {/* */});

我经常使用这个方法,从未发现它不起作用(但我无法确认 jQuery 1.3.2 版本之前的情况,因为我没有在那里测试过)。希望这能帮助到有需要的人。


更新:我刚刚重新阅读了这个主题,错过了您关于已将相关节点保存到变量中的评论,但这种方法仍然有效,只需要进行一些微小的调整。您需要执行:

var a = $("#a");
var b = $("#b");
$(a.selector+", "+b.selector).click(function () {/* */});

jQuery 做的一件很酷的事情之一是它向返回的节点添加了一些 jQuery 特定的属性(其中选择器是用于抓取该节点的原始选择器之一)。如果您使用的选择器已经包含逗号,则可能会遇到一些问题。这也可能是可争议的,是否比仅使用 add 更容易,但这是 jQuery 可以变得很酷的有趣示例 :)


这种方法将使jquery重新查找给定选择器的整个DOM树。这是额外的开销。 - Paul Annekov

8

您可以将它们放入数组中:

$.each([a, b], function()
{
    this.click(function () { });
});

糟糕,把语法和另一个each()搞混了 - 现在试试看 - Greg

4
为什么不使用数组呢?这个方法在我的端上是可行的:

$([item1, item2]).on('click', function() {
      // your logic
});

只有当item1和item2是DOM元素而不是jQuery对象时,此方法才有效:http://api.jquery.com/jQuery/#jQuery-elementArray。 - Paul Annekov
@SteelRat,嗯...我在试图回忆我当时测试的是什么。但那是很久以前的事了。 所以如果它是jQuery对象,那么它应该可以使用: $([item1[0], item2[0]]).on('click', function() { // 你的逻辑 }); - Andrey Borisko

2

我刚刚尝试了一下这个功能,发现了一个非常棒的东西:

$(a & b).click(function() { /* WORKS! */ });

超级棒!

编辑: 现在我为没有正确测试而感到非常尴尬。实际上,这个操作是将点击事件放在所有东西上...不确定为什么会这样...


@peirix:& 用于对数字进行按位操作。 - Crescent Fresh
但这并不能解释为什么整个页面都会触发点击事件?它应该只是不被添加,不是吗? - peirix
1
@peirix: DOMElementA&DomElementB的结果为0,因为每个参数都是NaN。 jQuery检查传递的参数是否为“falsey”(FYI 0为falsey),如果找到这样的值,则默认在整个“document”上操作。 - Crescent Fresh
这是故意的吗?如果某些东西是虚假的,它应该只在整个文档上运行吗?听起来非常奇怪,也很容易出现未知错误... - peirix
1
@peirix:jQuery正在模拟“默认”参数。它希望支持使用无参数调用$()并在整个“文档”上运行。自我记忆以来,它一直存在于其中。 - Crescent Fresh

2

您还可以编写一个类名,并为要处理的每个元素赋予该类。然后,您可以将事件绑定到共享该类的所有元素。

<p><a class="fakeClass" href="#">Click Me!</a></p>

<p><a class="fakeClass" href="#">No, Click Me!</a></p>

<div class="fakeClass">Please, Click Me!</div>

<script type="text/javascript">
    $(function () {
        $(".fakeClass").on("click", function () {
            alert("Clicked!");
        });
    })
</script>

0

试试这个:简单而甜美。

var handler = function() {
    alert('hi!');
}
$.each([a,b], function() {
    this.click(handler);
}

顺便说一句,这种方法不值得麻烦。

如果你已经知道只有这两种方法,那么我想最好的选择就是

a.click(handler);
b.click(handler);

干杯!


0

例子:

$("[name=ONE_FIELD_NAME], [name=ANOTHER_FIELD_NAME]").keypress(function(e){alert(e.which);});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接