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
?
onparse
does not existonload
does 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
onparse
event; and - use a custom
data-onparse
attribute to fire theonparse
event
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>