[英]callback function inside click event
當用戶使用jQuery單擊按鈕時,我想一個接一個地調用一個函數。 我在click事件中使用了回調函數,如下所示:
$(document).ready(function() {
var form = $('form');
function scaleUp(callback){
var pageWidth = $('.container').width();
var formWidth = form.width();
var scaleX = pageWidth*.8 / formWidth;
var scaleamount;
if (pageWidth * .8 < 1200){
scaleamount = 1.2;
}else if(pageWidth * .8 < 1900){
scaleamount = 1.8;
}
else{
scaleamount = 2;
}
var scaleY = scaleX / scaleamount;
form.attr('style', 'transform:scale(' + scaleX + ',' + scaleY + ');transition : transform 1.5s ease;'
);
return true;
};
function getPos(){
var formTop = form.position().top;
var formLeft = form.position().left;
console.log(formLeft);
};
$('.button').click(function(){
scaleUp(getPos());
});
});
但是,在轉換表單后,我總是得到舊的位置值,而不是新的位置值。 有任何想法嗎?
JSfiddle: https ://jsfiddle.net/k3j910ny/1/
常規的ol'回調將不起作用,因為CSS轉換是異步的。
舊的答案使用jQuery Promise。 但是,有一個事件稱為transitionend
,您可以將其添加到表單中。 基本上,當CSS過渡完成時,它甚至會發出一個transitionend
。 然后,當轉換結束時,表單可以調用getPos
。 這比使用jQuery Promise好得多。
var form = $('form');
console.log("The old left pos is:" + form.position().left);
function scaleUp() {
var pageWidth = $('.container').width();
var formWidth = form.width();
var scaleX = pageWidth * 0.8 / formWidth;
var scaleamount;
if (pageWidth * 0.8 < 1200) {
scaleamount = 1.2;
} else if (pageWidth * 0.8 < 1900) {
scaleamount = 1.8;
} else {
scaleamount = 2;
}
var scaleY = scaleX / scaleamount;
form.attr('style', 'transform:scale(' + scaleX + ',' + scaleY + ');transition : transform 1.5s ease;');
}
form.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function(e) {
if(e.originalEvent.propertyName.toLowerCase() === 'transform') {
return getPos();
}
});
function getPos() {
var formTop = form.position().top;
var formLeft = form.position().left;
console.log("The new left pos is:" + form.position().left);
}
$('button').on('click', scaleUp);
看到這個jsfiddle 。 它使用jQuery Promise:
var form = $('form');
console.log("The old left pos is:" + form.position().left);
function scaleUp() {
var deferred = $.Deferred();
var pageWidth = $('.container').width();
var formWidth = form.width();
var scaleX = pageWidth * 0.8 / formWidth;
var scaleamount;
if (pageWidth * 0.8 < 1200) {
scaleamount = 1.2;
} else if (pageWidth * 0.8 < 1900) {
scaleamount = 1.8;
} else {
scaleamount = 2;
}
var scaleY = scaleX / scaleamount;
form.attr('style', 'transform:scale(' + scaleX + ',' + scaleY + ');transition : transform 1.5s ease;');
setTimeout(function() {
deferred.resolve();
}, 1600); // needs to wait for the animation to complete
return deferred.promise()
}
function getPos() {
var formTop = form.position().top;
var formLeft = form.position().left;
console.log("The new left pos is:" + form.position().left);
}
$('button').on('click', function () {
$.when(scaleUp()).then(getPos);
});
動畫是異步發生的,因此有一個setTimeout
可以在動畫完成后稍微解決一個諾言。 承諾解決后,調用getPos
$.when
getPos
。 這有點駭人聽聞,但這是因為更改style
屬性並為其提供CSS動畫的異步特性。
換句話說,由於動畫是異步的,因此您需要等待動畫結束才能調用回調並獲得新位置。 承諾等待異步事件完成,然后調用回調。
如果您不熟悉諾言,建議您閱讀有關該主題的jQuery文檔 ,並在Google上搜索“ javascript諾言”。 這是另一個主題。
您將函數的被調用版本作為回調傳遞(並且在scaleUp
甚至從未使用過該回調),因此它不會將回調視為函數引用。
做這個:
function scaleUp(callback) {
// all your code... then
return callback(); // or just callback() without the return
}
$('.button').on('click', scaleUp.bind(null, getPos));
如果傳遞getPos()
,則傳遞的是getPos
的返回值 ,而不是函數引用本身。 順便說一下,上述點擊處理程序是縮寫。 您也可以這樣做:
$('button').on('click', function() {
scaleUp(getPos);
});
您沒有使用回調。 你打電話getPos()
第一 ,它的結果傳遞給scaleUp
。 然后,在scaleUp
您實際上並沒有為該結果做任何事情 。
如果要使其成為回調,只需傳遞函數引用即可:
scaleUp(getPos);
然后,在scaleUp
,調用函數:
calllback();
當然,由於您不執行任何異步操作,因此您無需執行所有操作。 擴展后只需調用該函數即可:
scaleUp();
getPos();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.