简体   繁体   中英

getElementById returning null when trying to access component from customElement

i created my own component that contains 2 inputs(type: range, number). I want to hide one of them after another checkbox is clicked but getElementById is returning null.

Error

在此处输入图像描述

This is in one js file

customElements.define("my-component",MyComponent);

document.getElementById('check').addEventListener("click", hideComponent, false); 

function hideComponent() {
    if(document.getElementById('check').checked) {
        document.getElementById('inp').style.display = 'none';
        document.getElementById('slider').style.display = '';
    } else {
        document.getElementById('inp').style.display = '';
        document.getElementById('slider').style.display = 'none';
    }
}

This is my custom Element

export class MyComponent extends HTMLElement {
    constructor(){
        super();

        this.attachShadow({mode: "open"});
        const wrapper = document.createElement("div");
        wrapper.setAttribute("class","wrapper");

        const slider = wrapper.appendChild(document.createElement("input"));
        slider.setAttribute("class","slider");
        slider.setAttribute("type","range");
        slider.setAttribute("id","slider");
        let minVal = this.hasAttribute("min-val")  ? this.getAttribute("min-val") : "0";
        let maxVal = this.hasAttribute("max-val")  ? this.getAttribute("max-val") : "5";
        slider.setAttribute("min",minVal);
        slider.setAttribute("max",maxVal);
        slider.setAttribute("value",minVal);

        const ampInput = wrapper.appendChild(document.createElement("input"));
        ampInput.setAttribute("type","number");
        ampInput.setAttribute("id","inp");
        ampInput.setAttribute("value","5");

        const style = document.createElement("style");
        style.textContent = `.slider{
            backround: #cfc;
        }

        .inp{
            display: block;
        }

        .wrapper {
            display: inline-grid;
        }`;

        this.shadowRoot.append(style,wrapper);

I added style in my custom Element so i dont understand this error. What should i change to make it work? Or how differently should i hide the element when checkbox is clicked?

try console logging the document.getElementById('inp') and see what would happen. if it works then the problem could be that the function is being triggered before the document is ready, which results in a null.

try wrapping it like this and see what happens

if (window){
 if(document.getElementById('check').checked) {
        document.getElementById('inp').style.display = 'none';
        document.getElementById('slider').style.display = '';
    } else {
        document.getElementById('inp').style.display = '';
        document.getElementById('slider').style.display = 'none';
    }
}

document.getElementById does not give you access to DOM content inside shadowRoots.

If you have an mode:open shadowRoot you could do:

document.querySelector("element-name").shadowRoot.document.getElementById

But that is too verbose, and tight coupling components.


Since :host-context isn't supported in all browsers: https://caniuse.com/?search=host-context

You can use CSS properties:

 <h1>range:</h1> <my-input type="range" min="10" max="20"></my-input> <h1>number:</h1> <my-input type="number"></my-input> <template id="MY-INPUT"> <style>:host([type="range"]) { --range_display: none; --number_display: inline-block; }:host([type="number"]) { --range_display: inline-block; --number_display: none; } [type="range"] { display: var(--range_display); } [type="number"] { display: var(--number_display); } </style> <input type="range"><input type="number"> </template> <script> customElements.define('my-input', class extends HTMLElement { constructor() { super().attachShadow({mode: 'open'}).append(document.getElementById(this.nodeName).content.cloneNode(true)); let range = this.shadowRoot.querySelector('[type="range"]'); let number = this.shadowRoot.querySelector('[type="number"]'); //... configure here } }); </script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM