如何在事件仅触发一次之后取消释放

时间:2011-03-18 11:22:25

标签: jquery events

我在一组选择列表(a.k.a.下拉列表)上连接了一个事件 - 在触发绑定事件时 - 我需要从中删除该事件。

每个选择列表都包含“change”事件,如下所示:

$('#batting-delivery-table tbody').delegate('select[id^="shot-"]', 'change', function () {
    $(this).find('option:first').remove();
});

只要删除了列表中的第一个选项,我就确保不会删除其他选项。我尝试了以下方法,但没有取得任何成功:

$('#batting-delivery-table tbody').delegate('select[id^="shot-"]', 'change', function () {
    $(this).find('option:first').remove().undelegate($(this), 'change');
});

我还尝试了“live”/“die”的变体,并考虑使用$ .one(),如果我可以想象如何安排我的代码。

建议表示赞赏。

2 个答案:

答案 0 :(得分:8)

jQuery .one()函数用于此特定目的。

  

<强>。一()

     

说明:将处理程序附加到元素的事件。每个元素最多执行一次处理程序。

答案 1 :(得分:1)

你试过这个吗?

$("#batting-delivery-table tbody").delegate('select[id^="shot-"]', "change", function () {
    $(this).undelegate("change").find("option:first").remove();

});

这些选择可能不会在(更长)页面生命期间在客户端上动态生成,而是在内容中加载,因此不需要使用delegate/undelegate功能。当用户选择某些东西并且你不想再次选择虚拟选项时,你可能只是试图从它们中删除从列表中选择项目选项(这是相当聪明和好看的) 。我会选择bind/unbind

$("select[id^='shot-']").bind("change", function(evt){
    $(this).unbind("change").find("option:first").remove();
});

您可以检查this JSFiddle是否按预期工作(甚至您可能也喜欢的风格改进很少)。

动态选择

解决方案1 ​​

live/delegate功能将无法正常工作,因为当您尝试取消特定元素上的事件时,委托事件仍然与其选择器匹配。所以它不起作用,因为事件与单个元素无关。可以在jQuery文档中阅读以这种方式工作的原因的详细信息,这超出了这个答案的范围。

制作它的最佳方法是给予虚拟option特殊class,这样您就可以将其与其他人区分开来,并在存在时将其删除,如果不存在则不执行任何操作。但change事件无论如何都会运行。

$("select[id^='shot-']").live("change", function(evt){
    $("option.dummy-option", this).remove();
});
使用live处理程序注册的

JSFiddle

解决方案2

您仍然可以使用one处理程序注册,但是新广告选择到表单的功能必须注册事件以及附加的新select元素(因此没有全局事件注册)。此功能的一个示例:

$("a.action-add-new").click(function(evt) {
    evt.prevetnDefault();
    $("<select><option>...</option></select>").appendTo("someContainer").one("change", function(){
        $("option:first", this).remove();
    });
});

解决方案3

哦,我提出了解决方案3,它使用live(或者可以使用delegate)事件注册。您应该将事件处理程序设置为在更改运行后更改的特定选择器。

创建选择时,请为其指定特定的class 取消选择。然后针对该选择器注册change事件。在更改事件中,只需删除该类,它就不会再次运行此select元素。

<select id="shot-first" class="unselected">
...
</select>

$("select[id^='shot-'].unselected").live("change", function(evt) {
    $(this).removeClass("unselected").find("option:first").remove();
});

检查this JSFiddle中的工作概念证明。作品。我不知道为什么我之前没有想出这个。 :)