最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use querySelector of Tags inside a Web Component - Stack Overflow

programmeradmin1浏览0评论

I am building an application with Web Components and only vanila javascript. I want to use vaadin-router for routing.

In my index.html I only display the web ponent app.module:

<!DOCTYPE html>
    <body>
        <mp-app-root></mp-app-root>
    </body>
</html>

the app module is a simple web ponent. It should display the routing module in a template. The Shadow DOM is optional.

app.module.js

import Template from './app.module.template.js'

class AppModule extends HTMLElement {
    connectedCallback() {
        this.innerHTML = Template.render();
    }
}

customElements.define('mp-app-root', AppModule)

The template simply renders the tag, where the routing should happen.

app.module.template.js

import './routing.module.js'

export default {
    render() {
        return `${this.html()}`;
    },

    html() {
        return `<script type="module" src="./routing.module.js"></script>
                <app-routing-module></app-routing-module>`;
    },
}

As you can see, i am importing the script routing.module.js - It also works, when im console.logging something

Now, I am using vaadin-router for routing and I want to access the <app-routing-module>-Tag with querySelector like this:

const outlet = document.querySelector('mp-app-root').querySelector('app-routing-module')

but it is always null.

console.log(document.querySelector('mp-app-root') works and prints the following:

<mp-app-root>
    <app-routing-module></app-routing-module>
</mp-app-root>

I am building an application with Web Components and only vanila javascript. I want to use vaadin-router for routing.

In my index.html I only display the web ponent app.module:

<!DOCTYPE html>
    <body>
        <mp-app-root></mp-app-root>
    </body>
</html>

the app module is a simple web ponent. It should display the routing module in a template. The Shadow DOM is optional.

app.module.js

import Template from './app.module.template.js'

class AppModule extends HTMLElement {
    connectedCallback() {
        this.innerHTML = Template.render();
    }
}

customElements.define('mp-app-root', AppModule)

The template simply renders the tag, where the routing should happen.

app.module.template.js

import './routing.module.js'

export default {
    render() {
        return `${this.html()}`;
    },

    html() {
        return `<script type="module" src="./routing.module.js"></script>
                <app-routing-module></app-routing-module>`;
    },
}

As you can see, i am importing the script routing.module.js - It also works, when im console.logging something

Now, I am using vaadin-router for routing and I want to access the <app-routing-module>-Tag with querySelector like this:

const outlet = document.querySelector('mp-app-root').querySelector('app-routing-module')

but it is always null.

console.log(document.querySelector('mp-app-root') works and prints the following:

<mp-app-root>
    <app-routing-module></app-routing-module>
</mp-app-root>
Share Improve this question asked Jul 24, 2020 at 11:37 CenasaCenasa 5991 gold badge12 silver badges33 bronze badges 3
  • Can you try this in your browser and tell us if it works? jsfiddle/1j87xtqe – Guerric P Commented Jul 24, 2020 at 11:53
  • @Guerric P yes it works. hm this is strange. – Cenasa Commented Jul 24, 2020 at 11:58
  • Well it might help you find the cause, I have no clue!. – Guerric P Commented Jul 24, 2020 at 12:00
Add a ment  | 

1 Answer 1

Reset to default 7

You get null, you can't access the lightDOM
Because the connectedCallback fired on the opening tag

This is considered the correct implementation of the W3C Web Components standard
(Firefox got it wrong until they fixed it in 2021)

See:

  • (long read) Dev.to blog: Developers haven't connected with the connectedCallback (yet)
  • How to Get the Contents of a Custom Element
  • wait for Element Upgrade in connectedCallback: FireFox and Chromium differences
  • Create WebComponent through createElement

working code: (read that long blogpost)

setTimeout( () => {
  const outlet = document.querySelector('mp-app-root')
                         .querySelector('app-routing-module')
});

All WebComponent libraries do something similar under the hood;
delay execution till the Eventloop is empty, and the DOM is ready to accept your selections/additions.


Note: querySelector takes a selector, so you can write:

  const outlet = document.querySelector('mp-app-root app-routing-module')
发布评论

评论列表(0)

  1. 暂无评论