I emphasize once again: the task is not to display a random image. The set of images and their addresses on the server are strictly specified.

Task: update the pictures on the site, because The contents of the image files may change. Physically, the image file remains at the same address, but since the contents of the file may change, you must force the browser to update the displayed image forcibly. For this timer add parameter to the image address

setInterval(function(){ var arr = $(".image-responsive"); for (var i = 0; i < arr.length; i++ ){ arr[i].style.backgroundImage = 'url(' + arr[i].style.backgroundImage.slice(4, -1).replace(/"/g, "").split("?")[0] + "?" + Math.random() + ')'; } }, 1000); 

Images are updated, but there is a delay before each update and the background remains empty for some time. Also the background appears abruptly. How to fix it to remove jerking and pause?

Update 2: I tried to use a preloader, an invisible container into which images are loaded, before setting them as background images for the necessary blocks on the page. With one picture to remove jerking turned out http://jsfiddle.net/rGkww/36/ However, scrolling twitches. With several http://jsfiddle.net/rGkww/41/, only one picture changes, the picture jerks as before, and the scrolling twitches

Update 3: It seems to have removed the jerking, an example of a code with a lot of images http://jsfiddle.net/rGkww/57/ It remains to jerk the scroll, well, not quite sure about the correctness of the solution itself. The page should be designed for long-term work.

Update 4: Removed scrolling jerking http://jsfiddle.net/rGkww/61/

Update 5:

I modified the code a bit so that in the event of a disconnection from the server there was no memory overflow, and after the restoration the update was resumed. http://jsfiddle.net/rGkww/64/ Update occurs without problems. However, Iceweasel/Firefox drops in a couple of hours. Because long work is necessary, it is critical. It is unclear whether the problem is in the code or in the browser. Chrome/Chromium quietly works for several days.

  • Probably, it turns out, because the new BACKGROUND does not load instantly (stupid traffic). So you need to preload images. ru.stackoverflow.com/a/455981/176892 - xaja
  • @xaja please explain. In my case, each new background image is essentially a new file for the browser. And in fact the same. In advance, I guess I can not load all the options, because The meaning is precisely in updating the background. the address of the image is the same, the contents of the file change, so I add a parameter to the src address of the image so that the browser updates the background image. Traffic in theory should not affect so much that a noticeable pause and jerking is obtained, the images are small, the problem is exactly the same on localhost - Emm
  • @xaja tried this: arr[i].style.backgroundImage = arr[i].style.backgroundImage; and then immediately arr[i].style.backgroundImage = 'url(' + arr[i].style.backgroundImage.slice(4, -1).replace(/"/g, "").split("?")[0] + "?" + Math.random() + ')'; Anyway, the background image is twitching - Emm
  • one
    @xaja tried to do it with one picture, it jerks less, in general, it’s normal jsfiddle.net/rGkww/36 And with three it didn’t work, only one changes, and jsfiddle.net/rGkww/41 twitches all the same. In both cases, scrolling is twitching - Emm
  • one
    Why are you adding an extra element to the page? You have already written that you can do only the Image() constructor. use it, do not create any elements, on the onload already insert a picture into the background. Your question has already been answered, but for some reason you do not want to admit it, insisting that YOUR implementation be changed, although the xaja implementation works - ThisMan

3 answers 3

Here's a remake of your script without jerking. Images appear only when fully loaded. Here is what was added (please pay attention to the fact that the order of the lines is very important):

 var i = new Image(); i.onload = function(){alert(i.width);} i.src = 'image.jpg'; // существующее изображение 

For the demo version I also registered a counter (increasing number), which shows the desynchronization of the appearance of a new number and image. Well, you understand, yes, that it takes time for the browser to load the image.

ps I will repeat once again - you are doing something wrong. Uploading an image that is already in the browser's cache is not correct. Nobody does that. On the contrary, they try to preload all the images in order to show them without jerking SIMULTANEOUSLY with the text.

ppt if you have a task to select 1 of a million images (that is, you really do not know which image will come to you and that is what you depict in this question using random() ), then you need to take a step back in the interval, that is, load FUTURE image (which will appear in the next iteration). It is difficult to give an example, because it is not known how the content in your real project is updated. ajax?

 $(window).load(function() { var num = 0; var randomImages = ['344291068_HdnTo', '344290962_h6JjS', '344291168_nErcq']; setInterval(function() { var rndNum = Math.floor(Math.random() * randomImages.length); var url = 'http://photos.smugmug.com/photos/' + randomImages[rndNum] + '-XL.jpg' + '?random=' + Math.random(); var i = new Image(); i.onload = function() { $(document.body).css({ 'background': 'url(' + url + ')' + ' no-repeat center center fixed', '-webkit-background-size': 'cover', '-moz-background-size': 'cover', '-o-background-size': 'cover', 'background-size': 'cover' }); } i.src = url; num++; $('#home').html(num); }, 3000); }); 
 #home { height: 150px; width: 150px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="home"></div> 

  • one
    Thanks, but the pictures still twitch, compare visually with this option of changing pictures jsfiddle.net/rGkww/36 about the re-loading, I explained in the question itself - Emm
  • The code example in the previous comment is provided solely for visual comparison - Emm

The timer is one-time, so that between the change of images there will always be a specified timer time (+ time to load the image).

 var url = 'http://photos.smugmug.com/photos' var images = ['344291068_HdnTo-XL.jpg', '344290962_h6JjS-XL.jpg', '344291168_nErcq-XL.jpg'] new updateBackgroundTimer('real', url, images, 1000) function updateBackgroundTimer(node_id, url, images, timer) { // init node_id = String(node_id) var node = document.getElementById(node_id) if (!node) return false this.node_id = node_id this.node = node url = String(url) if (!images.length) return false for (var i in images) { images[i] = url + '/' + images[i] + '?r=' + Math.random() } shuffleArray(images) // вывод изображний в случайном порядке this.images = images timer = parseInt(timer) if (isNaN(timer) || timer < 1) return false this.timer = timer // model this.start = function() { initTimer() } this.stop = function() { if (this.timer_id) { clearInterval(this.timer_id) this.timer_id = null } } initTimer = function(_this) { return function() { if (_this.timer_id) { clearTimeout(_this.timer_id) _this.timer_id = null } _this.timer_id = setTimeout( function(_this) { return function() { _this.updateImage() } }(_this), _this.timer) } }(this) this.updateImage = function() { var url = this.getImageNext() var image = new Image() image.onload = function(_this, url) { return function() { _this.setImage(url) if (!_this.images_loaded) _this.images_loaded = {} _this.images_loaded[url] = true _this.start() } }(this, url) image.src = url } this.setImage = function(url) { url = String(url) this.node.style.backgroundImage = 'url(' + url + ')' } this.getImageNext = function() { var images = this.images var images_qty = images.length var index = parseInt(this.index) if (isNaN(index) || index < 0 || index >= images_qty) { index = 0 } else { index++ if (index >= images_qty) index = 0 } this.index = index var image = images[index] return image } function shuffleArray(array) { for (var j, x, i = array.length; i; j = parseInt(Math.random() * i), x = array[--i], array[i] = array[j], array[j] = x); } // run this.start() } 
 #real { width: 300px; height: 300px; border: 2px solid red; } 
 <div id="real"></div> 

  • one
    It is not the answer to the question. To leave your comments or ask the author to clarify the question, leave a comment to the question. You can leave any number of comments under your post. When your reputation reaches the required level, you can comment on the messages of any user . - Cyrus
  • the answer is changed to fit the question - LV426
  • @psaproxy thanks, but the task of displaying random images is not worth it. Re-read, please, question) - Emm
  • You can use any images, and not random ones too - LV426

Update 2: .... With one picture to remove the twitch it turned out However, scrolling twitches.

We rewrote your code a bit, removed the scrolling jerking, in the same way the code changes for several pictures:

 $(window).load(function() { var randomImages = ['344291068_HdnTo', '344290962_h6JjS', '344291168_nErcq']; setInterval(function() { var rndNum = Math.floor(Math.random() * randomImages.length); var src = 'http://photos.smugmug.com/photos/' + randomImages[rndNum] + '-XL.jpg' + '?random=' + Math.random(); $(".preload_hidden").html("<img src=\"" + src + "\" />"); $(".preload_hidden img").load(function() { var img = src; $("#real").css({ "background": "url(" + img + ")" }); }); }, 1000); }); 
 .preload { width: 300px; height: 300px; #width: 1px; #height: 1px; background-repeat: none; #background-position: -1000px -1000px; #position: absolute; #opacity: 0; border: 2px solid blue; } #real { width: 300px; height: 300px; border: 2px solid red; } .preload_hidden { display: none; } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <div id="real"></div> <div class="preload"></div> <div class="preload_hidden"></div> 

JsFiddle example


UPDATE

wrote a decision on the author

 setInterval(function() { $(".real").each(function(index) { var obj = $(this); d = new Date(); var bg = obj.css("background-image").match(/((http|https):\/\/.*(jpg|png|gif)).*/i)[1] + '?random=' + d.getTime(); console.log(bg); $('<img/>').attr('src', bg).load(function() { $(this).remove(); // чтобы избежать утечки памяти obj.css('background-image', 'url(' + bg + ')'); }); }); }, 2000); 
 .real { width: 350px; height: 350px; border: 2px solid red; float: left; } .preload_hidden { display: none; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <div class="real" style='background-image: url("http://photos.smugmug.com/photos/344291068_HdnTo-XL.jpg");'></div> <div class="real" style='background-image: url("http://photos.smugmug.com/photos/344290962_h6JjS-XL.jpg");'></div> <div class="real" style='background-image: url("http://photos.smugmug.com/photos/344291168_nErcq-XL.jpg");'></div> 

Example on Jsfiddle

  • Thanks, in my example, your pictures still twitch. In the question I added a code with a lot of pictures, there is no jerking, but again the problem with scrolling is Emm
  • @Emm please specify under the code with a lot of pictures you mean update 3 - jsfiddle.net/rGkww/57 ? - Alex
  • yes, quite right, this code - Emm
  • yes, that's right, for this the random parameter is assigned - Emm