2013-03-18 110 views
1

我的HTML表单事件处理程序有这个标记:防止其他被运行

<fieldset> 
    <legend> 
     <label> <input type="checkbox" class="warnOnUncheck" /> Include the following data </label> 
    </legend> 
    <div class="fieldsetContent"> 
     <!-- and a bunch of <input type="text" /> here. --> 
    </div> 
</fieldset> 

我有由DOM准备叫了两个脚本:

  1. 第一个崩溃的内容当复选框未选中并显示
  2. 第二个显示一个confirm()确认消息,当复选框未选中时。如果用户点击“否”,则复选框被重新检查。

问题是总是调用第一个事件处理程序,所以即使用户单击“否”,字段集内容仍然隐藏。

这里是我的(有删节)的jQuery代码(DOM-ready事件处理过程中调用):

$("fieldset.collapseable legend input").change(function(event) { 

    var localFieldsetContent = $(this).closest("fieldset").find("div.fieldsetContent"); 

    var checked = $(this).is(":checked"); 
    if(checked && localFieldsetContent.is(":visible")) { 
     // if checked and already visible, then skip entirely. 
     return; 
    } 

    localFieldsetContent.slideToggle(200); 
); 

$("input[type=checkbox].warnOnUncheck").change(function(event) { 

    if(!this.checked) { 

     var message = $(this).data("warnMessage"); 

     var confirmed = confirm(message); 
     if(!confirmed) { 

      this.checked = true; 
      event.stopImmediatePropagation(); 
     } 
    } 

}); 

我认为event.stopImmediatePropagation();会的工作,但事实并非如此。

如何避免在confirmed为假时折叠字段集?

+0

尝试添加一个'返回false;'而不是stopImmediatePropagation – dakait 2013-03-18 07:44:32

+0

尝试返回false;如果我没有错,它会这样做 – xurca 2013-03-18 07:33:51

回答

1

立即解决问题:第一个处理程序的第二个(一个与确认)有机会打电话stopImmediatePropagation之前执行。绑定你的处理程序以相反的顺序,它应该工作:

$("input[type=checkbox].warnOnUncheck").change(function(event) { 

    if(!this.checked) { 

     var message = $(this).data("warnMessage"); 

     var confirmed = confirm(message); 
     if(!confirmed) { 

      this.checked = true; 
      event.stopImmediatePropagation(); 
     } 
    } 

}); 

$("fieldset.collapseable legend input").change(function(event) { 

    var localFieldsetContent = $(this).closest("fieldset").find("div.fieldsetContent"); 

    var checked = $(this).is(":checked"); 
    if(checked && localFieldsetContent.is(":visible")) { 
     // if checked and already visible, then skip entirely. 
     return; 
    } 

    localFieldsetContent.slideToggle(200); 
); 

不过,我觉得非常不安全了两个功能分开这一行为。

我将两个处理器合并成一个单一的一个:

$("input[type=checkbox].warnOnUncheck").change(function(event) { 
    var confirmed = true; 
    if(!this.checked) { 
     var message = $(this).data("warnMessage"); 

     var confirmed = confirm(message); 
     if(!confirmed) { 
      this.checked = true; 
     } 
    } 

    if (confirmed) { 
     var localFieldsetContent = $(this).closest("fieldset").find("div.fieldsetContent"); 
     localFieldsetContent.slideToggle(200); 
    } 
}); 

这里是一个jsfiddle


如果您不能合并的处理程序,可以绑定“崩溃”功能到一些自定义事件,并在复选框上有“点击”事件触发它。

看到这个updated jsfiddle

$("input[type=checkbox].warnOnUncheck").change(function(event) { 
    var confirmed = true; 
    if(!this.checked) { 
     var message = $(this).attr("data-warnMessage"); 
     confirmed = confirm(message); 
     if(!confirmed) { 
      this.checked = true; 
     } 
    } 

     if (confirmed) { 
      $(this).trigger("myToggleVisibility"); 
     } 
}); 

$("fieldset.collapseable").on("myToggleVisibility", function(event) { 
    $(this).find('.fieldsetContent').slideToggle(200); 
}); 
+0

谢谢。我添加了'event.stopImmediatePropagation();'和'if(event.isImmediatePropagationStopped()'并颠倒了事件的顺序,但它看起来有点像黑客,恐怕我不能将两者事件,对不起。 – Dai 2013-03-20 04:55:52

+0

我不想知道里面有什么:)添加了一个更清晰的方式来链接这两个事件,希望你可以使用它。 – LeGEC 2013-03-20 08:45:32

0

使用event.preventDefault();

OR

if(!confirmed){ 
    this.checked = true; 
    return false; 
} 
0

试试这个:

$("input[type=checkbox].warnOnUncheck").change(function(event) {  
    if (event.isImmediatePropagationStopped()) { 
     return false; 
    } 
    if(!this.checked) {  
     var message = $(this).data("warnMessage");  
     var confirmed = confirm(message); 
     if(!confirmed) {  
      this.checked = true; 
      event.stopImmediatePropagation(); 
     } 
    }  
}); 

http://api.jquery.com/event.isImmediatePropagationStopped/