Как использовать обратные вызовы CSS3 перехода с jQuery.ajax - PullRequest
2 голосов
/ 06 мая 2011

Я использую следующий фрагмент кода 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 до завершения перехода с затуханием.

Что бы вы сделали, чтобы запрос AJAX запускался только после завершения перехода CSS3?


Чтение различных потоков заставило меня задуматься над этим решением:

box.addEventListener( 
     'transitionEnd', 
     function( event ) { 
         alert( "Finished transition!" ); // here I could launch my Ajax request
     }, false );

Я мог бы использовать что-то подобное для запуска запроса ajax только после завершения затухания, но:

  • это включает в себя работу с первым переходом вне метода $ .ajax (таким образом удаляя метод beforeSend)
  • Я не знаю, как слушать только при переходах непрозрачности
  • Для меня не имеет смысла, что ajax-запрос инициируется переходом, так как в данный момент он запускается нажатием на ссылку.

Я также посмотрел на анимированную функцию jQuery, но, похоже, она не использует переходы CSS3.

Любая помощь будет высоко ценится

Ответы [ 3 ]

0 голосов
/ 16 августа 2011

Создайте несколько классов css с помощью css3-переходов и используйте .addClass / removeClass при обратных / успешных / ошибочных / полных обратных вызовах

http://css3.bradshawenterprises.com/transitions/ - переходы приемлемы, несмотря на начальное состояние, поэтому вы можете использовать их полностью асинхронно.

0 голосов
/ 28 марта 2014

Я нашел $. Отложенный, чтобы быть лучшим подходом к решению этой проблемы.Я не буду вдаваться в подробности того, как это работает, а просто объясню преимущества и решение.

Вот документация.http://api.jquery.com/category/deferred-object/ Я обнаружил, что это отличный ресурс для начала работы с $ .Deferred.http://www.html5rocks.com/en/tutorials/async/deferred/

Таким образом, в основном вы хотите объединить CSS3-анимацию с ajax-запросами, которые являются асинхронными.Тем не менее, вы хотите использовать обратные вызовы, чтобы эффект был синхронным или скоординированным, то есть затухание некоторого элемента ajax в новом элементе на его месте, а затем затухание. Преимущество использования $ .Deferred заключается в том, что вы можете координировать эти события в более«сложные?»путь.Вместо того, чтобы исчезать, затем выполните ajax-запрос, а затем - постепенный, что нормально, но это означает, что вам нужно дождаться окончания анимации, прежде чем даже начинать запрос.С $ .Deferred вы можете делать что-то вроде исчезновения и запускать запрос ajax, а когда они оба заканчивают, появляются.

Вот рабочая скрипка.

http://jsfiddle.net/SB987/1/

Я прокомментирую часть 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 );
    });
};
0 голосов
/ 06 мая 2011

Если вы готовы отказаться от переходов для 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);
          }
      });
   });

Не проверял, так что если синтаксис немного отключен, извините. Дает вам идею, хотя. Вызов ajax выполняется, когда заканчивается анимация до 0.

...