I am loading some markup into a page, asynchronously, using Ajax.
I want to attach an EventListener to an <element> within that markup, such that when the element is parsed the EventListener fires.
What Event can I use for myEvent ?
onparsedoes not existonloaddoes exist, but we can't apply it to<h2>or<div>. We can only apply it to:<body><frame><iframe><img><input type="image"><link><script><style>
Are there any other candidate Events I might use?
Or any alternative approaches to ensuring that an EventListener fires when an element is parsed?
The best approach I have come across so far (albeit a little bit unorthodox) is the
<img src>hack
An <img> with an undeclared src attribute will trigger the onerror EventListener when it is parsed.
Consequently the following example works:
let myHeadingLoadEventTrigger = document.getElementById('my-heading-load-event-trigger');
const updateHeading = (e) => {
let myHeading = e.target.previousElementSibling;
if (true) { // <= CONDITION HERE
myHeading.textContent = 'My Updated Heading';
}
// Modern alternative to document.body.removeChild(e.target);
e.target.remove();
}
myHeadingLoadEventTrigger.addEventListener('error', updateHeading, false);
<h2>My Heading</h2>
<img id="my-heading-load-event-trigger" src />
Solution:
Although a native onparse event does not exist, I can:
- write my own
onparseevent; and - use a custom
data-onparseattribute to fire theonparseevent
Working Example:
// Create (homemade) parse event
let parseEvent = new Event('parse');
// Create Initialising Function which can be run at any time
const initialiseParseableElements = () => {
// Get all the elements which need to respond to an onparse event
let elementsWithParseEventListener = document.querySelectorAll('[data-onparse]');
// Attach Event Listeners and Dispatch Events
elementsWithParseEventListener.forEach((elementWithParseEventListener) => {
elementWithParseEventListener.addEventListener('parse', updateParseEventTarget, false);
elementWithParseEventListener.dataset.onparsed = elementWithParseEventListener.dataset.onparse;
elementWithParseEventListener.removeAttribute('data-onparse');
elementWithParseEventListener.dispatchEvent(parseEvent);
});
}
// Callback function for the Parse Event Listener
const updateParseEventTarget = (e) => {
switch (e.target.dataset.onparsed) {
case ('my-heading') : e.target.textContent = 'My Updated Heading'; break;
}
}
// Run Initialising Function
initialiseParseableElements();
<h2 data-onparse="my-heading">My Heading</h2>