#javascript #html #css
Еще раз подчеркну: задача не стоит вывести рандомное изображение. Набор изображений и их адреса на сервере строго заданы. Задача: обновлять картинки на сайте, т.к. содержимое файлов с изображениями может измениться. Физически файл с изображением остается лежать по тому же адресу, но т.к. содержимое файла может измениться, необходимо заставить браузер обновлять отображаемое изображение принудительно. Для этого по таймеру добавляю параметр к адресу картинки 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); Изображения обновляются, но перед каждым обновлением происходит задержка и фон остается какое-то время пустым. Также фон появляется резко. Как это исправить, чтобы убрать дерганье и паузы? Обновление 2: Попытался использовать предзагрузчик - невидимый контейнер, в который подгружаются изображения, прежде чем установить их в качестве фоновых изображений для нужных блоков на странице. С одной картинкой убрать дерганье получилось http://jsfiddle.net/rGkww/36/ Однако дергается скроллинг. С несколькими http://jsfiddle.net/rGkww/41/ меняется только одна картинка, дерганье картинки по-прежнему, и скроллинг дергается Обновление 3: Вроде дерганье убрал, пример кода со множеством изображений http://jsfiddle.net/rGkww/57/ Осталось дерганье скролла, ну и не совсем уверен в корректности самого решения. Страница должна быть рассчитана на длительную работу. Обновление 4: Убрал дерганье скроллинга http://jsfiddle.net/rGkww/61/ Обновление 5: Доработал немного код, чтобы в случае обрыва соединения с сервером не возникало переполнение памяти, и после восстановления обновление возобновлялось. http://jsfiddle.net/rGkww/64/ Обновление происходит без проблем. Однако Iceweasel/Firefox через пару часов падает. Т.к. необходима длительная работа, это критично. Неясно, проблема в коде или в браузере. Chrome/Chromium спокойно работает несколько дней.
Ответы
Ответ 1
Вот переделка вашего скрипта без дерганий. Изображения появляются только когда полностью загрузились. Вот что добавилось (прошу обратить внимание на то, что порядок строк очень важен): var i = new Image(); i.onload = function(){alert(i.width);} i.src = 'image.jpg'; // существующее изображение Для демо версии так же прописал счетчик (увеличивающееся число), который показывает рассинхронизацию появления нового числа и изображения. Ну, вы же понимаете да, что для загрузки картинки браузеру нужно время. п.с. я повторю еще раз - вы что-то не то делаете. Загружать ещё раз изображение, которое уже лежит в кеше браузера - не правильно. Никто так не делает. Наоборот пытаются предзагрузить все изображения, чтобы потом показывать их без дерганий ОДНОВРЕМЕННО с текстом. п.п.с. если у вас задача выбрать 1 из миллиона изображений (то есть вы реально не знаете какое изображение к вам придет и именно это вы изображаете в данном вопросе с помощью random()), то тогда нужно в интервале сделать "шаг назад", то есть загружать БУДУЩЕЕ изображение (которое покажется в следующую итерацию). Пример давать сложно, потому что не известно каким образом в реальном проекте у вас контент обновляется. 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; }Ответ 2
Таймер одноразовый, что бы между сменой изображений всегда было заданное время таймера (+время на загрузку изображения). 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; }Ответ 3
Обновление 2: .... С одной картинкой убрать дерганье получилось Однако дергается скроллинг. Немного переписали Ваш код, убрали дерганье скролла, таким же образом код меняется и для нескольких картинок: $(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(""); $(".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; } } Пример на JsFiddle UPDATE написали решение по вопросу автора 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); $('').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; } Example on Jsfiddle
Комментариев нет:
Отправить комментарий