В настоящее время я работаю над веб-приложением, на котором есть страница, отображающая одну диаграмму (изображение .png). В другой части этой страницы есть набор ссылок, при нажатии на которые вся страница перезагружается и выглядит точно так же, как и раньше, за исключением диаграммы в середине страницы.
То, что я хочу сделать, - это когда на странице нажимают ссылку, изменяется только диаграмма на странице. Это значительно ускорит процесс, поскольку размер страницы составляет примерно 100 КБ, и на самом деле не нужно перезагружать всю страницу только для того, чтобы отобразить это.
Я делал это через JavaScript, который пока работает, используя следующий код
document.getElementById('chart').src = '/charts/10.png';
Проблема в том, что когда пользователь нажимает на ссылку, может пройти пара секунд, прежде чем диаграмма изменится. Это заставляет пользователя думать, что его щелчок ничего не сделал или что система медленно реагирует.
Я хочу отобразить индикатор прядильщика / пульсации / состояния вместо того, где находится изображение во время загрузки, поэтому, когда пользователь щелкает ссылку, он знает, что, по крайней мере, система приняла их ввод и что-то с этим делает. .
Я попробовал несколько предложений, даже используя тайм-аут psudo, чтобы показать счетчик, а затем вернуться к изображению.
Хорошее предложение, которое у меня было, - использовать следующие
<img src = "/charts/10.png" lowsrc = "/spinner.gif"/>
Что было бы идеально, за исключением того, что счетчик значительно меньше отображаемой диаграммы.
Есть другие идеи?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


поместите счетчик в div того же размера, что и диаграмма, вы знаете высоту и ширину, поэтому вы можете использовать относительное позиционирование для правильного центрирования.
Используйте мощь функции setTimeout () (Больше информации) - это позволяет вам установить таймер для запуска вызова функции в будущем и вызвать его не будет, блокирующее выполнение текущей / других функций (асинхронно).
Поместите div, содержащий счетчик, над изображением диаграммы, установив для него атрибут отображения css значение none:
<div> <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";
}
Для setTimeout не нужен первый параметр в кавычках - вы можете назвать его так: setTimeout (hideSpinner, spinnerShowTime); Это избавляет от необходимости оценивать строку интерпретатором JS, а это просто накладные расходы.
В этом случае это будет быстрее, но в ситуации, когда вы хотите передать аргументы функции, я обнаружил, что включение этой вещи в dbleQts вызывает меньше проблем (я полагаю, за счет разборчивости)
@iAn ссылка, которую вы добавили в своем ответе, не работает
Решение @iAn мне нравится. Единственное, что я бы изменил, - это вместо использования setTimeout я бы попытался подключиться к событию «Load» изображений. Таким образом, если изображение загружается дольше 3 секунд, вы все равно получите счетчик.
С другой стороны, если загрузка занимает меньше времени, вы получите счетчик менее чем на 3 секунды.
Это подводный камень использования события Load на изображении - если у вас есть кто-то с быстрым подключением, то счетчик просто включается и выключается снова. Вы должны учитывать, что счетчик на самом деле имеет две цели: не только «пожалуйста, подождите», но также «что-то произошло / произошло».
Я использовал что-то подобное, чтобы предварительно загрузить изображение, а затем автоматически перезвонить в свой 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(){};
}
}
}
Вы можете показать статическое изображение, которое дает оптическая иллюзия прялки, как эти.
Помимо опции lowsrc, я также использовал background-image в контейнере img.
Используйте CSS, чтобы установить анимацию загрузки как центрированное фоновое изображение для контейнера изображения.
Затем при загрузке нового большого изображения сначала установите src на предварительно загруженный прозрачный gif размером 1 пиксель.
например
document.getElementById('mainimg').src = '/images/1pix.gif';
document.getElementById('mainimg').src = '/images/large_image.jpg';
Во время загрузки large_image.jpg фон будет отображаться через прозрачный gif размером 1 пиксель.
Я бы добавил несколько случайных цифр, чтобы избежать кеширования браузера.
Зачем вам избегать кеширования браузера?
Не знаю, о чем я думал :) Это было 7 лет назад. Бьюсь об заклад, на то была веская причина, иначе я бы не предложил этого.
Основываясь на ответе Эда, я бы предпочел увидеть что-то вроде:
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, чтобы проверить, завершила ли загрузка изображения, пока вы настраиваете свои события - поскольку они настроены заранее, они будут запускаться независимо от того, как быстро загружаются изображения.
Имейте в виду, что функция обратного вызова также вызывается, если изображение src не существует (ошибка http 404). Чтобы избежать этого, вы можете проверить ширину изображения, например:
if (this.width == 0) return false;
Используя метод нагрузка() для jQuery, легко можно что-то сделать, как только изображение загружено:
$('img.example').load(function() {
$('#spinner').fadeOut();
});
См .: http://api.jquery.com/load-event/
использование load таким образом теперь устарело (удалено в версии 3.0) и заменено событиями загрузки.
Мне нравится метод jquery @ duddle, но я обнаружил, что load () не всегда вызывается (например, когда изображение извлекается из кеша в IE). Вместо этого я использую эту версию:
$('img.example').one('load', function() {
$('#spinner').remove();
}).each(function() {
if (this.complete) {
$(this).trigger('load');
}
});
Это вызывает load не более одного раза и сразу же, если загрузка уже завершена.
.one () должен быть .on ()
Нет, ты ошибаешься. В этом случае я хочу активировать загрузку только один раз. api.jquery.com/one
Некоторое время назад я написал плагин jQuery, который автоматически обрабатывает отображение счетчика http://denysonique.github.com/imgPreload/
Просмотр его исходного кода должен помочь вам определить, когда отображать счетчик, и отобразить его в центре загруженного изображения.
Для пользователей настольных компьютеров вы также можете изменить курсор, чтобы показать, что что-то происходит. Вам нужно будет использовать некоторый CSS, например
body.waiting{cursor: wait;}, а затем переключить его с помощью javascript с помощью:document.body.classList.add('waiting');и при загрузке изображения:document.body.classList.remove('waiting');.