0

I am about to learn vanilla js web components. I could successfull render some elements generated by webcomponents, now I would like to give it some design and put it inside a sidebar. However I am not sure if this is webcomponents or just design problem, the elements won´t display anymoer after adding the sidebar.

Maybe you could take a look at my code and give me some hints, where I am causing the problem?

@Edit: As suggested in comment I have put it in fiddle, so you can try it out. Now I understeand the behavior even less, then In fiddle it looks kind as it should and on my local machine not.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>DiceArea</title>
    </head>
    <body>
    
    <script  type="module" src="./index.js"></script>
    </body>
    </html>
    window.addEventListener('load', () => {
        getUsers();
    });

    function getUsers() {
        const users = ["player1", "player2", "player3", "player4", "player5"];
        const nav = document.createElement("player-nav");
        nav.setAttribute("class", "sidenav")
        document.body.appendChild(nav);
    
        users.forEach(user => {
            user = document.createElement('table-user');
            nav.appendChild(user);
    
            user.addEventListener("click", () => {
                alert("lol")
            })
        })
    }

    class User extends HTMLElement {
        constructor() {
            super();
            this.shadow = this.attachShadow({mode: 'open'});
        }
    
        connectedCallback() {
            this.user();
        }
    
        user() {
            this.shadow.innerHTML = ` 
            <style>
            .sidenav {
                height: 100px;
                width: 100px;
                position: fixed;
                background-color: #0000;
                overflow-x: hidden;
                padding-top: 20px;
            }
            .avatar {
                width: 90px;
                height: 90px;
                border-radius: 10%;
            }
            </style>
           <img src="html/aavatar.png" alt="Avatar" class="avatar">`
   }
}

customElements.define("table-user", User);

https://jsfiddle.net/9bt8Lk0v/8/

And that is how it look on my local machine: enter image description here

Community
  • 1
  • 1
WinterMute
  • 145
  • 2
  • 11

1 Answers1

1

At first sight I see 2 possible problems:

  • You are doing .createElement('player-nav') but never defined that Custom Element

  • You are doing nav.appendChild()
    IF nav is an element with shadowDOM, you have to do nav.shadowRoot.appendChild() because the original element content is now 'lightDOM'
    see: Difference between Light DOM and Shadow DOM

Your code is still very traditional/oldskool DOM manipulation.

I butchered your JSFiddle into a (quick) example showing some Web Components concepts you can play with:

<template id=TABLE-PLAYERS>
  <style>
    :host {
      display: block;
      background: grey;
      --clickedColor: green;
    }
  </style>
  <h3>Players</h3>
</template>

<template id=PLAYER-NAV>
  <style>
    :host {
      display: block;
      background: lightgreen;
    }

    * {
      float: left
    }
    :host(.clicked){
      background:var(--clickedColor);
    }
    .name{
      font-size:2em;
    }
  </style>

  <slot name=avatar></slot>

  <div>
        <slot class=name name=username></slot>
  </div>

</template>

<table-players id=Players></table-players>
Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
  • Thanks! I think I understeand the most of this code, however I still have some questions... For instance I would want to see big avatar, when I click on the picture. How would I do that? Or how would I mix the custom elements? Let´s say I want every player to have three buttons. How can I achieve that? Could you provide me some hints? – WinterMute Apr 23 '20 at 07:19
  • Those are not Component questions but regular development questions. Start with just JS/CSS/HTML in a JSFiddle. You will go through the...try-fail-learn cycle many times (we all did) Only after you have a working model you wrap your code in components. It is like learning to ride a uni/bicycle, you start with 2 wheels, not with the uni-cycle. Same applies here, learn JS/CSS/HTML first. So your first leaning object is: How can I make an IMG bigger when I click it... again.. adding Components to the mix is like starting on a uni-cycle.. – Danny '365CSI' Engelman Apr 23 '20 at 09:18