1

I am using Jimdo and have a given div (containing 3 sub-divs, I think this is my general problem, but I am not sure) I found with the browser:

<div class="jtpl-background-area jqbga-container jqbga-web--image" background-area="" style="background-image: url('https://image.jimcdn.com/app/cms/image/transf/dimension=767x/path/s4354a59fbfee63e4/backgroundarea/ibb91266a7f033fa3/version/1529172695/image.jpg');background-position: 54.0833% 41.0025%;"></div>

How do I get a function triggered after the background-image of this is loaded?

I've already spent hours into this, tried tons of ways I found here or tools like waitforimages - still without success. What is going on with Jimdo / this div? How do I get something triggered after the background-image is loaded?

var src = $('.jtpl-background-area').css('background-image');
var url = src.match(/\((.*?)\)/)[1].replace(/('|")/g,'');

var img = new Image();
img.onload = function() {
$('.jtpl-background-area').css('-webkit-animation', 'fadein 4s');
}
img.src = url;
if (img.complete) img.onload();

does not work.

$('.jtpl-background-area').waitForImages(true).done(function() {
$('.jtpl-background-area').css('-webkit-animation', 'fadein 4s');
});

does not work (waitforimages-script is included correct and opacity of .jtpl-background-area is set to 0 in css).

Any ideas?

 $(window).on('load', function() {
    $(".jtpl-background-area").css('-webkit-animation', 'fadein 4s');
 });

causes backgrounds often popping up too late. Page is displayed while pictures are still not ready/fully loaded.

-

Edit:

Regarding Scott Marcus and the answer here by 'adeneo' (Wait for background images in CSS to be fully loaded):

  $(window).on('load', function() {
   $(".jtpl-background-area jqbga-container jqbga-web- 
   image").ready(function() {
  $(".jtpl-background-area").velocity({ opacity: 1 },{ duration: 3000});
   })
  });

This here "works" - but my bg-images popping up too late. But why does nothing happen if I exchange this with

var src = $(".jtpl-background-area jqbga-container jqbga-web-image");
var url = src.match(/\((.*?)\)/)[1].replace(/('|")/g,'');
var img = new Image();
img.onload = function() {
$('.jtpl-background-area').velocity({ opacity: 1 },{ duration: 3000});
}
img.src = url;
if (img.complete) img.onload();

? Where is my mistake? Why doesnt this work and make my page stuck? It stays white and fails to load at all with this code.

Or in other words - how do I get

var src = $('#test').css('background-image');
var url = src.match(/\((.*?)\)/)[1].replace(/('|")/g,'');

var img = new Image();
img.onload = function() {
alert('image loaded');
}
img.src = url;
if (img.complete) img.onload();

to work with my (given and unchangeable)

<div class="jtpl-background-area jqbga-container jqbga-web--image" background-area="" style="background-image: url('https://image.jimcdn.com/app/cms/image/transf/dimension=767x/path/s4354a59fbfee63e4/backgroundarea/ibb91266a7f033fa3/version/1529172695/image.jpg');background-position: 54.0833% 41.0025%;"></div>

exactly?

MichaelS82
  • 21
  • 4

3 Answers3

1

Instead of using a background image, you can use an img element and CSS positioning to layer it behind the content of its parent div. Then, you can use the load event of the img element.

document.querySelector(".jtpl-background-area").addEventListener("load", function(){
  console.log("Background loaded!");
  $(".hidden").fadeIn(4000);    // Fade the image in
});
/* by positioning the element absolutely and giving it a negative
   z-index, we put it behind any other items in the same space. */
.jtpl-background-area { position:absolute; z-index:-1; top:0; left:0; }

div div { background-color:rgba(255,255,255, .5); }

.hidden { display:none; } /* Image will start off hidden */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <div>Some other div content</div>
  <!-- The image will be hidden at first -->
  <img class="hidden jtpl-background-area jqbga-container jqbga-web--image" background-area=""  src="http://imgsrc.hubblesite.org/hvi/uploads/image_file/image_attachment/30741/STSCI-H-p1821a-m-1699x2000.png">
</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • Your 3rd part is not clear to me...unfortunately I can't edit or change my
    as its given by Jimdo. I can only edit CSS and JS
    – MichaelS82 Nov 24 '18 at 19:22
  • @MichaelS82 What 3rd part? What can you not edit or change? This is how it has to be done. – Scott Marcus Nov 24 '18 at 19:25
  • Your 3rd code-snippet:
    Some other div content
    – MichaelS82 Nov 24 '18 at 19:26
  • @MichaelS82 You're going to have to change from using a background image to using a foreground image if you want to be able to trap the `load` event. But, you can then use CSS to position that foreground image so that it is in the background. That's what I'm showing in that HTML. – Scott Marcus Nov 24 '18 at 19:27
  • Thats the problem...I cant edit the html. My html-line in post 1 is given by Jimdo. and is not changeable. I could add html manually at the body-bottom maybe, but the original line will still be there, And if I remove my uploaded pictures completely I'll loose some functionality (changing Backgrounds on subpages for example). Seems I need a different solution... – MichaelS82 Nov 24 '18 at 19:34
  • @MichaelS82 Sorry, don't know what to tell you. Sounds like Jimdo is not compatible with what it is you want to do. – Scott Marcus Nov 24 '18 at 19:37
  • It seems so :D But I cant believe :( Why doesnt waitforImages for example simply 'trap' my background-image? Shouldn't it work in general with "background-image"? Is there really no way to trigger something after my background-image is loaded? Or in other words, why exactly doesnt it work? – MichaelS82 Nov 24 '18 at 19:52
  • @MichaelS82 The reason is that events have to be attached to DOM elements and the `load` event is only configured for elements in the foreground of the DOM. – Scott Marcus Nov 24 '18 at 20:12
  • Sound plausible, but I still do not get why https://stackoverflow.com/questions/22788782/wait-for-background-images-in-css-to-be-fully-loaded for example does not work for me ("by getting the image URL and using it for an image object in javascript"). Is there no other 'hack' around? Any solution is welcome. – MichaelS82 Nov 24 '18 at 20:48
  • So here is an idea: Why not have the background-image loaded with JS? Have jQuery apply a class to your .jtpl-background-area that includes the background-image and the animation? Does that not work because of timing reasons? – yinken Nov 24 '18 at 21:04
  • @yinken: how exactly? Sounds complicated...dont forget: the first code-snippet in my starting post is given. I cant change that line. I upload my background using Jimdo. On some subpages there are several backgrounds in a slider. And I dont want to miss that functionality. – MichaelS82 Nov 24 '18 at 21:26
  • I also trried around with for every picture on every subpage, of course without success. – MichaelS82 Nov 24 '18 at 21:27
0

So here is what I came up with. We are basically creating an image, waiting for the file to load, then applying a style to the container.

Basically, we are making sure that no background-image is shown when the page loads by setting background:none !important; to the container.

We then create a new Image with JS, once that image's source is loaded, we apply a new class to the container, which sets the background image. You can add the animation and/or the opacity at your own discretion.

You may or may not have to fiddle around with the !important flag for your use case.

Is this what you had in mind?

$(document).ready(function() {
  var img = new Image();
  var container = $('.container');
  img.src = "https://placeimg.com/640/480/any";
  img.addEventListener('load', function() {
    container.addClass('hasBackgroundImage')
  });
});
.container {
  opacity: 0;
  background: none !important;
}

.hasBackgroundImage {
  opacity: 1;
  background-image: url('https://placeimg.com/640/480/any') !important;
  background-size: cover;
  height: 500px;
  width: 500px;
  transition: all ease-in-out 4s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container"></div>
yinken
  • 423
  • 4
  • 11
  • Does not work actually. Tried it, added my picturelink, added the divclass at the bottom of my page - now I have a grey, large (background-colored) field under my content. – MichaelS82 Nov 24 '18 at 22:40
  • If I may, what is it you would like to achieve exactly? – yinken Nov 24 '18 at 22:41
  • My background-images are popping up too late. I need a simple way to ensure theyŕe completely loaded. I need a way that triggers a function when they are definately fully loaded. As written above - Opacity is 0 and if I do a "simple // $(window).on('load', function() { // $(".jtpl-background-area jqbga-container jqbga-web-image").ready(function() // { // $(".jtpl-background-area").velocity({ opacity: 1 },{ duration: 3000}); // }) //}); they are often not fully loaded and popping up too late. – MichaelS82 Nov 24 '18 at 22:47
  • It could be totally easy If I would get waitforImages to work...but It doesnt. Even "adeneo"'s answer here https://stackoverflow.com/questions/22788782/wait-for-background-images-in-css-to-be-fully-loaded does not work for me. But why?? Jimdo makes me sick. Scott Marcus seems to be right...in general it looks as if the page and "window on load" are just firing too early and the external images are still loading. – MichaelS82 Nov 24 '18 at 23:06
  • Why don't you give adeneo's solution another go, but instead of doing the animation, add the class .loaded which is set to "opacity:1;". So: img.onload = function() { $('.jtpl-background-area').addClass('loaded'); -- I just realized that this is what I was going for as well... – yinken Nov 24 '18 at 23:17
  • I do not get it, screen stays white with img.onload = function() { $('.jtpl-background-area').addClass('loaded'). And where is the difference to the way in my starting post? Code snippet 2. As its a horror to pur code in here I edit my startpost again and attach what Ive done there. – MichaelS82 Nov 24 '18 at 23:40
0

You might do it like this:
Script starts working before the document has been loaded.
It intercepts the inline style of your div before it's been applied.
Then uses Image object to load the image and sets the background-image onload.

var i = setInterval(function() {
  var div = document.querySelector('.jtpl-background-area');
  if (div) {
    clearInterval(i);
    var src = div.style.backgroundImage.replace(/^url\(['"]?|['"]?\)/ig, '');
    div.style.backgroundImage = 'none';
    var img = new Image();
    img.onload = function() {
      div.style.backgroundImage = 'url(' + src + ')';
      div.classList.add('loaded')
      img = null;
    }
    img.src = src;
  }
}, 10);
.jtpl-background-area {
  width: 330px;
  height: 200px;
  opacity: 0;
}

.loaded {
  transition: opacity 2s linear;
  opacity: 1;
}
<div class="jtpl-background-area jqbga-container jqbga-web--image" background-area="" style="background-image: url('https://image.jimcdn.com/app/cms/image/transf/dimension=767x/path/s4354a59fbfee63e4/backgroundarea/ibb91266a7f033fa3/version/1529172695/image.jpg');background-position: 54.0833% 41.0025%;"></div>

Hope this helps.

Kosh
  • 16,966
  • 2
  • 19
  • 34
  • Does not work on a quick try. Whyever... Contrary to code snippet 2 from my starting post, the page loads with your code...but the background stays grey. I also tried to exchange the queryselector with ".jtpl-background-area jqbga-container jqbga-web-image", same result. – MichaelS82 Nov 25 '18 at 01:40
  • Now Ive got a picture after I exchanged the queryselector to ".jqbga-container"...interesting. I removed the transition earlier, I re-add it now to .loaded and do some further tests..... – MichaelS82 Nov 25 '18 at 01:59
  • Since my snippet works as expected (you can run it and see the result), I think you're doing something wrong when trying to adopt it. The first mistake I see is that you trying to use selector `.jtpl-background-area jqbga-container jqbga-web-image` which is invalid. – Kosh Nov 25 '18 at 01:59
  • This seems to work good in Chrome and Samsung-browser on my mobile. Backgrounds still popping up in Firefox (mobile, on my desktop I have not yet cleaned my cache and tried it). But my biggest problem is that this solution atm only works on pages where I have one image. It does not work on subpages with a slider, even if I change the queryselector to jqbga-slider (which is only available on these pages). Not easy to find a "good way" ^^ – MichaelS82 Nov 25 '18 at 03:07
  • @MichaelS82, your question was `Trigger function after background-image is loaded`. One image was discussed. And you received several relevant answers. Now you want something different: several images, subpages, slider. It's a bit confusing. My solution can be easily transformed to handle more than one image. But I'd like you to edit your question and add your actual code. – Kosh Nov 25 '18 at 15:44