Резервный вариант для заблокированных фреймов: (грубое) решение с Vue.js

Одна вещь, которая отстой в использовании iframe, заключается в том, что вы не можете сказать из родительского контекста, правильно ли он загружен или нет.

Это затрудняет обеспечение хорошего UX, когда пользователи находятся в автономном режиме (а ваш сайт является PWA) или когда iframe не загружается по какой-либо другой причине.

Примечание: эта статья изначально была опубликована здесь, в блоге разработчиков Vue.js 25.12.2018.

Вариант использования

Разработчики Vue.js На веб-сайте есть видео Vimeo, встроенное в домашнюю страницу, которое использует iframe для предоставления видеоплеера. Вот как это выглядит, когда загружается iframe и все работает правильно:

изображение главной страницы

Я сейчас в Индонезии, и провайдер Telkomsel, услугами которого я здесь пользуюсь, решил заблокировать Vimeo по соображениям морали. Это означает, что я и 121 миллион других пользователей Telkomsel видят этот уродливый мертвый iframe спереди и по центру, когда смотрю на домашнюю страницу:

изображение заблокированного iframe

Это также выглядит так, когда офлайн-пользователи используют возможности PWA этого сайта.

Я хотел бы показать какой-нибудь резервный контент, если iframe не работает… но как?

Почему вы не можете обнаружить ошибки iframe

Нет никаких точный способ программного определения того, загружен ли iframe из родительского контекста. iframe элементы не генерируют событие ошибки, поэтому вы не можете использовать JavaScript для прослушивания ошибок.

Но что, если мы поумнеем и сделаем AJAX-вызов URL-адреса iframe? Если он вернет 404, мы будем знать, что iframe недоступен.

Неа. Из-за политики безопасности «одного происхождения», реализованной в вашем браузере, вы не можете использовать AJAX в таких доменах. Таким образом, ваш вызов AJAX завершится ошибкой, даже если iframe загружается нормально.

Сырой раствор

Вот решение, которое я реализовал, которое примерно выполняет эту работу. Это использует Vue.js, но вы можете легко сделать это с чистым JS или другим фреймворком.

Идея состоит в том, что я использую изображение (текст или другой контент тоже подойдет) в качестве резервного контента. Я показываю запасной вариант во время загрузки iframe, затем, если я думаю, что он загружается нормально, я заменяю резервный контент загруженным iframe.

Но как узнать, успешно ли загружен iframe? Хотя у фреймов нет события ошибки, у них есть событие загрузки. Рассчитывая время загрузки, вы можете получить приблизительное представление о том, правильно ли оно загружено или нет.

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

Как я это реализовал

Во-первых, я создал элемент-обертку и поместил в него резервный контент и iframe.

<div class="wrapper">
  <img class="fallback" v-if="!iframeLoaded">
  <iframe src="..." :class="{ 'loading' : !iframeLoaded }" @load="iframeLoad"/>
</div>

Я создал логическую переменную iframeLoaded который имеет два применения: во-первых, для динамического отображения резервного содержимого, а во-вторых, для скрытия iframe с динамически привязанным классом CSS.

Я то слушаю родной load событие в iframe и обработать событие с помощью метода iframeLoad. Отсюда я могу осмотреть timeStamp значение, и если оно меньше выбранного порога (у меня было 10 секунд), я предполагаю, что iframe успешно загружен, и переключаю iframeLoaded.

export default {
  data: () => ({
    iframeLoaded: false
  }),
  methods: {
    iframeLoad(e) {
      if (e.timeStamp < 10000) {
        this.iframeLoaded = true;
      }
    }
  }
});

Вы увидите loading class для iframe дает ему нулевую высоту и ширину, гарантируя, что его нельзя будет увидеть до тех пор, пока он не загрузится должным образом.

.wrapper {
  position: relative
}
.wrapper > * {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.wrapper > iframe.loading {
  width: 0%;
  height: 0%;
}

Что делать, если пользователь является частью ~30% людей во всем мире все еще используют соединение 2G.? Большая проблема с этим подходом заключается в том, что я обязательно получу ложные срабатывания независимо от того, какой установлен порог временной метки.

Если вы собираетесь использовать этот подход, убедитесь, что ваш резервный контент является чистым улучшением взаимодействия с пользователем даже при случайных ложных срабатываниях.

За Разработчики Vue.js, я считаю, что это так. Кто-то с достаточно медленным соединением, для загрузки iframe требуется более 10 секунд, вероятно, все равно не захочет транслировать видео. Резервный контент, который я использовал, представляет собой локальную версию миниатюры видео, поэтому в худшем случае пользователь просто увидит ее. 🤷

Изображение резервного решения


Станьте старшим разработчиком Vue в 2020 году.

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

Учить больше


Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *