2015-06-18 3 views
0

Я хочу вызвать функцию за другим, когда пользователь нажимает кнопку с помощью jQuery. Я использовал функцию обратного вызова внутри события щелчка так:callback function in click event

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

+0

Вы не можете использовать функцию обратного вызова и возврата ближе в той же функции и ожидать, что она вести себя должным образом. В этой ситуации вы можете использовать возврат ближе, обратный вызов здесь не требуется, так как стандартный на странице js не является асинхронным. Если вы хотите использовать обратный вызов, вы замените «return true»; с «обратным вызовом (true)». И вызывается scaleUp с "scaleUp (getPost)". В вашем обратном вызове не требуется аргумент или скобки, потому что это подразумевается. – jonode

ответ

1

Лучше Ответ

Регулярного ол»обратный вызов не будет работать, так как CSS переходы являются асинхронными.

Старый ответ, используемый jQuery, обещает. Однако есть событие под названием transitionend, которое вы можете добавить в свою форму. В принципе, когда переход CSS заканчивается, он испускает только transitionend. Затем форма может называть getPos, когда переход завершается. Это намного лучше, чем использование обещаний jQuery.

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. Это хакеры, но из-за асинхронного характера изменения атрибута style и предоставления ему анимации CSS.

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

Если вы не знакомы с обещаниями, я бы предложил прочитать jQuery docs по этой теме, а также выполнить поиск «javascript-обещаний» в Google. Это совсем другой предмет.

Оригинала ответ

Вы переходящие в вызываемой версии функции как обратный вызов (и в 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); 
}); 
+0

спасибо, Джош! Я добавил callback(); до конца моей функции scaleUp и изменил scaleUp (getPos()) на scaleUp (getPos), но все еще получаю старое значение :( – bunnyHat

+0

@bunnyHat, нет проблем. Извините, у вас все еще есть проблемы. Не могли бы вы сделать jsfiddle Таким образом, нам будет легче увидеть, что происходит и как это исправить. –

+1

Уверен, я делаю это прямо сейчас. – bunnyHat

1

Вы не используете обратный вызов.Вы звоните getPos()сперва и передаете его результат на scaleUp. Затем в пределах scaleUp вы на самом деле не ничего не делаете с этим результатом.

Если вы хотите быть обратный вызов, просто передать ссылку на функцию:

scaleUp(getPos); 

Затем в scaleUp, вызовите функцию:

calllback(); 

Конечно, так как вы не делая что-то асинхронное, вам не нужно все это делать. Просто вызвать функцию после вы делаете вашу масштабирование:

scaleUp(); 
getPos();