<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>customelements &amp;mdash; Nat Knight</title>
    <link>http://natknight.xyz/tag:customelements</link>
    <description>Reflections, diversions, and opinions from a progressive ex-physicist programmer dad with a sore back.</description>
    <pubDate>Fri, 22 May 2026 15:49:40 -0700</pubDate>
    <item>
      <title>TIL: Accessing Content in Custom HTML Elements</title>
      <link>http://natknight.xyz/til-accessing-content-in-custom-html-elements</link>
      <description>&lt;![CDATA[#til #javascript #webdev #customelements&#xA;&#xA;I was working on a custom element today that replaces a textarea with CodeMirror in the UI while still updating the textarea in the background so that it can be submitted in a form. I ran across a wild footgun in custom elements.&#xA;&#xA;sStackOverflow eventually provided the solution./s There&#39;s a solution on stack overflow, but Danny Engleman wrote up a more thorough explanation.&#xA;&#xA;!--more--&#xA;&#xA;When you&#39;re creating a custom element you do most of your setup in a method called connectedCallback. Here you can read the content of the custom element, replace it with different elements, set up callback handlers, etc.&#xA;&#xA;Or so I thought.&#xA;&#xA;You can read the attributes of the node just fine, but if you try to read its contents you&#39;ll find they aren&#39;t there. The reason is that the connectedCallback fires when the opening tag of the custom element is parsed, so the contents aren&#39;t in the DOM yet.&#xA;&#xA;The solution is breathtakingly simple and silly: call setTimeout to defer initialization until after the DOM has been fully parsed.&#xA;&#xA;export class MyCustomElement extends HTMLElement {&#xA;  initialize () {&#xA;    // Fancy custom element stuff goes here; you can safely access&#xA;    // this.innerHTML and stuff.&#xA;  }&#xA;&#xA;  connectedCallback() {&#xA;    // Be sure to use an arrow function here or &#39;this&#39; will be&#xA;    // messed up in `initialize.&#xA;    setTimeout(() =  this.initialize(), 0)&#xA;  }&#xA;}&#xA;`]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="http://natknight.xyz/tag:til" class="hashtag"><span>#</span><span class="p-category">til</span></a> <a href="http://natknight.xyz/tag:javascript" class="hashtag"><span>#</span><span class="p-category">javascript</span></a> <a href="http://natknight.xyz/tag:webdev" class="hashtag"><span>#</span><span class="p-category">webdev</span></a> <a href="http://natknight.xyz/tag:customelements" class="hashtag"><span>#</span><span class="p-category">customelements</span></a></p>

<p>I was working on a custom element today that replaces a <code>textarea</code> with <a href="https://codemirror.net/">CodeMirror</a> in the UI while still updating the <code>textarea</code> in the background so that it can be submitted in a form. I ran across a <em>wild</em> footgun in custom elements.</p>

<p><s>StackOverflow eventually provided <a href="https://stackoverflow.com/questions/64169068/obtain-this-textcontent-during-custom-element-construction">the solution</a>.</s> There&#39;s a solution on stack overflow, but Danny Engleman wrote up a <a href="https://dev.to/dannyengelman/web-component-developers-do-not-connect-with-the-connectedcallback-yet-4jo7">more thorough explanation</a>.</p>



<p>When you&#39;re creating a custom element you do most of your setup in a method called <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#using_a_custom_element"><code>connectedCallback</code></a>. Here you can read the content of the custom element, replace it with different elements, set up callback handlers, etc.</p>

<p><em>Or so I thought.</em></p>

<p>You can read the <em>attributes</em> of the node just fine, but if you try to read its <em>contents</em> you&#39;ll find they aren&#39;t there. The reason is that the <code>connectedCallback</code> fires when the <em>opening</em> tag of the custom element is parsed, so the contents aren&#39;t in the DOM yet.</p>

<p>The solution is breathtakingly simple and silly: call <code>setTimeout</code> to defer initialization until after the DOM has been fully parsed.</p>

<pre><code class="language-javascript">export class MyCustomElement extends HTMLElement {
  initialize () {
    // Fancy custom element stuff goes here; you can safely access
    // `this.innerHTML` and stuff.
  }

  connectedCallback() {
    // Be sure to use an arrow function here or &#39;this&#39; will be
    // messed up in `initialize.
    setTimeout(() =&gt; this.initialize(), 0)
  }
}
</code></pre>
]]></content:encoded>
      <guid>http://natknight.xyz/til-accessing-content-in-custom-html-elements</guid>
      <pubDate>Sun, 09 Mar 2025 21:59:00 +0000</pubDate>
    </item>
  </channel>
</rss>