click事件中的回调函数

时间:2015-06-18 16:24:14

标签: javascript jquery

当用户使用jQuery单击按钮时,我想要一个接一个地调用一个函数。我在点击事件中使用了一个回调函数,如下所示:

$(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/

2 个答案:

答案 0 :(得分:1)

更好的答案

常规的ol'回调不起作用,因为CSS转换是异步的。

旧答案使用jQuery承诺。但是,有一个名为transitionend的事件可以添加到表单中。基本上,当CSS转换完成时,它会发出transitionend偶数。然后,当转换结束时,表单可以调用getPos。这比使用jQuery promise更好。

Newest jsfiddle

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承诺:

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可以在动画完成后稍微解析一个承诺。一旦承诺解决,$.when就会调用getPos。这有点像hacky,但这是因为改变style属性并给它一个CSS动画的异步性。

换句话说,因为动画是异步的,所以在调用回调并获得新位置之前,需要等待它完成。 Promise等待异步事件完成,然后调用回调。

如果您不熟悉承诺,我建议您阅读有关该主题的jQuery docs,并在Google上搜索“javascript promises”。这是另一个主题。

原始答案

您将函数的被调用版本作为回调传递(并且在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);
});

答案 1 :(得分:1)

你没有使用回调。您首先调用getPos() 并将结果传递给scaleUp。然后在scaleUp内,您实际上并没有使用该结果执行任何操作

如果您希望它成为回调,只需传递函数参考:

scaleUp(getPos);

然后,在scaleUp内,调用函数:

calllback();

当然,由于你没有做任何异步事情,你不需要做所有这些。只需在进行缩放后调用函数

scaleUp();
getPos();