简体   繁体   中英

jQuery animation bug: repeating

I'm working on a landing page for my web app, and I'm using some sort of modal boxes I built. It uses some jQuery to display the box itself and the overlay. There are 3 modal boxes on the same page that you can open with one link for each box.

My code works really well (even though it seems heavy [I'm not a pro in Javascript but I always give a try as much as I can]). But when I close the modal box, the overlay slides out as it's supposed to do but the animation repeats 3 times (probably because of the code for the 3 modal box).

So, my code is fully online there → http://graphix.net23.net/app/

Here's the jsFiddle for you to play :) → http://jsfiddle.net/EY59T/ (the bug isn't really visible, you can only see the overlay takes a while to get away)

I already tried the .stop() function. It solves the problem when you display the first modal, but after when you click on another modal, the overlay doesn't come.

Look at my heavy code:

// iOS Modal
$("a#modal-open").click(function () {
      $("div#modal-ios").show("fade", 600);
      $("div.modal-overlay").show("slide", 300);
      $(".app h4").hide("fade", 300);
      $("div.app").animate({backgroundPositionY:-120}, 600);
      return false;
});
$("a#modal-done,div.modal-overlay").click(function () {
      $("div#modal-ios").hide("fade", 600);
      $("div.modal-overlay").hide("slide", 300);
      $(".app h4").show("fade", 600);
      $("div.app").animate({backgroundPositionY:0}, 600);
      return false;
});
$( document ).on( 'keydown', function ( e ) {
    if ( e.keyCode === 27 ) {
        $("div#modal-ios,div.modal-overlay").hide("fade", 300);
        $(".app h4").show("fade", 300);
        $("div.app").animate({backgroundPositionY:0}, 600);
    }
});
// END iOS Modal
// Android Modal
$("a#modal-open-android").click(function () {
      $("div#modal-android").show("fade", 600);
      $("div.modal-overlay").show("slide", 300);
      return false;
});
$("a#modal-done,div.modal-overlay").click(function () {
      $("div#modal-android").hide("fade", 600);
      $("div.modal-overlay").hide("slide", 300);
      return false;
});
$( document ).on( 'keydown', function ( e ) {
    if ( e.keyCode === 27 ) {
        $("div#modal-android,div.modal-overlay").hide("fade", 300);
    }
});
// END Android Modal
// WP Modal
$("a#modal-open-wp").click(function () {
      $("div#modal-wp").show("fade", 600);
      $("div.modal-overlay").show("slide", 300);
      return false;
});
$("a#modal-done,div.modal-overlay").click(function () {
      $("div#modal-wp").hide("fade", 600);
      $("div.modal-overlay").hide("slide", 300);
      return false;
});
$( document ).on( 'keydown', function ( e ) {
    if ( e.keyCode === 27 ) {
        $("div#modal-wp,div.modal-overlay").hide("fade", 300);
    }
});
// END WP Modal​

It's been two days I'm working on it and still can't find a working solution, help me please :)

EDIT: you can close the modal with three different ways: click on button, click on overlay or ESC key. Note that the bug doesn't happen with the ESC key.

This is happening because you are hiding the overlay 3 times (once per platform [iOS, Android, WP])

Your code needs some cleaning. You've used multiple elements on the page with the same id (eg #modal-close) which is not valid, not sure if there are other instances. What I would try to do here is create and object per platform, index everything at the start and run from there.

However you could just modify what you got but adding a hiding function. I've mocked it up here: http://jsfiddle.net/3sz2u/1/

I've changed the a#modal-close to a.modal-close

Hope this helps! Only tested on Chrome


NOTE : the jsFiddle you created doesn't show the same effect becuase of the version you are using. Switch it to jQuery 1.7.2 and you'll see it :)

The problem is that you are binding the closing handlers three times one for each type of model you open. but you bind those on the same elements a#modal-done,div.modal-overlay . This way when you click on it, it starts 3 fades on the same elements and that messes it up.

You need to apply the handler only once, and just add the fading of all popups in there..

Also by adding a common class to your links that are for opening the popups, you can target those in a single pass as well

These will simplify your code to

// method to hide any open popup and the overlay
function closePopupOverlay() {
    // hide all popups - will only really work with the currently open one
    $("#modal-ios,#modal-wp,#modal-android,div.modal-overlay").hide("fade", 500);

    $(".app h4").show("fade", 500);
    $("div.app").animate({
        backgroundPositionY: 0
    }, 600);
}
$(document).on('keydown', function(e) {
    if (e.keyCode === 27) {
        closePopupOverlay();
    }
});
$("a#modal-done,div.modal-overlay").click(function() {
    closePopupOverlay();
    return false;
});
// when we click on one of the links 
$('.model-open').click(function() {
    var target = this.id.replace('-open-', '-'); // find the related popup id
    $('#' + target).show("fade", 600); // show the related popup
    $("div.modal-overlay").show("slide", 300); // show the overlay

    if (target === 'modal-ios') { // handle the special needs of the ios button
        $(".app h4").hide("fade", 300);
        $("div.app").animate({
            backgroundPositionY: -120
        }, 600);
    }

    return false;
});

The html change is that i added class="model-open" to your 3 links and also changed the id for the ios link to modal-open-ios to conform with the other two, so we can easily extract what popup we want to open..

Demo at http://jsfiddle.net/EY59T/1/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM