Reputation: 1504
For example I have some image src.
I open this page in the new chrome tab.
On the page I have script that runs on DOMContentLoaded
event:
document.addEventListener('DOMContentLoaded', function() {
console.log('done');/*call to init function*/
}, false);
However in this case the event is never fire. On the regular page with full CSS and hierarchical DOM tree all works fine. Only in the case with open image alone in the new tab something goes wrong or I miss some details in using this event . Will be glad of any help or explanation
UPDATE
According to this answer , the DOMContentLoaded event fires only on document.readyState=interactive
, but the image view page never gave this status... So my question is there is any workaround of this issue?
Upvotes: 1
Views: 673
Reputation: 8118
To answer the question, let's decode the question first from the start to set the context right and try to reach a reasonable solution.
Part 1: INITIAL QUESTION:
On the regular page with full CSS and hierarchical DOM tree, all works fine. Only in the case with open image alone in the new tab, something goes wrong or I miss some details in using this event.
My response to Part-1 (for what I understood):
The issue is related to the DOMContentLoaded event not firing when an image is opened alone in a new tab. When an image is directly opened, it does not create an HTML document context where DOMContentLoaded would be applicable. Instead, the browser treats it as a standalone image.
Handling Both Scenarios
Scenario 1: Image in an HTML Document
If you are dealing with an HTML document that includes an image, the DOMContentLoaded event should work as expected.
Scenario 2: Standalone Image
If you open the image directly in a browser tab (not embedded in an HTML document), DOMContentLoaded will not fire because there is no HTML document to load.
Handling Both Scenarios
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>Image Load Test</title>
</head>
<body>
<img
src="https://images.pexels.com/photos/1000366/pexels-photo-1000366.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2"
alt="random image"
/>
<script>
console.log('JS loading ...')
document.addEventListener(
'DOMContentLoaded',
function () {
console.log('DOMContentLoaded event fired')
},
false
)
window.addEventListener('load', function () {
if (document.contentType && document.contentType.startsWith('image/')) {
console.log('Image loaded in a standalone context')
} else {
console.log('Window load event fired')
}
})
</script>
</body>
</html>
Explanation:
DOMContentLoaded Event:
This event is added to handle regular HTML documents. It fires when the HTML document has been completely loaded and parsed.
window.addEventListener('load'):
This event is added to handle scenarios where an image is opened directly in a new tab.
It checks if the document's content type starts with 'image/'. If so, it logs a message indicating that an image was loaded in a standalone context.
If the content is not an image, it logs a different message.
PART-2: UPDATE QUESTION
UPDATE: According to this answer, the DOMContentLoaded event fires only on document.readyState=interactive, but the image view page never gave this status... So my question is there is any workaround for this issue?
Response:
The issue arises because the DOMContentLoaded
event fires only when document.readyState
is 'interactive
', which doesn't occur in standalone image contexts. As a result, the event fails to trigger.
A workaround is to use the load event for images, as it ensures proper initialization after the image has fully loaded. Here's how you can implement it:
Workaround
Use the load event for images, ensuring the initialisation logic runs correctly regardless of the content type:
<script>
console.log('JS loading ...')
document.addEventListener(
'DOMContentLoaded',
function () {
console.log('DOMContentLoaded event fired')
init()
},
false
)
window.addEventListener('load', function () {
if (document.contentType && document.contentType.startsWith('image/')) {
console.log('Image loaded in a standalone context')
} else {
console.log('Window load event fired')
}
init()
})
function init() {
console.log('Initialization function called')
// Your initialization logic here
}
</script>
By utilizing the load event, you ensure that your initialization logic runs regardless of the context in which the image is loaded. This addresses the issue effectively.
Upvotes: -2
Reputation: 13097
The problem is in modern browsers images are loaded asynchronously, so the DOMContentLoaded event fires before the images are fully read in. Looking at your fiddle you don’t have a <html>
or <body>
elements, so I expect this is why you don’t get it at all, or it could be that their is so little content that it fires before you JS has time to run.
There are two possible work arounds to this issue.
ResizeObserver If you don’t predefined the size of the image, the element will resize as the images loads and you can detect this by adding a resizeObserver to the image element, or maybe even the body tag of the document if and only if the image is in the main document flow.
Load event of the image
The image element has it’s own events for load
and error
and you could listen for these instead.
element.addEventListener('load', imageLoaded, false)
element.addEventListener('error', imageError, false)
This is going to be the more robust approach.
Upvotes: 0
Reputation: 3689
all works fine, http://jsfiddle.net/k1L6mwzs/2/
in jsfiddle you had onLoad
event setted in list at the left side of screen, and your js
code is called after it.
But DOMContentLoaded
event fires BEFORE onload
, thats why you don't see your alert.
(if your problem is not in jsfiddle, please show us full code of page (html) and script. You are also use jQuery -> for what?)
Upvotes: -2