log if image loads or fails to

by Laurens Maneschijn

HTML

<p>
	A little proof of concept to test if we can log failing image load. see console and javascript panel.
</p>
<img src="idontexist.png">
<img src="https://placekitten.com/200/300">

JavaScript

if (console && console.clear) {
	console.clear();
}
init();

function init() {
//	// This does not work: (load/error/abort events do not seem to bubble up)
//	$(document).on('load error abort', 'img', function(e){
//		console.log(1, this.src, e.type);
//	});

	// This works, but impractical for all new images appearing later:
//	$('img').bind('load error abort', function(e){
//		console.log(2, this.src, e.type);
//	});

//  // This works, also for img elements created later:
//	// use capturing events: addEventListener(..., ..., true)
//	// https://stackoverflow.com/questions/14983988/is-bubbling-available-for-image-load-events
//	// https://stackoverflow.com/a/24611104/1158769
//	document.addEventListener(
//		'error',
//		function(e){
//			if( e.target.tagName == 'IMG'){
//				console.log(3, e.target.src, e.type);
//			}
//		},
//		true // <-- useCapture
//	);

	// jQuery.on() with added captureEvent = true: this works:
	$on(document, 'load error abort', 'img', function(e){
		console.log(4, this.src, e.type);
	}, true); // note the captureEvent = true here

	// elements created after event listener is set should also work:
	$(document.body).append(`<img src="idontexist2.png">`);
	$(document.body).append(`<img src="idontexist2.png">`);
	$(document.body).append(`<img src="https://placekitten.com/200/200">`);
	$(document.body).append(`<img src="https://placekitten.com/200/200">`);
}

// native js variant on jQuery.on() , with additional useCapture parameter
// also see http://youmightnotneedjquery.com/#delegate
// $(document).on(eventName, elementSelector, handler);
function $on(eventTarget, eventName, elementSelector, handler, usecapture){
	if (typeof eventTarget === 'undefined' || ! eventTarget) {
		eventTarget = document; // default fallback
	}
	var eventNames = (''+eventName).trim().split(/\s+/); // support multiple events seperated by whitespace
	eventNames.forEach(function(eventName){
		eventTarget.addEventListener(eventName, function(e) {
			for (var target...