Javascript window onload images

Загрузка ресурсов: onload и onerror

Браузер позволяет отслеживать загрузку сторонних ресурсов: скриптов, ифреймов, изображений и др.

Для этого существуют два события:

Загрузка скриптов

Допустим, нам нужно загрузить сторонний скрипт и вызвать функцию, которая объявлена в этом скрипте.

Мы можем загрузить этот скрипт динамически:

let script = document.createElement('script'); script.src = "my.js"; document.head.append(script);

…Но как нам вызвать функцию, которая объявлена внутри того скрипта? Нам нужно подождать, пока скрипт загрузится, и только потом мы можем её вызвать.

Для наших собственных скриптов мы можем использовать JavaScript-модули, но они не слишком широко распространены в сторонних библиотеках.

script.onload

Главный помощник – это событие load . Оно срабатывает после того, как скрипт был загружен и выполнен.

let script = document.createElement('script'); // мы можем загрузить любой скрипт с любого домена script.src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.js" document.head.append(script); script.onload = function() < // в скрипте создаётся вспомогательная переменная с именем "_" alert(_.VERSION); // отображает версию библиотеки >;

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

…А что если во время загрузки произошла ошибка? Например, такого скрипта нет (ошибка 404), или сервер был недоступен.

script.onerror

Ошибки, которые возникают во время загрузки скрипта, могут быть отслежены с помощью события error .

Например, давайте запросим скрипт, которого не существует:

let script = document.createElement('script'); script.src = "https://example.com/404.js"; // такого файла не существует document.head.append(script); script.onerror = function() < alert("Ошибка загрузки " + this.src); // Ошибка загрузки https://example.com/404.js >;

Обратите внимание, что мы не можем получить описание HTTP-ошибки. Мы не знаем, была ли это ошибка 404 или 500, или какая-то другая. Знаем только, что во время загрузки произошла ошибка.

Обработчики onload / onerror отслеживают только сам процесс загрузки.

Ошибки обработки и выполнения загруженного скрипта ими не отслеживаются. Чтобы «поймать» ошибки в скрипте, нужно воспользоваться глобальным обработчиком window.onerror .

Другие ресурсы

События load и error также срабатывают и для других ресурсов, а вообще, для любых ресурсов, у которых есть внешний src .

let img = document.createElement('img'); img.src = "https://js.cx/clipart/train.gif"; // (*) img.onload = function() < alert(`Изображение загружено, размеры $x$`); >; img.onerror = function() < alert("Ошибка во время загрузки изображения"); >;

Однако есть некоторые особенности:

  • Большинство ресурсов начинают загружаться после их добавления в документ. За исключением тега . Изображения начинают загружаться, когда получают src (*) .
  • Для событие load срабатывает по окончании загрузки как в случае успеха, так и в случае ошибки.

Такое поведение сложилось по историческим причинам.

Ошибка в скрипте с другого источника

Есть правило: скрипты с одного сайта не могут получить доступ к содержимому другого сайта. Например, скрипт с https://facebook.com не может прочитать почту пользователя на https://gmail.com .

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

Это правило также касается ресурсов с других доменов.

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

Для примера давайте возьмём мини-скрипт error.js , который состоит из одного-единственного вызова функции, которой не существует:

Теперь загрузим этот скрипт с того же сайта, на котором он лежит:

  

Мы видим нормальный отчёт об ошибке:

Uncaught ReferenceError: noSuchFunction is not defined https://javascript.info/article/onload-onerror/crossorigin/error.js, 1:1

А теперь загрузим этот же скрипт с другого домена:

  

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

Зачем нам могут быть нужны детали ошибки?

Существует много сервисов (и мы можем сделать наш собственный), которые обрабатывают глобальные ошибки при помощи window.onerror , сохраняют отчёт о них и предоставляют доступ к этому отчёту для анализа. Это здорово, потому что мы можем увидеть реальные ошибки, которые случились у наших пользователей. Но если скрипт – с другого домена, то информации об ошибках в нём почти нет, как мы только что видели.

Похожая кросс-доменная политика (CORS) внедрена и в отношении других ресурсов.

Чтобы разрешить кросс-доменный доступ, нам нужно поставить тегу атрибут crossorigin , и, кроме того, удалённый сервер должен поставить специальные заголовки.

Существует три уровня кросс-доменного доступа:

  1. Атрибут crossorigin отсутствует – доступ запрещён.
  2. crossorigin=»anonymous» – доступ разрешён, если сервер отвечает с заголовком Access-Control-Allow-Origin со значениями * или наш домен. Браузер не отправляет авторизационную информацию и куки на удалённый сервер.
  3. crossorigin=»use-credentials» – доступ разрешён, если сервер отвечает с заголовками Access-Control-Allow-Origin со значением наш домен и Access-Control-Allow-Credentials: true . Браузер отправляет авторизационную информацию и куки на удалённый сервер.

Почитать больше о кросс-доменных доступах вы можете в главе Fetch: запросы на другие сайты. Там описан метод fetch для сетевых запросов, но политика там точно такая же.

Такое понятие как «куки» (cookies) не рассматривается в текущей главе, но вы можете почитать о них в главе Куки, document.cookie.

В нашем случае атрибут crossorigin отсутствовал. Поэтому кросс-доменный доступ был запрещён. Давайте добавим его.

Мы можем выбрать «anonymous» (куки не отправляются, требуется один серверный заголовок) или «use-credentials» (куки отправляются, требуются два серверных заголовка) в качестве значения атрибута.

Если куки нас не волнуют, тогда смело выбираем «anonymous» :

  

Теперь при условии, что сервер предоставил заголовок Access-Control-Allow-Origin , всё хорошо. У нас есть полный отчёт по ошибкам.

Итого

Изображения , внешние стили, скрипты и другие ресурсы предоставляют события load и error для отслеживания загрузки:

Единственное исключение – это : по историческим причинам срабатывает всегда load вне зависимости от того, как завершилась загрузка, даже если страница не была найдена.

Событие readystatechange также работает для ресурсов, но используется редко, потому что события load/error проще в использовании.

Задачи

Загрузите изображения с колбэком

Обычно изображения начинают загружаться в момент их создания. Когда мы добавляем на страницу, пользователь не увидит его тут же. Браузер сначала должен его загрузить.

Чтобы показать изображение сразу, мы можем создать его «заранее»:

let img = document.createElement('img'); img.src = 'my.jpg';

Браузер начнёт загружать изображение и положит его в кеш. Позже, когда такое же изображение появится в документе (не важно как), оно будет показано мгновенно.

Создайте функцию preloadImages(sources, callback) , которая загружает все изображения из массива sources и, когда все они будут загружены, вызывает callback .

В данном примере будет показан alert после загрузки всех изображений.

function loaded() < alert("Изображения загружены") >preloadImages(["1.jpg", "2.jpg", "3.jpg"], loaded);

В случае ошибки функция должна считать изображение «загруженным».

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

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

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

  1. Создадим img для каждого ресурса.
  2. Добавим обработчики onload/onerror для каждого изображения.
  3. Увеличиваем счётчик при срабатывании onload или onerror .
  4. Когда значение счётчика равно количеству ресурсов – тогда вызываем callback() .

Источник

JavaScript onload

Summary: in this tutorial, you will learn how to handle the load event that fires on the document, image, and script elements in JavaScript.

The window’s load event

For the window object, the load event is fired when the whole webpage (HTML) has loaded fully, including all dependent resources, including JavaScript files, CSS files, and images.

To handle the load event, you register an event listener using the addEventListener() method:

window.addEventListener('load', (event) => < console.log('The page has fully loaded'); >);Code language: JavaScript (javascript)

Or use the onload property of the window object:

window.onload = (event) => < console.log('The page has fully loaded'); >;Code language: JavaScript (javascript)

If you maintain a legacy system, you may find that the load event handler is registered in of the body element of the HTML document, like this:

html> html> head> title>JS load Event Demo title> head> body onload="console.log('Loaded!')"> body> html>Code language: HTML, XML (xml)

It’s a good practice to use the addEventListener() method to assign the onload event handler whenever possible.

The image’s load event

The load event also fires on images. To handle the load event on images, you use the addEventListener() method of the image elements.

The following example uses the load event handler to determine if an image, which exists in the DOM tree, has been completely loaded:

html> html> head> title>Image load Event Demo title> head> body> img id="logo"> script> let logo = document.querySelector('#logo'); logo.addEventListener('load', (event) => < console.log('Logo has been loaded!'); >); logo.src = "logo.png"; script> body> html> Code language: HTML, XML (xml)

You can assign an onload event handler directly using the onload attribute of the element, like this:

img id="logo" src="logo.png" onload="console.log('Logo loaded!')"> Code language: HTML, XML (xml)

If you create an image element dynamically, you can assign an onload event handler before setting the src property as follows:

window.addEventListener('load' () => < let logo = document.createElement('img'); // assign and onload event handler logo.addEventListener('load', (event) => < console.log('The logo has been loaded'); >); // add logo to the document document.body.appendChild(logo); logo.src = 'logo.png'; >); Code language: JavaScript (javascript)
  • First, create an image element after the document has been fully loaded by placing the code inside the event handler of the window’s load event.
  • Second, assign the onload event handler to the image.
  • Third, add the image to the document.
  • Finally, assign an image URL to the src attribute. The image will be downloaded to the element as soon as the src property is set.

The script’s load event

The element also supports the load event slightly different from the standard ways. The script’s load event allows you to check if a JavaScript file has been completely loaded.

Unlike images, the web browser starts downloading JavaScript files only after the src property has been assigned and the element has been added to the document.

The following code loads the app.js file after the page has been completely loaded. It assigns an onload event handler to check if the app.js has been fully loaded.

window.addEventListener('load', checkJSLoaded) function checkJSLoaded( ) < // create the script element let script = document.createElement('script'); // assign an onload event handler script.addEventListener('load', (event) => < console.log('app.js file has been loaded'); >); // load the script file script.src = 'app.js'; document.body.appendChild(script); >Code language: JavaScript (javascript)

Summary

  • The load event occurs when the document has been completely loaded, including dependent resources like JavaScript files, CSS files, and images.
  • The and elements also support the load event.
  • Use the addEventListener() method to register an onload event handler.

Источник

Читайте также:  Data structures and algorithms in java programs
Оцените статью