2015-10-13 3 views
1

В соответствии с jQuery documentationимеет параметр «Complete», который должен срабатывать только после завершения анимации. К сожалению, я обнаружил, что он запускает до, анимация даже началась.jQuery оживить «завершение» обратного вызова слишком быстро

if ($('html').scrollTop()) { 
    $('html').animate({ scrollTop: 0 }, callback); 
    return; 
} 

JSFiddle показывает проблему: http://jsfiddle.net/JohnnyWalkerDesign/5zu90ygz/

Что я упускаю?

ответ

3

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

Параметр callback должен быть function pointer. Это не термин, который используется очень часто в наши дни, но это означает, что вы передаете функцию непосредственно, а не результат функции.

Что это значит?

Учитывая пример:

function message(q) { 
    alert(q); 
} 

Здесь message функция. Чтобы передать эту функцию в качестве callback, используйте имя функции, например:

setTimeout (message, 100); $ ("# id"). Click (message);

Обратите внимание, что нет () после имени функции.

В javascript терминах сама функция является переменной, и вы передаете переменную, но как только вы добавляете (), вы вызываете функцию и передаете результат, а не сама функция.

Если вы используете message(), то функция будет выполнена и результат функции переданного в качестве callback, а именно:

setTimeout(message("x"), 100); 

является эквивалентом:

var x = message("x"); 
setTimeout(x, 100); 

Так вы может видеть из этого кода, почему сообщение запускается немедленно (более очевидно с событием клика или более длинным таймаутом).

Формат setTimeout(message, 100); не используется очень часто, так как он выглядит как опечатка (должен быть message()?) И b) он не позволяет вам передавать параметр, поэтому это часто записывается как:

setTimeout(function() { message("x") }, 100); 

который использует анонимные в линии функции как/указатель функции callback переменных.


Назад вопрос:

В вашем original fiddle, все, что вам нужно сделать, это изменить callback к истинному callback без необходимости добавления отдельного параметра, а именно:

$('#scroll').on('click', function(e) { 
    e.preventDefault; 
    scrollToTop(function() { message("Reached Top")}); 
}); 

Обновлена ​​скрипка: http://jsfiddle.net/5zu90ygz/9/

+0

Спасибо. Я знал, что есть некоторые проблемы с другим решением. Были вещи, которые были изменены без причины, и упоминания о проблемах, которые не были проблемой вообще. Я поражен тем, что у меня так много аплодисментов, чтобы быть честным (хотя в конце концов он оказался в достаточно хорошем состоянии). Ваше объяснение идеально и очень полезно. –

6

Вы вызываете функцию message при регистрации в качестве обратного вызова в заявлении scrollToTop(message('Reached Top'));. Здесь вызывается функция message, и возвращаемое значение будет передано функции scrollToTop.

Updated Fiddle

Вы можете передать дополнительный параметр функции scrollToTop то есть сообщение, которое будет отображаться, а затем это сообщение может быть перенаправлен в функции message после анимации завершается.

// Scroll to the top and fire callback 
 
function scrollToTop(callback, message) { 
 
    // Send the message as the second parameter 
 

 
    if ($('html').scrollTop()) { 
 
    $('html').animate({ 
 
     scrollTop: 0 
 
    }, function() { 
 
     // Call the callback function with the message as param after completion of animate 
 
     callback(message) 
 
    }); 
 
    return; 
 
    } 
 

 
    if ($('body').scrollTop()) { 
 
    $('body').animate({ 
 
     scrollTop: 0 
 
    }, function() { 
 
     // Call the callback function with the message as param after completion of animate 
 
     callback(message) 
 
    }); 
 
    return; 
 
    } 
 

 
    callback(message); 
 
} 
 

 
// Dummy callback function to fire 
 
function message(q) { 
 
    alert(q); 
 
} 
 

 
// On click event 
 
$('#scroll').on('click', function(e) { 
 
    e.preventDefault; 
 
    
 
    // Add message as second parameter 
 
    scrollToTop(message, "Reached Top! Yay!"); 
 
});
div { 
 
    width: 100%; 
 
    border: 1px solid black; 
 
    height: 200px; 
 
    margin: 10px 0; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<a href="#" id="scroll">Scroll to top</a>

+0

Вы больше не передаете параметр функции обратного вызова. Это не помогает мне :(Кроме того, 'message()' НЕ вызывается 'scrollToTop()' - прочитал ли вы код с кодом? Это резервная версия, если браузер уже находится в верхней части экрана. –

+0

@ Chuck Пожалуйста, проверьте обновленную скрипту в нижней части ответа. – Tushar

+0

Вы можете использовать 'bind', если хотите передать сообщение в качестве аргумента' scrollToTop'. –

Смежные вопросы