Небольшой совет: реализация эффекта состояния загрузки изображения

внешний интерфейс сервер Язык программирования Vue.js

Одним из требований является достижение эффекта загрузки изображения, подобного следующему рисунку:

Загрузите картинку с локального на сервер, а затем сервер отвечает и возвращает адрес ссылки картинки на сервере, отображает картинку, соответствующую адресу ссылки на экране, и представляет динамическую картинку до того, как ресурс картинки будет полностью скачал.loading, пока полностью не скачается образ на замену

маленький наконечник

Это очень распространенное требование. Ключевым моментом является обнаружение события завершения загрузки изображения. Общая практика заключается в том, чтобы сначалаimgпомеченsrcАтрибут указывает наsrcПросто укажите реальную ссылку

const img = new Image()
// 真实图片地址
const realSrc = 'http://a.com/real.png'
img.src = realSrc
img.onload = () => {
  // domImgElement 为 img 的 HTML DOM对象
  domImgElement.src = realSrc
}

В этом подходе нет ничего плохого, и он применяется в большинстве случаев, но поскольку я хорошо умею (сянь) долго (дэ) думать (дан) тестировать (тэн), а потом думать о небольшой проблеме

Потребность, которую я имею под рукой, основана наvue, после рендеринга страницы, если вы хотите изменить содержимое на странице, вам нужно снова изменить соответствующий DO, хотяvueсуществуетvnodeСкорость обновления очень высокая, но какой бы быстрой она ни была, расчет диффа все равно нужно выполнять.Этот процесс все равно не убежать.Если есть десяток или даже десятки картинок, похожих на приведенный выше эффект асинхронной загрузки изображений , разве это не должно было измениться десятки разdataстоимость,vueматч внутриpatchДесятки раз, а потом страницу десятки раз обновят целиком, страшно подумать об этом

все большеpatchоднаждыvnode tree, каждый раз, когда страница обновляется, это вызоветCPUа такжеGPUУвеличение энергопотребления — это огромная и невидимая черная дыра энергопотребления, которая будет тяжелым бременем для личного развития, финансов компании и парникового эффекта на земле!

Более того, обычно данные изображения этого типа списка существуют в массиве.Каждый раз, когда изображение загружается, оно будет замененоsrcРаньше также необходимо сначала основываться на определенном флаге, например, на картинке.idилиurlЧтобы найти соответствующее изображение из этого массива изображений, а затем заменить его, обратите внимание на этот шагvueПроблема автоматического выполнения реактивных операций над свойствами вложенных объектов:

loadImg (imgId) {
  const img = new Image()
  // 真实图片地址
  const realSrc = 'http://a.com/real.png'
  img.src = realSrc
  img.onload = () => {
    this.imgList.some(imgObj => {
      if (imgObj.id === imgId) {
        imgObj.src = realSrc
        this.$forceUpdate()
        return true
      }
      return false
    })
  }
}

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

Главное не заменитьimgЭтикеткаsrcоперации, так что вы можете сэкономить более половиныjsработа следующим образомDOMПример структуры:

<div class="img-item">
  <img :src="item.realUrl" alt="" />
</div>

item.realUrlЭто реальный адрес текущего изображения.Когда вы его получите, вы можете присвоить его напрямую, и вы не будете использовать его позже.srcЭто свойство исчезло, так как большая часть работы перемещена вcssначальство:

.img-item {
  position: relative;
  width: 80px;
  height: 80px;
  background-color: #aeaeae;
}
.img-item::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 22px;
  height: 22px;
  margin-left: -11px;
  margin-top: -11px;
  /* 这是加载效果的图片 */
  background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABAUlEQVQ4T6WSzyrEYRSGn2crF6GmJJTsLLGyEVM2lAshdriUsbAwsWeWlpJ/Kck1KNtXM330G8b84due8z7fed9z5J/P3/RJNoCDUt9XT3r1/gAkmVSfktwB00V0r84MBCS5AJaAc6A2EiDJOPBW+WUb2KtaSDKr3lYn6bKQ5AxYBS7V5WHy/QIkWSmCV/VhGHG7pwNIsg6cFlFdbfbZzlRHqI9VwCbQKKIt9bgPYKEArqqAMWCriBrq+0gWPpuTzAG7wKF68x2SpKY+99tC2/sa0FTr1cYkE8ALMK9ef9a+r7F9RDvAkdpK0ip+F0vY/SfoMXIXYOApDxvcrxn8BfABIiRjEYfmQAcAAAAASUVORK5CYII=') no-repeat;
  background-position: center center;
  background-size: contain;
  animation: loadpic .5s infinite linear;
  z-index: 1;
}

@keyframes loadpic {
  from { transform: rotate(0) }
  to { transform: rotate(360deg) }
}

img {
  position: relative;
  height: 100%;
  width: 100%;
  z-index: 2;
}

.img-itemэто единый пакетimgРодительский элемент , который имеет две роли: Во-первых, растянуть занимаемое пространство Во-вторых, используйте его::beforeПсевдоэлемент для загрузки анимации, используемый для указания того, что изображение загружаетсяloadingфигура, то естьloadingКартина размещена::beforeначальство

::beforeбудет существовать до тех пор, пока.boxвнутриimgПосле того, как ресурс скачан, покажите его, закройте, т.к.imgширина и высота элемента.boxто же самое, иimgизz-indexбольше, так что простоimgЕсли он не загружен, то не будет отображаться, то будет отображаться::beforeэлемент, то есть дисплейloadingсостояние, и покаimgПосле завершения загрузки он будет отображаться и закрываться.::before, этот процесс визуально позволяет добиться эффекта картинки в начале статьи, а расход ниже

emmmm, раз уж речь идет о картинках, то, кстати, оimgМетки обычно не используются, но иногда бывают полезны.

Для изображения:

<img src="http://a.com/b.png" />

еслиsrcТочка, которой нет соответствующего ресурса или она является нелегальной, то в браузере будет отображаться специальный стиль, например:

Разные браузеры могут по-разному отображать недопустимые изображения.ChromeВот как выглядит вышеприведенное сломанное изображение. Оно говорит вам, что изображение не может быть найдено. Такой пользовательский опыт определенно не очень хорош. В этом случае большинство методов заключается в наблюдении.imgпомеченonerrorСобытие, если это событие срабатывает, значит сбой, и тогда можно переходить к логике сбоя

Но это такжеjsКаждое изображение должно устанавливать событие слушателя, тогда, если на странице есть десятки изображений, не нужно ли устанавливать десятки событий слушателя?

Каждый раз, когда устанавливается событие прослушивателя, это вызывает...

Это просто опыт прогрессивного улучшения, и в него не нужно вкладывать так много, поэтому вам нужно использоватьcssспособность не слушатьerrorКогда событие происходит, непосредственно добавьте следующие стили к изображениям, которые должны отображаться дружественным образом при сбое загрузки:

img:before {
  /* 关键是这句 */
  content: '图片加载失败~';

  /* 下面都是辅助的样式代码 */
  display: block;
  padding: 0 20px;
  background-color: #eaeaea;
  color: indianred;
  line-height: 30px;
}

Если изображение не загружается, оно покажет, где должен был отображаться сломанный стиль.图片加载失败~быстрая копия

в основном используют:beforeа также:afterЭти два псевдоэлемента находятся вimgхарактеристики на этикетке,imgНормальная загрузка, содержимое этих двух псевдоэлементов отображаться не будет, еслиimgЕсли загрузка не удалась, будет отображено содержимое этих двух псевдоэлементов.Возможностей этих двух псевдоэлементов по-прежнему много.Выше приведен лишь пример, который я привел вскользь.

Суммировать

я думаюcssЭто также очень важная способность для фронтенд-инженеров.jsОбъем кода может естественным образом снизить вероятность сообщения об ошибках, а иногда его можно легко реализовать, что требует много усилий.jsДля достижения эффекта улучшите работу страницы

Так что я иногда вижу, как кто-то говорит в интерфейсеtaнисколькоcare CSS, я думаю, что это даже не язык программирования, спецификация грамматики беспорядочна, и я даже не утруждаю себя ее изучением,taнужно толькоJSможно написать любой эффект, особенно в сегодняшнем разнообразномjsНа данный момент, когда фреймворк популярен, многие новички знают толькоjsне знаяcss, четноеhtmlНе только новички, но даже некоторые фронтенд-инженеры, проработавшие много лет, когда я вижу код, который они пишут, иногда поражаюсь ихcssа такжеhtmlКод все еще можно написать так

В большинстве случаев в этом явлении может и нет ничего страшного, ведь задница решает голова, даже если вы выйдете на собеседование, интервьюер будет практически только задавать вопросы.jsвопросы, не спрашивая васsectionа такжеarticleГде этикетка подходит для использования, какова базовая линия шрифта,line-heightЧто толку,мне просто интересно,как фронтенд разработчик,можно использовать только один из трех фронтенд мушкетеров.Печаль можно не упоминать,но два навыка из трех теряются в начале,в по крайней мере, это можно расценивать как навыки самоуничтожения.