防止其他事件处理程序运行

时间:2013-03-18 07:29:37

标签: jquery

我的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. 时,第一个会折叠字段集的内容
  3. 第二个,当取消选中该复选框时,会显示confirm()确认消息。如果用户单击“否”,则重新选中该复选框。
  4. 问题是始终会调用第一个事件处理程序,因此即使用户单击“否”,字段集内容仍然是隐藏的。

    这是我的(删节)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,我怎样才能阻止字段集折叠?

3 个答案:

答案 0 :(得分: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


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

请参阅此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);
});

答案 1 :(得分:0)

使用event.preventDefault();

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

答案 2 :(得分: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/