Подтвердить что ты не робот

Как показать прядильщик при загрузке изображения с помощью JavaScript

В настоящее время я работаю над веб-приложением, которое имеет страницу, на которой отображается один график (изображение .png). На другой части этой страницы есть набор ссылок, которые при нажатии на нее перегружаются и выглядят точно так же, как и раньше, за исключением диаграммы в середине страницы.

То, что я хочу сделать, - это когда ссылка нажимается на странице, только изменилась диаграмма на странице. Это значительно ускорит работу, поскольку страница имеет размер около 100kb, и на самом деле не нужно перезагружать всю страницу, чтобы отобразить ее.

Я делал это через JavaScript, который работает до сих пор, используя следующий код

document.getElementById('chart').src = '/charts/10.png';

Проблема заключается в том, что когда пользователь нажимает на ссылку, это может занять пару секунд до изменения графика. Это заставляет пользователя думать, что их клик ничего не сделал или что система не реагирует.

То, что я хочу сделать, это показать индикатор spinner/throbber/status, вместо того, где изображение находится во время загрузки, поэтому, когда пользователь нажимает на ссылку, которую они знают, по крайней мере, система приняла свой вклад и делает что-то об этом.

Я пробовал несколько советов, даже используя время psudo, чтобы показать spinner, а затем перевернуться к изображению.

Хорошее предложение, которое у меня было, это использовать следующие

<img src="/charts/10.png" lowsrc="/spinner.gif"/>

Что было бы идеальным, за исключением того, что счетчик значительно меньше отображаемой диаграммы.

Любые другие идеи?

4b9b3361

Ответ 1

Я использовал что-то вроде этого, чтобы предварительно загрузить изображение, а затем автоматически перезвонить на мой javascript, когда изображение закончит загрузку. Вы хотите проверить завершение до того, как вы настроите обратный вызов, потому что изображение уже может быть кэшировано и оно не может вызвать ваш обратный вызов.

function PreloadImage(imgSrc, callback){
  var objImagePreloader = new Image();

  objImagePreloader.src = imgSrc;
  if(objImagePreloader.complete){
    callback();
    objImagePreloader.onload=function(){};
  }
  else{
    objImagePreloader.onload = function() {
      callback();
      //    clear onLoad, IE behaves irratically with animated gifs otherwise
      objImagePreloader.onload=function(){};
    }
  }
}

Ответ 3

Используйте силу функции setTimeout() (Дополнительная информация) - это позволяет вам установить таймер для запуска вызова функции в будущее, а вызов не будет блокировать выполнение текущих/других функций (async.).

Поместите div, содержащий счетчик над изображением диаграммы, при этом атрибут css display установлен равным none:

<div>&nbsp;<img src="spinner.gif" id="spinnerImg" style="display: none;" /></div>

nbsp останавливает развал div, когда прядильщик скрыт. Без него, когда вы переключаете отображение счетчика, ваш макет будет "подергиваться"

function chartOnClick() {
  //How long to show the spinner for in ms (eg 3 seconds)
  var spinnerShowTime = 3000

  //Show the spinner
  document.getElementById('spinnerImg').style.display = "";

  //Change the chart src
  document.getElementById('chart').src = '/charts/10.png';

  //Set the timeout on the spinner
  setTimeout("hideSpinner()", spinnerShowTime);
}

function hideSpinner() {
  document.getElementById('spinnerImg').style.display = "none";
}

Ответ 4

Используя метод load() jQuery, можно легко сделать что-то, как только загрузится изображение:

$('img.example').load(function() {
  $('#spinner').fadeOut();
});

Смотрите: http://api.jquery.com/load-event/

Ответ 5

Используйте CSS, чтобы настроить загрузку анимации как центрированное фоновое изображение для контейнера изображения.

Затем при загрузке нового большого изображения сначала установите src на предварительно загруженный прозрачный 1 пиксель gif.

например.

document.getElementById('mainimg').src = '/images/1pix.gif';
document.getElementById('mainimg').src = '/images/large_image.jpg';

При загрузке файла large_image.jpg фон будет отображаться через прозрачный gif 1pix.

Ответ 6

Основываясь на ответе Эд, я бы предпочел увидеть что-то вроде:

function PreLoadImage( srcURL, callback, errorCallback ) {
     var thePic = new Image();

     thePic.onload = function() {
          callback();
          thePic.onload = function(){};
     }

     thePic.onerror = function() {
          errorCallback();
     }
     thePic.src = srcURL;
}

Ваш обратный вызов может отображать изображение в нужном месте и располагать/скрывать прядильщика, а errorCallback предотвращает "отбой" вашей страницы. Все управляемые событиями, без таймеров или опроса, плюс вам не нужно добавлять дополнительные операторы if, чтобы проверить, завершилось ли заполнение изображения, когда вы настраиваете свои события, - поскольку они настроены заранее, они будут запускаться независимо от того, как быстро загружаются изображения.

Ответ 7

Мне нравится метод @duddle jquery, но обнаруживает, что load() не всегда вызывается (например, когда изображение извлекается из кеша в IE). Вместо этого я использую эту версию:

$('img.example').one('load', function() {
  $('#spinner').remove();
}).each(function() {
  if(this.complete) {
    $(this).trigger('load');
  }
});

Это вызывает нагрузку не более одного раза и сразу же, если она уже завершила загрузку.

Ответ 8

Некоторое время назад я написал плагин jQuery, который автоматически обрабатывает прядильщик http://denysonique.github.com/imgPreload/

Входящий в исходный код должен помочь вам определить, когда отображать счетчик и отображать его в центре загруженного изображения.

Ответ 9

поместите счетчик в div того же размера, что и диаграмма, вы знаете высоту и ширину, чтобы вы могли использовать относительное позиционирование, чтобы правильно центрировать его.

Ответ 10

Помимо опции lowsrc, я также использовал background-image в контейнере img.

Ответ 11

Помните, что функция обратного вызова также вызывается, если изображение src не существует (ошибка HTTP 404). Чтобы этого избежать, вы можете проверить ширину изображения, например:

if(this.width == 0) return false;

Ответ 12

@i Решение выглядит хорошо для меня. Единственное, что я изменил, вместо использования setTimeout, я попытаюсь подключиться к событию Load Load. Таким образом, если для загрузки требуется более 3 секунд, вы все равно получите счетчик.

С другой стороны, если потребуется меньше времени для загрузки, вы получите счетчик менее 3 секунд.

Ответ 13

Я бы добавил некоторые случайные цифры, чтобы избежать кеша браузера.