I was trying to create a web component. The component just had a progress. the following is my code.
class MyElement extends HTMLElement {
static get observedAttributes() {
return ['value'];
}
get value() {
return this.hasAttribute('value');
}
set value(val) {
if(val) {
this.setAttribute('value', val);
}
else {
this.removeAttribute('value')
}
setValue(val);
}
constructor() {
super();
let shadowRoot = this.attachShadow({mode: 'open'});
const t = document.querySelector('#my-element');
const instance = t.content.cloneNode(true);
shadowRoot.appendChild(instance);
this.shadowDOM = shadowRoot;
}
attributeChangedCallback(name, oldValue, newValue) {
if (this.value) {
this.setValue(newValue);
}
}
// Set a value to progress
setValue(val) {
// How to do?
}
}
customElements.define('my-element', MyElement);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>index</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div>
<my-element value=50></my-element>
</div>
<button onclick="test()" style="bottom: 10px; right: 10px; position: absolute;">test</button>
<script>
function test() {
// How to set the value to my-element?
}
</script>
<!--My Element-->
<template id="my-element">
<style>
:host {
position: relative;
display: block;
width: 600px;
}
progress {
-webkit-appearance: none;
-moz-appearance: none;
}
progress::-moz-progress-bar {
background: gainsboro;
width: 300px;
height: 500px;
}
progress::-moz-progress-value {
background: green;
}
progress::-webkit-progress-bar {
background: gainsboro;
width: 300px;
height: 500px;
}
progress::-webkit-progress-value {
background: green;
}
</style>
<progress value=20 max=100>
</progress>
</template>
</body>
</html>
I wanted to control the progress value by the value of my-element.
I set a value in my-element(<my-element value=50></my-element>)
but it's not work, and I didn't know how to set value by js.
I guessed the problem was the setValue(val)
in my MyElement
class, but I didn't know how to implement it.
Someone can help me? Thanks!
I would say you just need to use the DOM and retrieve your progress element.
class MyElement extends HTMLElement {
static get observedAttributes() {
return ['value'];
}
get value() {
return this.hasAttribute('value');
}
set value(val) {
if(val) {
this.setAttribute('value', val);
}
else {
this.removeAttribute('value')
}
}
constructor() {
super();
let shadowRoot = this.attachShadow({mode: 'open'});
const t = document.querySelector('#my-element');
const instance = t.content.cloneNode(true);
shadowRoot.appendChild(instance);
this.shadowDOM = shadowRoot;
}
attributeChangedCallback(name, oldValue, newValue) {
if (this.value) {
this.setValue(newValue);
}
}
// Set a value to progress
setValue(val) {
const progress = this.shadowDOM.lastElementChild;
progress.value = val;
}
}
customElements.define('my-element', MyElement);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>index</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div>
<my-element id="myElement" value=50></my-element>
</div>
<button onclick="test()" style="bottom: 10px; right: 10px; position: absolute;">test</button>
<script>
function test() {
document.getElementById("myElement").value = 5;
}
</script>
<!--My Element-->
<template id="my-element">
<style>
:host {
position: relative;
display: block;
width: 600px;
}
progress {
-webkit-appearance: none;
-moz-appearance: none;
}
progress::-moz-progress-bar {
background: gainsboro;
width: 300px;
height: 500px;
}
progress::-moz-progress-value {
background: green;
}
progress::-webkit-progress-bar {
background: gainsboro;
width: 300px;
height: 500px;
}
progress::-webkit-progress-value {
background: green;
}
</style>
<progress value=20 max=100>
</progress>
</template>
</body>
</html>