Image onload error

On this page, we are going to explore the issues of tracking the resource loading along with the primary events, such as onload and onerror used for them.

The browser helps to track the loading of external resources, such as pictures, scripts and more.

Two primary events are used for that purpose:

  • onload: it supposes a successful load.
  • onerror: it means that an error has occurred.

Imagine that you should load a third-party script and call a function residing there, as illustrated below:

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

To run the function declared inside that script, you should wait until the script loads and only then call it.

Please note, that here you could also use JavaScript modules, but they are not widely used by third-party libraries.

Script.onload

The load event is the main helper here. It occurs once the was already loaded and executed.

Here is an example of the load event:

w3docs logo
javascript loading script file

let script = document.createElement(‘script’);
// any script can be loading from any domain
script.src = «https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.js»
document.head.append(script);
script.onload = function () {
// the script generates an auxiliary function
alert(_); // the function available
};

So, Script variables and run functions can be used in download.

But, the loading may fail. Note that there isn’t any such script (error 404) or the server is done.

Let’s see what happens in such a circumstance.

Script.onerror

Errors occurring during the script loading are tracked in an error event.

Let’s take a look at an example of requesting a non-existing script:

w3docs logo
javascript loading script onerror

let script = document.createElement(‘script’);
script.src = «https://example.com/404.js»; // no such script
document.head.append(script);
script.onerror = function () {
alert(«Loading an error » + this.src); // Loading an error https://example.com/404.js
};

Please, take into account that the details of the HTTP error are not available here: you can’t know whether it’s an error 404, 500 or anything else.

Another important thing to note: the onload and onerror events track only the loading itself. In other words, errors occurring during the script processing and execution are out of the framework. So, if a script loaded efficiently, then onload happens, even if it includes some programming errors. For tracking the script errors, you can use a global handler called window.onerror.

The load and error events operate for any other resources that have an external src, like in the example below:

w3docs logo
javascript load and error events

let img = document.createElement(‘img’);
img.src = «https://www.w3docs.com/uploads/media/default/0001/05/9eb9e9cba721ba3bb5e653751449173197f2924a.png»; // (*)
img.onload = function () {
alert(`Image loaded, size ${img.width}x${img.height}`);
};
img.onerror = function () {
alert(«An error occurred while loading image»);
};

But, note that several resources begin loading once they are added to the document. The <img> is an exception to the rule. It begins to load after getting a src (*).

For <iframe>, the iframe.onload event occurs once the iframe loading is over. It is both for the efficient load and in case of an error.

Scripts from one site don’t have access to the scripts of the other one. For example, a script at https://www.instagram.com/ can’t read the user’s mailbox at https://gmail.com.

In other words, one origin (domain/port/protocol) can’t access the content of the other one. Even in case of having a subdomain, these are considered different origins.

The rule above affects the resources from other domains, as well.
An example of a script error.js consisting of a single (bad) function call is demonstrated below:

//  error.js
noSuchFunction();

If you try loading it from the same site where it’s located, you will have this:

<script>
  window.onerror = function(message, url, line, col, errorObj) {
    alert(`${message}n${url}, ${line}:${col}`);
  };
</script>
<script src="/article/onload-onerror/crossorigin/error.js"></script>

A good error report can be seen here:

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

The example of loading the same script from another domain will look like this:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    <script>
      window.onerror = function(message, url, line, col, errorObj) {
        alert(`${message}n${url}, ${line}:${col}`);
      };
    </script>
    <script src="https://cors.javascript.info/article/onload-onerror/crossorigin/error.js"></script>
  </body>
</html>

So, there is a different report here:

Script error.
, 0:0

There can be different details, depending on the browser. However, idea remains the same: any information regarding the internals of a script is hidden. The reason is that it is from a different domain.

Still, it is important to know details about errors.

There are services, listening for global errors using window.onerror, saving errors and providing an interface to access and analyze them. So, they make it possible to see real errors, triggered by the users. But, if a script has another origin, no more information will be available.

For allowing cross-origin access, the <script> tag should have the crossorigin attribute. The remote server has to provide specific headers.

Three levels of cross-origin access exist:

  1. No crossorigin attribute — the access is not allowed.
  2. For crossorigin="anonymous" the access is allowed, in case the server responds with the header Access-Control-Allow-Origin including or the origin. Any authorization information or cookies are sent to the remote server.
  3. crossorigin="use-credentials": the access is allowed in case the server sends back the Access-Control-Allow-Origin header with the origin and Access-Control-Allow-Credentials: true. Authorization information and cookies are sent to the remote server.

In case of not having any crossorigin attribute, the access will be prohibited.

So, let’s see how to add it.

You can choose between "anonymous" and "use-credentials".
In the event of not caring about the cookies, "anonymous" is the way to go, like this:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    <script>
      window.onerror = function(message, url, line, col, errorObj) {
        alert(`${message}n${url}, ${line}:${col}`);
      };
    </script>
    <script crossorigin="anonymous" src="https://cors.javascript.info/article/onload-onerror/crossorigin/error.js"></script>
  </body>
</html>

Supposing that the server provides Access-Control-Allow-Origin header, the full error report is ready.

Resources such as scripts, styles, images provide load and error events for tracking their loading:

  • The load event happens on a successful load.
  • The error event occurs on a failed load.

, there is an exception: <iframe>, which only triggers the load, for each load completion, even if the page is not found. For resources, you can also use the readystatechange event. But it is used rarely as the load and error events are simpler and handier.

  1. the .onload Event in JavaScript
  2. the image.onload Event in JavaScript
  3. the image.onload Event in HTML

Image Onload Event in JavaScript

This article will discuss how we can handle the .onload event in JavaScript. We will learn how to create an alert box using JavaScript when an image has been uploaded.

We will also find out how we can check whether an image is loaded or not using JavaScript by creating an alert box.

the .onload Event in JavaScript

The .onload event occurs only when an object has been loaded. The .onload event is mainly used within the element body to execute a script once a web page has loaded all contents, including images, script, CSS files, etc.

The browsers used will allow us to track the loading of external resources such as images, scripts, iframes, etc. When we upload an image, and if it is saved in the browser cache, the onload event will be fired.

How can we create an alert box that displays when an image is loaded regardless of whether the image is cached?

We need to create an alert box that will display a message that says The image is loaded successfully when the onload event fires on an image. We can tackle this problem using JavaScript and HTML.

the image.onload Event in JavaScript

Using JavaScript, we can check whether an image has been completely loaded or not. We will use the HTMLimageElement interface’s complete attribute.

This attribute returns true when the image has been fully uploaded and false otherwise. We have the naturalWidth and naturalHeight properties in JavaScript, and we can use either.

We used .naturalWidth in the example code, which will return true if the image loads successfully and returns 0 if not.

HTML code:

<!DOCTYPE html>
<html>
  <head>
    <title>Onload event using Javascript</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
      <h1 class="title">Onload event using Javascript</h1>
      <script src="script.js"></script>
      <img src="https://secure.gravatar.com/avatar?d=wavatar">
  </body>
</html>

JavaScript code:

window.addEventListener("load", event => {
    var image = document.querySelector('img');
    var isLoadedSuccessfully = image.complete && image.naturalWidth !== 0;
    alert(isLoadedSuccessfully);
});

If we run this code, it will return true, which means the image is loaded successfully.

You can see the live demo of the example code above by clicking here.

the image.onload Event in HTML

In case we don’t want to use JavaScript, we can use HTML attributes to check whether an image has loaded or not. In HTML, we can use onload and onerror attributes.

In HTML, the onload attribute fires when the image is loaded successfully, while the onerror attribute fires if an error happens while loading an image.

We used onload and onerror attributes in the following code. So, with the help of these attributes, we can create an alert box that will display a message that says The image is loaded successfully when the image is loaded.

If an error occurs while loading the image, it will display a message that says the image is not loaded.

HTML code:

<!DOCTYPE html>
<html>
  <head>
    <title>Onload event using HTML</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
      <h1 class="title">Onload event using HTML </h1>
      <p id="currentTime"></p>
      <script src="script.js"></script>
      <img src="https://secure.gravatar.com/avatar?d=wavatar"
      onload="javascript: alert('The image is loaded successfully')"
      onerror="javascript: alert('Image is not loaded')" />
  </body>
</html>

If we run the code, it will display an alert message that The image is loaded successfully.

Click here to see the live demo of the given example code.

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

Допустим, у нас на сервере лежит файл: https://svgshare.com/i/7ck.svg

Рассмотрим следующий пример. Сколько изображений будет показано?

<html>
  <head>
    <meta charset="utf-8" content="text/html; charset=utf-8"/>
    <style>
      html, body {
        height: 100px;
        width: auto;
      }
    </style>
  </head>

  <body>
    <div class="achievement-image">
      <img src="https://svgshare.com/i/7ck.svg">
      <img src="//svgshare.com/i/7ck.svg">
      <img src="svgshare.com/i/7ck.svg">
      <img src="7ck.svg">
    </div>
  </body>
</html>

Одно, максимум два.

Ответ зависит от того, как открыть этот код. Если разместить его на сервере, вроде https://myserver.com, мы увидим первые два изображения. Если же сохранить его локально и открыть в браузере html файл — только одно. Для ясности я покажу, во что превращаются ссылки из атрибута src в обоих случаях.

В случае сервера https://myserver.com имеем:

https://svgshare.com/i/7ck.svg
https://svgshare.com/i/7ck.svg
https://myserver.com/svgshare.com/i/7ck.svg
https://myserver.com/7ck.svg

В случае локального файла из file:///home/leksa/html/example.html имеем:

https://svgshare.com/i/7ck.svg
file://svgshare.com/i/7ck.svg
file:///home/leksa/html/svgshare.com/i/7ck.svg
file:///home/leksa/html/7ck.svg

Для отслеживания и реакции на успешную или неуспешную загрузку изображения HTML предлагает нам два события, доступных для тега img: onload и onerror. Как следует из названия, первое событие возникает, когда изображение было загружено, а второе, когда что-то пошло не так.

Модифицируем наш код и проверим работу этих событий в консоли браузера.

<div class="achievement-image">
  <img src="https://svgshare.com/i/7ck.svg" 
       onload="console.log('load 1')" onerror="console.log('error 1')">
  <img src="//svgshare.com/i/7ck.svg"
       onload="console.log('load 2')" onerror="console.log('error 2')">
  <img src="svgshare.com/i/7ck.svg"
       onload="console.log('load 3')" onerror="console.log('error 3')">
  <img src="7ck.svg"
       onload="console.log('load 4')" onerror="console.log('error 4')">
</div>

Как и ожидалось, последние три изображения спровоцировали событие onerror. Назначим на него свой обработчик (потребуется подключить библиотеку JQuery) и подменим атрибут src на адрес желаемого изображения.

$(document).ready(function() {
  $(".image-container img").each(function(key, item) {
    $(item).on("error", function() {
      showDefaultImage(this);
    }).attr('src', $(item).attr('src'));
  });
});

function showDefaultImage(img) {
  $(img).attr('src', 'https://svgshare.com/i/7bo.svg');
  $(img).off("error");
}

В интернете есть много примеров решения данной задачи, однако есть один важный момент, о котором часто забывают. Хочу обратить ваше внимание на вызов

$(item).on(...).attr('src', $(item).attr('src'))

после назначения обработчика. Атрибут src устанавливается в то же значение, в котором он изначально был. Зачем это нужно?

Для ответа на этот вопрос вернёмся к последовательности возникновения событий.

  • Событие DOMContentLoaded возникает, когда построено дерево DOM, а также загружены и выполнены все скрипты. При этом внешние ресурсы, включая изображения и стили, могут быть ещё не загружены.
  • Событие load объекта window возникает, когда страница со всеми ресурсами была загружена.
  • Событие ready специфично для JQuery, согласно документации, оно аналогично событию DOMContentLoaded, то есть не дожидается загрузки мультимедийного контента.

Откроем код, приведённый ниже, и посмотрим на вывод в консоли браузера.

<html>
  <head>
    <meta charset="utf-8" content="text/html; charset=utf-8"/>

    <style>
      html, body {
        height: 100px;
        width: auto;
      }
    </style>

    <script>
      $(document).on("DOMContentLoaded", function() {
        console.log("document loaded");
      });
      $(window).on("load", function() {
        console.log("content loaded");
      });
      $(document).ready(function() {
        console.log(“JQuery ready”);
      });
    </script>
  </head>

  <body>
    <div class="image-container">
      <img src="https://svgshare.com/i/7ck.svg" 
           onload="console.log('load 1')" onerror="console.log('error 1')">
      <img src="//svgshare.com/i/7ck.svg"
           onload="console.log('load 2')" onerror="console.log('error 2')">
      <img src="svgshare.com/i/7ck.svg"
           onload="console.log('load 3')" onerror="console.log('error 3')">
      <img src="7ck.svg"
           onload="console.log('load 4')" onerror="console.log('error 4')">
    </div>
  </body>
</html>


 

Тут есть кое-что интересное. Вопреки ожиданием, событие ready срабатывает после загрузки всего контента (включая изображения), аналогично событию load. А значит, на момент создания обработчиков, события error и load уже произошли, и обработчики никогда не будут вызваны.

В браузере firefox картина примерно такая же.

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

Окончательный вариант кода приведён ниже (живой пример).
 

<html>
  <head>
    <meta charset="utf-8" content="text/html; charset=utf-8"/>

    <style>
      html, body {
        height: 100px;
        width: auto;
      }
    </style>

    <script>
      // $(document).on("DOMContentLoaded", function() {
      $(document).ready(function() {
        $(".image-container img").each(function(key, item) {
          $(item).on("error", function() {
            showDefaultImage(this);
          }).attr('src', $(item).attr('src'));
        });
      });

      function showDefaultImage(img) {
        $(img).attr('src', 'https://svgshare.com/i/7bo.svg');
        $(img).off("error");
      }
    </script>
  </head>

  <body>
    <div class="image-container">
      <img src="https://svgshare.com/i/7ck.svg">
      <img src="//svgshare.com/i/7ck.svg">
      <img src="svgshare.com/i/7ck.svg">
      <img src="7ck.svg">
    </div>
  </body>
</html>

I was recently coding an application that would inject an image into the page and then execute a given function when the image’s onLoad event fires. My code was working everywhere except Internet Explorer. That wasn’t all together shocking initially but the fact that even IE8 was failing to the fire the onLoad event was discouraging. Here’s what my code looked like:

var img = new Element('img',{
	alt: this.title ? this.title.get('html') : this.options.url,
	src: this.options.url,
	events: {
		error: function() {
			this.messageBox.set('html',this.options.errorMessage);
			img.dispose();
		}.bind(this),
		load: function() {
			img.setStyle('display','');
			this.unfade();
			if(!this.footer) {
				img.setStyle('cursor','pointer').addEvent('click',this.close.bind(this));
			}
		}.bind(this)
	},
	styles: {
		display: 'none'
	}
}).inject(this.messageBox);

On a hunch I detached the «src» assignment and coded that as a separate statement:

var img = new Element('img',{
	alt: this.title ? this.title.get('html') : this.options.url,
	events: {
		error: function() {
			this.messageBox.set('html',this.options.errorMessage);
			img.dispose();
		}.bind(this),
		load: function() {
			img.setStyle('display','');
			this.unfade();
			if(!this.footer) {
				img.setStyle('cursor','pointer').addEvent('click',this.close.bind(this));
			}
		}.bind(this)
	},
	styles: {
		display: 'none'
	}
});
img.set('src',this.options.url).inject(this.messageBox); //for ie

Not too surprisingly that worked. The reason my modification worked is that image was being pulled from cache as soon as the SRC attribute was set, thus «beating» the event assignment to the punch. Keep this in mind if you run into onLoad issues with your images.

Website performance monitoring

Website performance monitoring

Website performance monitoring

Website performance monitoring

Incredible Demos

  • MooTools Image Preloading with Progress Bar

    MooTools Image Preloading with Progress Bar

    The idea of image preloading has been around since the dawn of the internet. When we didn’t have all the fancy stuff we use now, we were forced to use ugly mouseover images to show dynamism. I don’t think you were declared an official…

  • CSS Triangles

    CSS Triangles

    I was recently redesigning my website and wanted to create tooltips.  Making that was easy but I also wanted my tooltips to feature the a triangular pointer.  I’m a disaster when it comes to images and the prospect of needing to make an image for…

Понравилась статья? Поделить с друзьями:
  • Imgcoresocket error 10013
  • Image install error lenovo
  • Imgburn ошибка i o error
  • Image inspect error
  • Iisnode encountered an error when processing the request