功能完成时执行代码

时间:2022-01-13 03:35:39

I have a function in my code that animates several elements. What I'm wanting to do is execute a sequence of code but only after this function has completed.

我的代码中有一个函数可以激活几个元素。我想要做的是执行一系列代码,但只有在此功能完成后才能执行。

Say for example I had this:

比方说,我有这个:

executeMyAnimationFunction();

// Execute this code AFTER executeMyAnimationFunction() has completed
alert('test');

So far I've tried using setTimeout but this doesn't seem to be very reliable. I've also tried using .promise() but this doesn't seem to execute properly either:

到目前为止,我已尝试使用setTimeout,但这似乎不太可靠。我也尝试过使用.promise(),但这似乎也没有正确执行:

$(executeMyAnimationFunction()).promise().done(function () {
    alert('test');
});

However I admit I be using it incorrectly. In the demo on the jquery site, it seems promise() is being used on the elements that are being animated. I tried doing it like this:

但是我承认我错误地使用它。在jquery站点的演示中,似乎promise()正在被动画化的元素上使用。我尝试这样做:

$('#myAnimatedElement').promise().done(function () {
    alert('test');
});

and it seemed to work in certain scenarios but in others it didn't work. I wonder if this is a reliable way of using promise()?

它似乎在某些情况下起作用,但在其他情况下它不起作用。我想知道这是否是使用promise()的可靠方式?

Basically I'm stuck now with how I can do this. All I want to do is wait until a function has fully executed (the function simply animates a group of elements) and then continue with the execution of my code.

基本上我现在已经陷入了如何做到这一点。我想要做的就是等到一个函数完全执行(该函数只是动画一组元素),然后继续执行我的代码。

Is there a simple way of doing this using jquery/javascript that I'm missing?

有没有一种简单的方法使用我缺少的jquery / javascript来做到这一点?

Thanks

EDIT: To show my problem in a little more detail, here is the exact code I'm using:

编辑:为了更详细地显示我的问题,这里是我正在使用的确切代码:

<script>
        $(function () {

            $(window).bind('hashchange', function (e) {
                if ($(':animated').length) {
                    return false;
                }

                var section = $.param.fragment();
                var current = $('#content').children(':visible').attr('id');

                $('a').removeClass('active');                

                // If this is the first load of the page, then animate in the initial content
                if (section === '') {                    
                    if (current === 'reception') {
                        animateContentIn("reception");                        
                    }
                    else {                        
                        $('a[href="#' + section + '"]').addClass('active');

                        // Animate out existing content
                        animateContentOut(current);

                        setTimeout(function () {
                            animateContentIn("reception");
                        }, 1000);
                    }
                }
                else {
                    // Otherwise find the current page content and animate out
                    animateContentOut(current);

                    setTimeout(function () {
                        animateContentIn(section);
                    }, 1000);
                }               
            })

            // Since the event is only triggered when the hash changes, we need to trigger
            // the event now, to handle the hash the page may have loaded with.
            $(window).trigger('hashchange');
        });       

        function animateContentIn(activePage) { 
            // Now animate in the new content
            switch (activePage) {
                case "floorspace":
                    animateFloorspaceElementsIn();
                    break;
                case "reception":
                    animateReceptionElementsIn();
                    break;
            }
        }

        function animateContentOut(currentPage) {
            // Now animate in the new content
            switch (currentPage) {
                case "floorspace":                    
                    animateFloorspaceElementsOut();
                    break;
                case "reception":
                    animateReceptionElementsOut();
                    break;
            }
        }

        function animateReceptionElementsIn() {
            $('#reception').show();

            $('#reception .title').animate({
                bottom: 520
            }, 400);

            $('#reception .tile1').animate({
                bottom: 504
            }, 600);

            $('#reception .tile2').animate({
                bottom: 504
            }, 700);

            $('#reception .hero').animate({
                bottom: 40
            }, 1000);

            $('#reception .content1').animate({
                bottom: 8
            }, 400);

            $('#reception .content2').animate({
                bottom: 8
            }, 500);
        }

        function animateReceptionElementsOut() {
            $('#reception .title').animate({
                bottom: -56
            }, 400);

            $('#reception .tile1').animate({
                bottom: -136
            }, 600);

            $('#reception .tile2').animate({
                bottom: -152
            }, 700);

            $('#reception .hero').animate({
                bottom: -464
            }, 1000, function () {
                $('#reception').hide();
            });

            $('#reception .content1').animate({
                bottom: -112
            }, 400);

            $('#reception .content2').animate({
                bottom: -104
            }, 500);
        }

        function animateFloorspaceElementsIn() {
            $('#floorspace').show();

            $('#floorspace .title').animate({
                bottom: 520
            }, 400);

            $('#floorspace .tile1').animate({
                bottom: 504
            }, 600);

            $('#floorspace .tile2').animate({
                bottom: 504
            }, 700);

            $('#floorspace .hero').animate({
                bottom: 40
            }, 1000);

            $('#floorspace .content1').animate({
                bottom: 8
            }, 400);

            $('#floorspace .content2').animate({
                bottom: 8
            }, 500);
        }

        function animateFloorspaceElementsOut() {
            $('#floorspace .title').animate({
                bottom: -56
            }, 400);

            $('#floorspace .tile1').animate({
                bottom: -136
            }, 600);

            $('#floorspace .tile2').animate({
                bottom: -152
            }, 700);

            $('#floorspace .hero').animate({
                bottom: -464
            }, 1000, function () {
                $('#floorspace').hide();
            });

            $('#floorspace .content1').animate({
                bottom: -112
            }, 400);

            $('#floorspace .content2').animate({
                bottom: -104
            }, 500);
        }
    </script>
</head>
<body>
    <div id="vert-wrapper">
        <div id="wrapper">
            <aside id="sidebar">
                <nav id="navigation">
                    <ul>
                        <li><a href="#">Building</a></li>
                        <li><a href="#reception">Reception</a></li>
                        <li><a href="#floorspace">Floor Space</a></li>
                        <li><a href="#">Views</a></li>
                        <li><a href="#">Terraces</a></li>
                        <li><a href="#">Profile</a></li>
                    </ul>
                    <ul>
                        <li><a href="#">Specification</a></li>
                        <li><a href="#">Plans</a></li>
                        <li><a href="#">Location</a></li>
                        <li><a href="#">Ten Storeys</a></li>
                        <li><a href="#">Gallery</a></li>
                        <li><a href="#">Contact</a></li>
                    </ul>
                </nav>
            </aside>  
            <div id="content">
                <article id="reception">
                    <h1 class="title">
                        <img src="/images/reception/title.png" alt="Edge" />
                    </h1>
                    <img src="/images/reception/1.jpg" alt="" class="tile1" />
                    <img src="/images/reception/2.jpg" alt="" class="tile2" />
                    <img src="/images/reception/hero.jpg" alt="" class="hero" />
                    <img src="/images/reception/content1.jpg" alt="" class="content1" />
                    <img src="/images/reception/content2.jpg" alt="" class="content2" />
                </article>
                <article id="floorspace">
                    <h1 class="title">
                        <img src="/images/floorspace/title.png" alt="Space" />
                    </h1>
                    <img src="/images/floorspace/1.jpg" alt="" class="tile1" />
                    <img src="/images/floorspace/2.jpg" alt="" class="tile2" />
                    <img src="/images/floorspace/hero.jpg" alt="" class="hero" />
                    <img src="/images/floorspace/content1.jpg" alt="" class="content1" />
                    <img src="/images/floorspace/content2.jpg" alt="" class="content2" />
                </article>
            </div>          
        </div>
    </div>
</body>

Now the code I have above does work, however I don't feel it's very clean nor does it seem to execute correctly 100% of the time.

现在我上面的代码确实可以工作,但我觉得它不是很干净,也不是100%的时间都能正确执行。

Basically the dilemma I have is I want to be able to execute animateContentIn() after animateContentOut() has finished. The only way I've managed to do this is to delay the animateContentIn() function by the time it takes to do the longest animation - in this case it's 1000ms.

基本上我遇到的困境是我希望能够在animateContentOut()完成后执行animateContentIn()。我设法做到这一点的唯一方法是将animateContentIn()函数延迟到执行最长动画所需的时间 - 在这种情况下它是1000ms。

Isn't there a tidier, more efficient way of writing this??

是不是有更整洁,更有效的写作方式?

3 个解决方案

#1


3  

function someRandomFunction(){
    // This will be executed after myFirstFunction
}

function myFirstFunction(callbackFunction){
    // Do some stuff
    alert(1);
    // Do something slow here

    // Callback when done:
    callbackFunction(some, input);
}
// Usage:
myFirstFunction( someRandomFunction ); // with existing function
myFirstFunction( function(){ alert(1);} ); // anonymous

Note: You can use anonymous functions
Small Demo: http://jsfiddle.net/zcp82/2/

注意:您可以使用匿名函数Small Demo:http://jsfiddle.net/zcp82/2/

Another topic with good info: Create a custom callback in JavaScript

另一个有良好信息的主题:在JavaScript中创建自定义回调

#2


2  

Use a callback?

使用回调?

function executeMyAnimationFunction(complete){
    $('div').animate({ height: '1px' }, 500, complete);
}

Call it like this:

这样叫:

executeMyAnimationFunction(function(){
    console.log('animation complete');
});

Or if you insist on using promises:

或者如果你坚持使用承诺:

executeMyAnimationFunction(){
    var dfd = $.deferred();

    $('div').animate({ height: '1px' }, 500, function(){
        dfd.resolve();
    });

    return dfd.promise();
}

executeMyAnimationFunction().done(function(){
    console.log('animation complete');
});

#3


0  

Please refer Old Post

请参考Old Post

This seem like duplicate question, if you call multiple function it will call in sequence only

这似乎是重复的问题,如果你调用多个函数,它将只按顺序调用

#1


3  

function someRandomFunction(){
    // This will be executed after myFirstFunction
}

function myFirstFunction(callbackFunction){
    // Do some stuff
    alert(1);
    // Do something slow here

    // Callback when done:
    callbackFunction(some, input);
}
// Usage:
myFirstFunction( someRandomFunction ); // with existing function
myFirstFunction( function(){ alert(1);} ); // anonymous

Note: You can use anonymous functions
Small Demo: http://jsfiddle.net/zcp82/2/

注意:您可以使用匿名函数Small Demo:http://jsfiddle.net/zcp82/2/

Another topic with good info: Create a custom callback in JavaScript

另一个有良好信息的主题:在JavaScript中创建自定义回调

#2


2  

Use a callback?

使用回调?

function executeMyAnimationFunction(complete){
    $('div').animate({ height: '1px' }, 500, complete);
}

Call it like this:

这样叫:

executeMyAnimationFunction(function(){
    console.log('animation complete');
});

Or if you insist on using promises:

或者如果你坚持使用承诺:

executeMyAnimationFunction(){
    var dfd = $.deferred();

    $('div').animate({ height: '1px' }, 500, function(){
        dfd.resolve();
    });

    return dfd.promise();
}

executeMyAnimationFunction().done(function(){
    console.log('animation complete');
});

#3


0  

Please refer Old Post

请参考Old Post

This seem like duplicate question, if you call multiple function it will call in sequence only

这似乎是重复的问题,如果你调用多个函数,它将只按顺序调用