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-ready 调用的脚本:

  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为 false 时被折叠?

4

3 回答 3

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


如果您不能合并处理程序,您可以将“折叠”功能绑定到某个自定义事件,并让复选框上的“点击”事件触发它。

看到这个更新的 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);
});
于 2013-03-18T07:56:41.247 回答
0

采用event.preventDefault();

或者

if(!confirmed){
    this.checked = true;
    return false;
}
于 2013-03-18T07:48:20.623 回答
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/

于 2013-03-18T07:57:18.017 回答