如何让jQuery toggle执行完成后再运行其他函数?
解决jQuery Toggle动画完成后再执行方法的问题
这个问题的核心在于jQuery的toggle("slow")是异步执行的动画——它会立刻返回,而动画在后台运行,所以你的changeText()会在动画还没完成、DOM状态还没更新的时候就执行了,自然拿不到正确的:hidden状态。不用setTimeout也能完美解决,下面给你两种靠谱的方案:
方案1:利用jQuery动画的回调参数(传统写法)
jQuery的toggle方法本身支持传入动画完成后的回调函数,我们可以把后续逻辑放在这个回调里,或者串联多个动画的回调:
首先修改你的方法,让它们支持接收回调:
const toggleContainer = function(onComplete) { // 把回调传给toggle,动画结束时触发 addAnswerContainer.toggle("slow", onComplete); }; const toggleButtons = function(onComplete) { // 同时执行两个按钮的toggle,用$.when等待两者都完成后触发回调 $.when( submitAnswerBtn.toggle("slow"), cancelAnswerBtn.toggle("slow") ).done(onComplete); }; const changeText = function() { if( addAnswerContainer.is(":hidden") ) { addOwnAnswerBtn.text("Add your own answer" ); } else { addOwnAnswerBtn.text("Hide adding answer" ); } };
然后修改toggleUI,把changeText作为最终回调传入:
const toggleUI = function() { // 先执行容器动画,完成后执行按钮动画,最后执行文本切换 toggleContainer(() => { toggleButtons(changeText); }); // 如果希望容器和按钮动画同时执行,等两者都完成再切换文本,可以这样写: // $.when(toggleContainer(), toggleButtons()).done(changeText); };
方案2:用Promise + Async/Await(现代写法)
如果你更喜欢现代JS的异步写法,可以把每个动画操作包装成Promise,然后用async/await等待所有动画完成:
// 把toggle包装成Promise,动画完成时resolve const toggleContainer = function() { return new Promise(resolve => { addAnswerContainer.toggle("slow", resolve); }); }; // 同时处理两个按钮的toggle,用Promise.all等待两者完成 const toggleButtons = function() { return Promise.all([ new Promise(resolve => submitAnswerBtn.toggle("slow", resolve)), new Promise(resolve => cancelAnswerBtn.toggle("slow", resolve)) ]); }; const changeText = function() { if( addAnswerContainer.is(":hidden") ) { addOwnAnswerBtn.text("Add your own answer" ); } else { addOwnAnswerBtn.text("Hide adding answer" ); } }; // 用async标记异步函数,await等待所有动画完成 const toggleUI = async function() { // 并行执行容器和按钮的动画 await Promise.all([toggleContainer(), toggleButtons()]); // 所有动画完成后,再执行文本切换 changeText(); };
为什么你之前的回调/Promise没生效?
大概率是你没有正确把回调和toggle方法关联起来——比如原来的toggleContainer没有返回jQuery的Deferred对象(toggle方法本身会返回一个Deferred),也没有把回调传给toggle的第二个参数,导致后续逻辑无法监听动画完成事件。上面的两种方案都解决了这个问题,任选其一即可。
内容的提问来源于stack exchange,提问作者Maksim Dimitrov
相关产品推荐
相关产品推荐

