我已经创建了一个自定义模式对话框,在调用时会在屏幕上添加和删除。但是,当我尝试删除它时,删除功能似乎在某些情况下无法正常工作。
这是模态的关闭函数(通过单击关闭按钮触发):
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上暂停,但这似乎没有帮助。
感谢您的帮助!
答案 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();
});