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.