$.Deferred reject已忽略,在特定情况下不会触发任何回调
$.Deferred reject ignored and does not fire any callbacks in a specific situation
我正在尝试制作一个淡入,在淡入的位置停止淡入,并从淡入停止时的不透明度开始淡入。目前,当我第一次键入键时,如果我用另一个按键中断淡入,它将导致animOpacityPromise
在页面刷新之前永远无法解析。如果我让fadeOut完成,任何后续的animOpacityPromiseCtrl.reject();
都将被忽略,直到页面刷新,允许fadeOut结束。例如,在JSFiddle中,如果我键入一个密钥,等待我在日志中看到clearOverlay animate promise completed
,然后键入"ABC",等待它开始淡出并用"SS"中断它的淡出,覆盖将立即在第一个s上消失,并在第二个s上重新出现内容"SS"。预期的行为是,在覆盖完成淡出之前,它不会清除searchString和覆盖,而是用淡入来中断淡出,并将键附加到搜索字符串和覆盖上。如果我用键击中断第一个淡出,动画行为就是我想要的淡入,淡入会在它所在的位置停止淡出,并从淡出停止时的不透明度开始淡入,但在页面刷新之前,animOpacityPromise.done
和animOpacityPromise.always
永远不会在任何键击中调用。
JSFiddle
function initQuickSearch() {
var overlay = $('#searchOverlay');
var overlayIsFadingOut = false;
var fadeOutTimeOut;
var searchString = '';
var animOpacityPromiseCtrl = $.Deferred();
function showOverlay() {
var fadeDelay = 200;
if (overlayIsFadingOut) {
console.log('clearOverlay animate promise rejected');
animOpacityPromiseCtrl.reject();
overlayIsFadingOut = false;
clearTimeout(fadeOutTimeOut);
fadeDelay = 100;
}
overlay.css({'visibility': 'visible'});
overlay.stop(true, false).animate({opacity: 1}, {duration: fadeDelay, queue: true}, 'easeOutQuint');
}
function clearOverlay(bool) {
var fadeDelay = 1000;
var fadeDuration = 400;
var animOpacityPromise;
if (bool === true) {
fadeDelay = 0;
fadeDuration = 200;
}
overlayIsFadingOut = true;
fadeOutTimeOut = setTimeout(function() {
console.log('clearOverlay setTimeout called');
animOpacityPromise = $.when(overlay.animate(
{opacity: 0},
{
duration: fadeDuration,
queue: true,
start: function() {
console.log('Fade out started.');
},
done: function() {
console.log('Fade out done. Resolving promise.');
animOpacityPromiseCtrl.resolve();
}
},
'easeOutQuint').promise(), animOpacityPromiseCtrl);
animOpacityPromise.done(function() {
console.log('clearOverlay animate promise completed');
overlay.css({'visibility': 'hidden'});
searchString = '';
$('#searchOverlay span').html('');
});
animOpacityPromise.always(function() {
console.log('clearOverlay animate promise always');
overlayIsFadingOut = false;
});
}, fadeDelay);
}
function addChar(char) {
searchString = searchString + String.fromCharCode(char.which);
console.log('Character "' + String.fromCharCode(char.which) + '" added to searchString. searchString is now "' + searchString + '"');
$('#searchOverlay span').append(String.fromCharCode(char.which));
}
function removeChar() {
searchString = searchString.substring(0, searchString.length - 1);
$('#searchOverlay span').text(function(iter, txt) {
return txt.slice(0, -1);
});
}
$(window).keydown(function(key) {
//If it's not an alphabetical character or the backspace key.
if (!(key.which > 64 && key.which < 91) && key.which != 8) {
} else {
showOverlay();
clearOverlay();
if (key.which == 8) {
removeChar();
} else if (searchString.length <= 20) {
addChar(key);
key.preventDefault();
} else {
return false;
}
}
});
overlay.click(function() {
clearOverlay(true);
});
}
错误在于它一直重复使用同一个promise对象。因此,每次调用clearOverlay
时,我都会将animOpacityPromiseCtrl
分配给一个新的延迟对象,它就解决了这个问题。
更新了JSFiddle。
相关文章:
- 节点.js“已调用回调”.但是没有任何其他回调
- FireFox webrtc createoffer,没有任何回调调用
- 从Node.js查询Neo4j时看不到任何回调
- jQuery,在任何请求之前对 ajax 请求的默认回调
- 任何使JavaScript中的嵌套回调代码更具可读性的方法
- GreaseMonkey 和 JQuery AJAX 响应不会以任何形式在回调中幸存下来
- jQuery函数在回调时不返回任何内容
- 为什么任何对象原型都不用作 forEach 回调
- 关闭离子侧菜单时是否有任何回调
- 异步函数的 JavaScript 回调:是否有任何模式可以区分“返回值”和“异常”
- 组合多个回调的任何更好方法
- 我可以将 $(this) 传递给 .getJSON 回调函数吗?任何解决方法
- 我无法在jQuery绑定的回调函数中返回任何内容
- 任何jQuery“;打字机”;支持换行+回调函数的插件
- 将回调函数从任何子框架传递到顶部窗口的最有效方法
- 在任何ajax回调中出现运行时错误后,ajaxStop事件停止激发
- 回调函数不返回任何东西
- 没有收到ajax调用的任何回调
- 是否有任何回调函数上传图像插件CKEditor
- 在ready回调或类似的东西上有任何引导旋转木马吗?