我正在使用以下jQuery代码片段来执行AJAX请求:
$.ajax({
url: page,
context: $(pageContent),
beforeSend: function(){
$(pageContent).css('opacity', '0');
},
success: function(html){
$(pageContent).html(html);
},
complete: function(){
$(pageContent).css('opacity', '1');
}
});
我还设置了CSS3过渡,以便不透明度的变化在0.25秒内淡入和淡出。 期望的结果是(在点击链接后)页面的一部分淡出,然后替换内容,最后该部分再次淡入(显示新内容)。
问题是在淡出过渡完成之前,内容被Ajax答案取代。
如果CSS3转换完成后,您将如何才能启动AJAX请求?
通过不同的线程阅读让我考虑这个解决方案:
box.addEventListener(
'transitionEnd',
function( event ) {
alert( "Finished transition!" ); // here I could launch my Ajax request
}, false );
我可以使用这样的东西只在淡出结束时启动ajax请求,但是:
我还看了一下jQuery的animate函数,但似乎没有使用CSS3过渡。
非常感谢任何帮助
答案 0 :(得分:-1)
如果你愿意放弃jquery animate的转换:
$(pageContent).animate({'opacity': '0'},250,
function(){
$.ajax({
url: page,
context: $(pageContent),
success: function(html){
$(pageContent).html(html);
},
complete: function(){
$(pageContent).animate({'opacity': '1'},250);
}
});
});
没有测试,所以如果语法稍微偏离,抱歉。但是给你的想法。一旦0的不透明度动画完成,就会进行ajax调用。
答案 1 :(得分:-1)
使用css3-transitions创建一些css类,并在成功/错误/完整回调中使用.addClass / removeClass
http://css3.bradshawenterprises.com/transitions/ - 尽管处于初始状态,但转换是可以接受的,这就是为什么你可以完全异步使用它们。
答案 2 :(得分:-1)
我发现$。推迟是解决这个问题的最佳方法。我不太了解它是如何运作的,只是解释了它的好处和解决方案。
这是文档。 http://api.jquery.com/category/deferred-object/ 我发现这是开始使用$ .Deferred的一个很好的资源。 http://www.html5rocks.com/en/tutorials/async/deferred/
所以基本上你想要将CSS3动画与既是异步的ajax请求结合起来。然而你想要使用回调以使效果同步或协调,即在一个新元素中将一些元素淡化为ajax然后淡入它。使用$ .Deferred的优点是你可以更多地协调这些事件#&34;尖端&#34?;办法。而不是淡出然后做一个ajax请求然后淡入,这是好的,但这意味着你必须等待你的动画完成甚至开始请求之前。使用$ .Deferred,您可以执行淡出和触发ajax请求以及完成淡入时的操作。
这是一个工作小提琴。
我将通过下面的js部分发表评论。
//Clicking the anchor triggers the loadContent function
$('a').on('click', function(){
var url = $(this).data('url');
var target = $(this).data('target');
loadContent(url, target);
});
//Slide out the existing element using a css transform
var slideOut = function($el, $target){
//Create a deffered object
var deferred = new $.Deferred();
//Slide our element out (note this has a transition through css) (double note you should use transforms for other browsers
$el.css({"-webkit-transform":"translateX(100%)"}).on('transitionend webkitTransitionEnd', function(e){
//once the transition ends resolve our deferred object and return $target
deferred.resolve($target);
});
//return the promise from the deferred object
return deferred.promise();
};
//Add the element returned from our Ajax request and slide it in
var slideIn = function(el, $target){
var $el = $(el);
$target.empty().append($el).css({height : "auto"});
//weird bug, css transition doesn't work when taken out of setTimeout (any ideas?)
setTimeout(function(){
$el.removeClass('content2');
}, 0);
};
//Make an ajax request and returns some html
//Note ajax requests return promises as well as deferred objects, I am just wrapping it here for clarity
var getData = function(url){
var deferred = new $.Deferred();
//var htmlData = "asdfasfasdf";
$.ajax({
url: url,
method : "POST",
data : { 'html': htmlData},
success: function (returnhtml) {
//resolve our deferred object and return the response
deferred.resolve(returnhtml);
},
error: function (xhr, ajaxOptions, thrownError) {
//you can reject a deferred object and then execute a different callback(s) but i'll let you figure that out
deferred.reject(thrownError);
}
});
//return the promise from the deferred object
return deferred.promise();
}
var loadContent = function(url, target){
$el = $('.content');
$target = $(target);
//Run slideOut and getData
var slidePromise = slideOut($el, $target);
var dataPromise = getData(url);
//So because we are returning promises from deferred objects in both of the above functions the following code will only run once those deferred objects have been resolved
$.when(slidePromise, dataPromise).done(function(slidePromise, dataPromise) {
//Great the ajax request is finished and our slideOut animation has finished, lets slide in the new content passing it the target element and response content
slideIn(dataPromise, slidePromise );
});
};