Shadow Dom Cannot read property 'style' of undefined

Viewed 510

I am creating a component with shadow dom but I have the error in the console "Cannot read property 'style' of undefined" this is my HTML code in php My problem is that I don't know how to get the javascript code that gives the image slideshow functionality to run. If I put an alert in the script it runs, so the code runs. But I can't access the style property.

```
<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <title>Avisos</title>        
    </head>

    <body>
        <aviso-dos>A</aviso-dos>
        <aviso-dos>B</aviso-dos>
        <aviso-dos>C</aviso-dos>

        <template id="plantilla">
            <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

            <style>
                .item {
                    width: 288px;
                    height: 192px;
                    border-style: solid;
                    border-width: 1px;
                    border-color: DarkGray;
                }

                #iconos{ 
                    display: none;
                }

                #aviso:hover #iconos{
                    display : block;
                    background:rgba(255, 255, 255, 0.75);
                }      

                .slide {
                    display: none;
                }
            </style>

            <div id="aviso" class="item w3-display-container">
                <div id="iconos" class="w3-display-middle w3-display-container w3-animate-opacity" style="width:100%; height:100%">
                    <div class="w3-display-topleft" id="arrIzq" style="width:44px; height:auto; display: flex; flex-flow: column; align-content: space-between">
                        <div class="w3-dropdown-hover w3-hover-green" style="background-color: transparent">
                            <img src="varios/bars-solid.svg" style="width:24px; height:24px; margin:10px">   
                            <div class="w3-dropdown-content w3-bar-block w3-border">
                                <a href="#" class="w3-bar-item w3-button">Link 1</a>
                                <a href="#" class="w3-bar-item w3-button">Link 2</a>
                                <a href="#" class="w3-bar-item w3-button">Link 3</a>
                            </div>
                        </div>
                    </div>
                    <div class="w3-display-topmiddle" id="arrMed" style="width:auto; height:44px; display: flex; flex-flow: row; align-content: space-between">
                        <img src="varios/crown-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                        <img src="varios/crown-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                        <img src="varios/crown-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                    </div>
                    <div class="w3-display-topright" id="arrDer" style="width:44px; height:auto; display: flex; flex-flow: column; align-content: space-between">                
                        <img src="varios/check-circle-regular.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                    </div>
                    <div class="w3-display-bottomleft" id="abaIzq" style="width:auto; height:44px; display: flex; flex-flow: row; align-content: space-between">
                        <img src="varios/circle-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                        <img src="varios/comment-alt-regular.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                    </div>
                    <div class="w3-display-middle" id="abaMed" style="width:auto; height:44px; display: flex; flex-flow: row; align-content: spcae-between">
                        <img src="varios/star-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                        <img src="varios/star-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                        <img src="varios/star-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                        <img src="varios/star-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                        <img src="varios/star-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                    </div>
                    <div class="w3-display-bottomright" id="abaDer" style="width:auto; height:44px; display: flex; flex-flow: row; align-content: space-between">
                        <img src="varios/thumbs-up-regular.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                        <img src="varios/star-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                        <img src="varios/bell-solid.svg" style="width:24px; height:24px; margin:10px; cursor:pointer">
                    </div>
                </div>
                <!--<div id="slide">
                    <img src="imagenes/gonzaloRuiz_prueba2_6_288x192.jpg">
                </div>-->
                <div style="width:100%; height:100%; overflow:hidden">                    
                    <img class="slide" src="imagenes/carrasquera_prueba2_2_288x192.jpg" style="width:100%; height:100%">
                    <img class="slide" src="imagenes/gonzaloRuiz_prueba2_6_288x192.jpg" style="width:100%; height:100%">
                    <img class="slide" src="imagenes/higueritas_prueba6_288x192.jpg" style="width:100%; height:100%">
                    <img class="slide" src="imagenes/sanAntonio_prueba11_288x192.jpg" style="width:100%; height:100%">
                    <img class="slide" src="imagenes/siberia_prueba4_288x192.jpg" style="width:100%; height:100%">
                </div>
            </div>

            <script>
                var myIndex = 0;

                carousel();

                function carousel() {
                    var i;
                    var x = document.getElementsByClassName("slide");

                    for (i = 0; i < x.length; i++) {
                        x[i].style.display = "none";  
                    }

                    myIndex++;

                    if (myIndex > x.length) {
                        myIndex = 1
                    }    


                    x[myIndex-1].style.display = "block";  

                    setTimeout(carousel, 2500);    
                }     
            </script>
        </template>

        <script src="aviso2.js"></script>
    </body>
</html>

AND THIS IS MY JAVASCRIPT
My problem is that I don't know how to get the javascript code that gives the image slideshow functionality to run.
If I put an alert in the script it runs, so the code runs.
But I can't access the style property.

    ```
    class aviso2 extends HTMLElement {
    
        constructor() {
            // Siempre llamar primero a super en el constructor
            super();
    
            this.attachShadow({mode: 'open'});
    
            this.template = document.getElementById("plantilla");
    
            this.shadowRoot.appendChild(this.template.content.cloneNode(true));
        }
    
        connectedCallback(){
            
        }
    }
    
    customElements.define('aviso-dos', aviso2);

2 Answers

When this line x[myIndex-1].style.display = "block"; is executed, x.length is equal 0 because the nodes don't exist in the DOM yet.

Try to add the carousel script after creating the custom element:

aviso2.js

 window.customElements.define("aviso-dos", aviso2);

 const script = document.createElement("script");
 script.src = "carousel.js";
 document.body.appendChild(script);

I continued investigating in other forums and in the end I was able to find the solution obtaining information from one side and the other. I hope it helps you in the future.

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

    const template = document.getElementById("plantilla");

    this.shadowRoot.appendChild(template.content.cloneNode(true));

    this.myIndex = 0;
    this.x = this.shadowRoot.querySelectorAll(".slide");
}

prueba()
{
    this.prueba2();
}

prueba2(){
    var i;
    
    for (i = 0; i < this.x.length; i++) {
        this.x[i].style.display = "none";  
    }

    this.myIndex++;

    if (this.myIndex > this.x.length) {
        this.myIndex = 1
    }    

    this.x[this.myIndex-1].style.display = "block";  

    setTimeout(() => {
        this.prueba2();
    }, this.getAttribute('tiempo'));
}

connectedCallback() {
    this.prueba();
}

}

window.customElements.define('aviso-dos', aviso2);

Related