2

I am having a problem with an image not loading fast enough on mobile. My project has an image and a button. When the button is clicked, the image slides downwards and another image slides from the top to replace it. Here is the code

html

 <div class="main">

    <div id="myDiv1><img src="img1.jpg" width="100%"></div>
    <div id="myDiv2"></div>

</div>

css

.moveFromTop {
    animation: moveFromTop 2s ease both;
}

.moveToBottom {
    animation: moveToBottom 2s ease both;
}

@keyframes moveFromTop {
    from { transform: translateY(-100%); }
}

@keyframes moveToBottom {
    from { }
    to { transform: translateY(100%); }
}

js

var img2 = new Image(); 

img2.src = "img2.jpg";

$(img2).css("width","100%");

$(document).ready( function () {


    $('#button').click(function(){

        $('#myDiv1').addClass('moveToBottom');

        $("#myDiv2").append(img2);

        $('#myDiv2').addClass('moveFromTop');
   });
});

It's fairly straightforward and it works on desktop. On mobile though, the second image doesn't load immediately as you click the #button so you get a black image for a second which completely ruins the effect I am going for. This happens both on iPhone and iPad. I haven't had the chance to test on android yet, but you would have thought at $700+ apple phone could deal with a little transition ;) I am wondering if there is something I am doing wrong with my code that is creating this issue. This is my first project. Thanks for your time.

-------------------------------------------------------------------edit------------------------------------------------------------

I have tried quite a few things since I posted this question. I've tried moving the "append" line to outside of the "click" function, and the image loads immediately, pointing to this problem not having anything to do with the append() method. I have also tried a different approach, by having the image load immediately with display "none" and then doing a .css("display","block") instead of append. Still we get the black image that ruins the effect I am going for on mobile. If you want to see the problem for yourselves, please visit "alicesoyer.com". The site is live but under construction. You need to click anywhere on the screen to fire up the animation. You will see the effect I am going for. On desktop it works fine. On mobile it does not. I am testing on an iPad air and iPhone6. Thanks.

Paul
  • 1,277
  • 5
  • 28
  • 56

3 Answers3

1

The solution is to add

    * {
        -webkit-transform: translate3d(0,0,0);
    }

or at least to some child elements to trigger the browser to use hardware accelaration better. More info at this page

---update: putting it like this (ie. only on the animations), should suffice and wil likely solve the new IPad issue:

.moveFromTop {
    animation: moveFromTop 2s ease both;
    -webkit-transform: translate3d(0,0,0);
}

.moveToBottom {
    animation: moveToBottom 2s ease both;
    -webkit-transform: translate3d(0,0,0);
}
Community
  • 1
  • 1
S. Roose
  • 1,398
  • 1
  • 12
  • 27
  • Hi, thanks for this answer. I have tried it and the iPhone works perfectly now. When I did it for the iPad (using media queries) it completely messed up my layout, with the background image changing size and coming to the foreground. I'm looking into it now, as soon as I get it working I will accept your answer as a good solution. – Paul Nov 27 '16 at 23:19
  • Hi, try putting this only in your 2 animation classes (moveFromTop, moveToBottom) instead of on all elements (*) – S. Roose Nov 28 '16 at 07:30
0

What you're doing probably won't preload the image, because you haven't attached it to the DOM.

You can attach it off-page, so that when you load it, it's already been cached:

var preloadDiv = $("<div></div>")
    .css({
        position: "absolute",
        left: -10000
    })
    .append('<img src="img2.jpg">')
    .appendTo(document.body);
 var image 2 = preloadDiv.find("img");

Then when showing it:

$("#myDiv2").append(image2);
preloadDiv.remove();
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

My suggestion, rather than appending it into the DOM, include it in right in the beginning. But this is if you're willing to have that additional load on init.

$(document).ready( function () {
    $('#button').click(function(){
        $('#myDiv1').addClass('moveToBottom');
        $('#myDiv2 > img').css({dislay:'block'});
        $('#myDiv2').addClass('moveFromTop');
   });
});
#myDiv2 > img { display:none }
.moveFromTop {
    animation: moveFromTop 2s ease both;
}

.moveToBottom {
    animation: moveToBottom 2s ease both;
}

@keyframes moveFromTop {
    from {}
    to { transform: translateY(-100%); }
}

@keyframes moveToBottom {
    from {}
    to { transform: translateY(100%); }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="main">
    <div id="myDiv1">
      <img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=IMG1&w=350&h=150" width="100%">
    </div>
    <div id="myDiv2">
      <img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=IMG2&w=350&h=150" width="100%">
    </div>
</div>

<button id="button">Toggle</button>
jkris
  • 5,851
  • 1
  • 22
  • 30