Access Web Component Content With A querySelector() Via setTimeout()
Note
This post covers an issue I had with putting a tag in the
of my document directly and without
type="module"
. I've since moved the tags to just before the
tag and added
type="module"
which solves the issue for me.
If you do that, you should pretty much be able to ignore this post.
Introduction
I decided to try Web Components for the code blocks on my site1. I looked at a few component examples2 3 that use querySelector()
to access content but I couldn't get the method to work for my code.
The reason was that the examples put the that defines the component after the corresponding custom element was used on the page. I was trying to put the definition in the
of the document. The result is that the DOM elements weren't fully loaded when the elements initialized.
The solution I found4 is to wrap the contents of connectedCallback()
in a setTimeout()
call.
Working Example
Here's an example in action. Check the console and you'll see "Working Node Count: 2" for the two If you don't use I've played with Web Components a few times before and they just kinda didn't make sense to me. It seemed to complicated to do something basic like access the original content inside them. With this new understanding of how to do that, I'm way more excited about them than I have been in the past. I'm even more excited about Web Components now that I know I don't have to do this hack. It's one of those silly things where I was doing something a little differently that caused an issue, but it wasn't clear to me that what I was doing was weird. Tech is like that sometimes. I found this solution after banging my head into the desk for a few hours trying to figure out why my code wasn't working. It's solving the problem I had, but I haven't run it enough to know if there are other issues. Based on what I've read, it seems like things should be fine, but I want to through the warning out just in case. According to the Danny Engelman article the There are also more details in the article about how/why this works if you want to investigate further.
element.
JavaScript
customElements.;
The Problem This Fixes
setTimeout()
the NodeList
will be empty. Check the console for this output and you'll see "Problem Node Count: 0" NOTE: This is no longer the case since I moved the script to before the closing body the problem no longer existsJavaScript
customElements.;
Original Conclusion
Updated Conclusion
Endnotes
setTime()
method only works up to a point. For example, if a page has too many DOM elements on it (the article suggest 1000+), the setTimeout()
may finish and fire before everything is loaded. The article covers potential fixes for that.References
Footnotes