Web component cannot get textContent

  class SpoilerText extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: 'open' });

      const style = document.createElement('style');
      style.textContent = `.spoiler {
						display: inline-block;
						filter: blur(0.5em);
						transition: filter 0.1s ease;
					}
					.spoiler:hover {
						filter: blur(0.18em);
					}
					.spoiler.revealed {
						filter: blur(0);
					}
				`;

      this.wrapper = document.createElement('span');
      this.wrapper.classList.add('spoiler');
      this.wrapper.textContent = this.textContent.trim();

      this.wrapper.addEventListener('click', () => {
        this.wrapper.classList.toggle('revealed');
      });

      this.shadowRoot.append(style, this.wrapper);
    }
  }
  customElements.define('spoilter-text', SpoilerText);


I write a spoiler web component,But when I put this web component code into tiddlywiki with startup modules, it seems that the web component value of textContent cannot be obtained.

If I use the widget approach instead of web component, everything works fine.

I tried to define the web component with delay, such as using setTimeout, or DOMContentLoaded listener, and it worked for the first time. Loading seems normal, but if you close and reopen the tiddler containing this web component, the web component textContent can no longer be obtained, which is very strange.

window.addEventListener('DOMContentLoaded', () => {
customElements.define(' spoiler-text', SpoilerText);
});

@jeremyruston Do you have any suggestions for this web component?

That needs to be replaced with a slot

      this.wrapper = document.createElement('span');
      this.wrapper.classList.add('spoiler');
     this.wrapper.innerHTML = `<slot></slot>`;
      this.wrapper.addEventListener('click', () => {
        this.wrapper.classList.toggle('revealed');
      });
1 Like

This works for me. I need to learn how to write web components.

It seems that in tiddlywiki, the rendering time has some influence. For example, if I want to get the text attribute, I can’t get it either. I can only manually add some hack code such as the following. I don’t understand what the real reason is.

      setTimeout(() => {
        // const text = this.getAttribute('text') || `<slot></slot>`;
        const text = this.getAttribute('text') || this.textContent.trim();
        this.wrapper.innerHTML = text;
      }, 0);

the attributes of a web component can only be read safely from within the

connectedCallback() {....}
1 Like