简体   繁体   English

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

[英]My .remove() event isn't working

I've created a custom modal dialog that is added and removed from the screen when it is called. 我创建了一个自定义模式对话框,该对话框在调用时会添加到屏幕上或从屏幕上删除。 However, when I'm trying to remove it, the remove function doesn't seem to be working in certain circumstances. 但是,当我尝试删除它时,删除功能在某些情况下似乎不起作用。

This is the close function from the modal (triggered by clicking on the close button): 这是模态中的关闭功能(通过单击关闭按钮触发):

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

This is how I call that function from the button inside the modal dialog: 这是我从模式对话框中的按钮调用该函数的方式:

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

If I just click the close button, the dialog is removed and everything works as expected. 如果我只单击关闭按钮,则对话框将被删除,并且一切都会按预期进行。 But when I trigger the close, the dialog fades to nothing, but remains in the body so it displays again the next time it is called. 但是,当我触发关闭操作时,对话框将消失为空,但仍保留在主体中,因此在下次调用该对话框时会再次显示。

Checking the console between I get: 检查控制台之间我得到:

$('.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

I've tried putting a timeout on my playGame, but that didn't seem to help either. 我尝试在playGame上设置超时,但这似乎也无济于事。

Thanks for the help! 谢谢您的帮助!

The issue you observe is due to .fadeOut() , which is implemented asynchronously in a whole series of later event threads. 您观察到的问题.fadeOut().fadeOut() ,它在一系列更高版本的事件线程中异步实现。

Meanwhile, in the original event thread .remove() , subsequent statements, returning from the function and subsequent statements in the function's caller, ALL execute synchronously - well before .fadeOut() has completed. 同时,在原始事件线程.remove() ,从该函数返回的后续语句以及该函数的调用.fadeOut()后续语句在ALL 同步执行-在.fadeOut()完成之前。

The solution is to exploit .promise() , which will return a jQuery promise, from which you can chain .then() : 解决方案是利用.promise() ,它将返回一个jQuery .promise() ,您可以从中链接.then()

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

In the caller, .trigger() returns jQuery but you now need to work with the returned promise, therefore use .triggerHandler() . 在调用.trigger().trigger()返回jQuery,但是您现在需要使用返回的.triggerHandler() ,因此请使用.triggerHandler()

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

Edit: 编辑:

Code from add_block_page() and add_popup_box() can be safely rolled into show_modal_box() to make one larger function. 来自add_block_page()add_popup_box()可以安全地滚动到show_modal_box()以实现一个更大的功能。

By doing so, you will benefit from being able to access the variables $block_page , $pop_up , $close , $inner from the close button's click handler. 这样,您将从能够从关闭按钮的单击处理程序访问变量$block_page$pop_up$close$inner $pop_up

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();
}

EDIT 2 编辑2

I think I have it! 我想我有!

In the custom_modal_box plugin, the code below causes a click handler to be appended to this : custom_modal_box插件中,以下代码导致将点击处理程序附加this

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

That's fine if the plugin is invoked just once on any particular element however in this game's code it is invoked on the same element, $('.win') , every time a game is completed. 如果该插件在任何特定元素上仅被调用一次,那很好,但是在游戏的代码中,每次游戏完成时,它在同一个元素$('.win')上被调用。

To prevent an accumulation of click handlers on $('.win') , change that code to : 为了防止$('.win')上单击处理程序的积累,请将代码更改为:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM