我的.remove()事件不起作用

时间:2018-01-17 19:53:17

标签: javascript jquery

我已经创建了一个自定义模式对话框,在调用时会在屏幕上添加和删除。但是,当我尝试删除它时,删除功能似乎在某些情况下无法正常工作。

这是模态的关闭函数(通过单击关闭按钮触发):

function modal_close() {
  $('.custom_block_page').fadeOut().remove();
  $(this).parent().fadeOut().remove();
};

这就是我从模态对话框中的按钮调用该函数的方法:

MatchGame.closeWin = function() {
  $('.custom_modal_close').trigger('click');
  MatchGame.playGame();
};

如果我只是单击关闭按钮,对话框将被删除,一切都按预期工作。但是当我触发关闭时,对话框会消失,但会保留在体内,以便下次调用时再次显示。

在我之间检查控制台:

$('.custom_block_page').length
1  // displayed the first time
$('.custom_block_page').length
0  // during the 2nd game (expected)
$('.custom_block_page').length
2  // displayed after the 2nd game; I expect this to be 1

我已经尝试在我的playGame上暂停,但这似乎没有帮助。

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您观察到的问题归因于.fadeOut(),它是在一系列后续事件线程中以异步方式实现的。

同时,在原始事件线程.remove()中,后续语句从函数调用程序中的函数和后续语句返回,ALL同步执行 - 远在.fadeOut()之前完成。

解决方案是利用.promise(),它将返回一个jQuery承诺,您可以从中.then()链接:

function modal_close() {
    return $('.custom_block_page').add($(this).parent()).fadeOut().promise().then(function() {
        $(this).remove();
    });
};

在调用者中,.trigger()返回jQuery,但您现在需要使用返回的promise,因此使用.triggerHandler()

MatchGame.closeWin = function() {
    $('.custom_modal_close').triggerHandler('click').then(function() {
        MatchGame.playGame();
    });
};

修改

来自add_block_page()add_popup_box()的代码可以安全地汇总到show_modal_box()以生成一个更大的功能。

通过这样做,您可以从关闭按钮的点击处理程序中访问变量$block_page$pop_up$close$inner

function show_modal_box() {
    var $block_page = $('<div class="custom_block_page"></div>').appendTo('body'); // dark background
    var $pop_up = $('<div class="custom_modal_box"></div>').appendTo($block_page);
    var $close = $('<a href="#" class="custom_modal_close"></a>').appendTo($pop_up);
    var $inner = $('<div class="custom_inner_modal_box">loading...</div>').appendTo($pop_up);
    if(options.name != '') {
        $pop_up.attr('id', options.name);
    }

    // Add the content - if url, load the page otherwise use the text
    if (options.url != '') {
        $inner.load(options.url);
    } else {
        var innerHTML = '';
        if(options.title[0] === "<") { // assume formatting
            innerHTML += options.title;
        } else {
            innerHTML += '<h2>' + options.title + '</h2>';
        }
        if(options.description[0] === "<") {
            innerHTML += options.description;
        } else {
            innerHTML += '<p>' + options.description + '</p>';
        }
        $inner.html(innerHTML);
    }

    $close.click(function() {
        // for example
        return $pop_up.fadeOut().promise().then(function() {
            $block_page.remove();
        });
    });
    $(window).off('resize.popup').on('resize.popup', add_styles).trigger('resize.popup'); // prevent accumulation of resize handlers

    // checkNeedScroll();
    $pop_up.fadeIn();
}

编辑2

我想我拥有它!

custom_modal_box插件中,下面的代码会将点击处理程序附加到this

    return this.click(function(e) {
        show_modal_box();
    });

如果在任何特定元素上只调用一次插件,那就没关系了,但是在这个游戏的代码中,每次游戏完成时都会在相同的元素$('.win')上调用它。

要防止在$('.win')上累积点击处理程序,请将该代码更改为:

    return this.off('click.popup').on('click.popup', function(e) {
        show_modal_box();
    });