In JavaScript, events are actions that happen in an app. They are triggered by various things like inputs being entered, forms being submitted, changes in an element like resizing, or errors that happen when an app is running, etc. We can assign an event handler to take action on these events.
Events that happen to DOM elements can be handled by assigning an event handler to properties of the DOM object for the corresponding events. In this article, we will look at the onloadedmetadata
property of a media DOM element, and the onloadend
property of an XmlHttpRequest object.
onloadedmetadata
The onloadedmetadata
property of a media DOM element lets us set an event handler function that’s run when the loademetadata
event is fired. Whenever media metadata is loaded this event will fire.
For example, we can use it by first adding a video tag to our HTML code:
<video src='https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4'></video>
Then in the corresponding JavaScript code, we can set an event handler function to the onloadedmetadata
property as we do in the following code:
const video = document.querySelector('video');
video.onloadedmetadata = (e) => {
console.log(e);
}
Then we get the video’s metadata in the srcElement
property of the e
parameter, which is an Event
object. We get something like:
clientHeight: 240
clientLeft: 0
clientTop: 0
clientWidth: 320
contentEditable: "inherit"
controls: false
controlsList: DOMTokenList [value: ""]
crossOrigin: null
currentSrc: "https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4"
currentTime: 0
dataset: DOMStringMap {}
defaultMuted: false
defaultPlaybackRate: 1
dir: ""
disablePictureInPicture: false
disableRemotePlayback: false
draggable: false
duration: 368.2
elementTiming: ""
ended: false
enterKeyHint: ""
error: null
firstChild: null
firstElementChild: null
height: 0
hidden: false
id: ""
innerHTML: ""
innerText: ""
inputMode: ""
isConnected: true
isContentEditable: false
lang: ""
lastChild: null
lastElementChild: null
localName: "video"
loop: false
mediaKeys: null
muted: false
namespaceURI: "[http://www.w3.org/1999/xhtml](http://www.w3.org/1999/xhtml)"
networkState: 1
nextElementSibling: script
nextSibling: text
nodeName: "VIDEO"
nodeType: 1
nodeValue: null
nonce: ""
offsetHeight: 240
offsetLeft: 8
offsetParent: body
offsetTop: 8
offsetWidth: 320
...
outerHTML: "<video src="https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4"></video>"
outerText: ""
ownerDocument: document
parentElement: body
parentNode: body
part: DOMTokenList [value: ""]
paused: true
playbackRate: 1
played: TimeRanges {length: 0}
playsInline: false
poster: ""
prefix: null
preload: "metadata"
previousElementSibling: null
previousSibling: text
readyState: 4
remote: RemotePlayback {state: "disconnected", onconnecting: null, onconnect: null, ondisconnect: null}
scrollHeight: 240
scrollLeft: 0
scrollTop: 0
scrollWidth: 320
seekable: TimeRanges {length: 1}
seeking: false
shadowRoot: null
sinkId: ""
slot: ""
spellcheck: true
src: "https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4"
srcObject: null
style: CSSStyleDeclaration {alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: "", …}
tabIndex: -1
tagName: "VIDEO"
textContent: ""
textTracks: TextTrackList {length: 0, onchange: null, onaddtrack: null, onremovetrack: null}
title: ""
translate: true
videoHeight: 240
videoWidth: 320
volume: 1
webkitAudioDecodedByteCount: 10995
webkitDecodedFrameCount: 4
webkitDisplayingFullscreen: false
webkitDroppedFrameCount: 0
webkitSupportsFullscreen: true
webkitVideoDecodedByteCount: 37638
Some useful metadata include the videoHeight
, which tells us the height of the video in pixels, videoWidth
, which tells us the width of the video in pixels, and duration
which tells us the length of the video in seconds. duration
is also available audio elements.
onloadend
The onloadend
property of an XMLHttpRequest object let us assign an event handler to it which is run whenever the loadend
event is fired. The loadend
event is fired whenever a request is completed, regardless of whether the request is completed successfully or not. If it’s successful then this event will be fired after the load
event. Otherwise, it’ll fire after the abort
or error
events.
For example, we can assign an event handler to the onloadend
event as we do in the following code:
const loadButtonSuccess = document.querySelector('.load.success');
const loadButtonError = document.querySelector('.load.error');
const loadButtonAbort = document.querySelector('.load.abort');
const log = document.querySelector('.event-log');
function handleLoadEnd(e) {
log.textContent = log.textContent + `${e.type}: ${e.loaded} bytes transferred\n`;
}
function addListeners(xhr) {
xhr.onloadend = handleLoadEnd;
}
function get(url) {
log.textContent = ''; const xhr = new XMLHttpRequest();
addListeners(xhr);
xhr.open("GET", url);
xhr.send();
return xhr;
}
loadButtonSuccess.addEventListener('click', () => {
get('https://jsonplaceholder.typicode.com/todos/1');
});
loadButtonError.addEventListener('click', () => {
get('https://somewhere.org/i-dont-exist'));
});
loadButtonAbort.addEventListener('click', () => {
get('https://jsonplaceholder.typicode.com/todos/1').abort();
});
In the code above, we have 3 buttons that run the click
event handler whenever each button is clicked. The ‘Load (success)’ button will run the get
function when it’s clicked. We’ll pass in a valid URL in the call for the get
function. The click handling for the ‘Load (success)’ button is done by the following block:
loadButtonSuccess.addEventListener('click', () => {
get('https://jsonplaceholder.typicode.com/todos/1');
});
The JSONPlaceholder has a test API that can serve any URL since it hosts a fake API so we can load it and not get any errors. Likewise, we have buttons for load a URL that’ll give an error, and another button to load a valid URL but then we abort the request. Once the XmlHttpRequest is finished, then the function we assigned to the onloadend
event handler, which is the handleLoadEnd
function, will be run.
The handleLoadEnd
function has one parameter, which is an Event
object with some data about the request that’s finished. In the function, we get the value of the type
property, which has the event type that’s fired, which should be loadend
. Also, we get the value of the loaded
property which has the number of bytes of data that’s been loaded.
Then in the HTML code, we add the elements listed in the querySelector
calls above:
<div class="controls">
<input class="load success" type="button" name="xhr" value="Load (success)" />
<br>
<input class="load error" type="button" name="xhr" value="Load (error)" />
<br>
<input class="load abort" type="button" name="xhr" value="Load (abort)" />
</div>
<textarea readonly class="event-log"></textarea>
We have 3 buttons to click on to load the successful HTTP request, an HTTP request with a non-existent URL, and an aborted HTTP request respectively. Then we display the event that’s fired and the number of bytes loaded.
The onloadedmetadata
property of a media DOM element lets us set an event handler function that’s run when the loademetadata
event is fired. Whenever media metadata is loaded this event will fire. We can get the metadata that’s loaded from the srcElement
property of the event
parameter of the event handler function.
The onloadend
property of an XMLHttpRequest object let us assign an event handler to it which is run whenever the loadend
event is fired. The loadend
event is fired whenever a request is completed, regardless of whether the request is completed successfully or not. If it’s successful then this event will be fired after the load
event. Otherwise, it’ll fire after the abort
or error
events. We can handle this event by setting the onloadend
property of an XMLHttpRequest object. The event handler function should have an event
parameter which is an event
object that has the type
property, which has the event type that’s fired, which should be loadend
. Also, we get the value of the loaded
property which has the number of bytes of data that’s been loaded.