javascript - 如何使用 JS 类创建自定义元素来创建元素的属性
问题描述
所以我知道如何创建一个自定义元素,并且已经制作了 2 个我很满意的元素。我的两个元素看起来像这样:
let menuPicker = Object.create(HTMLElement.prototype);
menuPicker.initialized = false;
menuPicker._init = function(){
...
}
...
menuPicker.attachedCallback = menuPicker._init;
menuPicker.createdCallback = menuPicker._init;
...
document.registerElement('menu-picker', {
prototype: menuPicker
});
哪个有效,但这次我想要一个 JS类。特别是这个功能:
class test {
get item(){...}
set item(){...}
}
所以我想我可以做以下事情来轻松实现这一点。
class listBox extends HTMLElement.prototype {
initialized = false;
constructor(props){
super(props);
this.attachedCallback = this._init;
this.createdCallback = this._init;
}
_init () {
if(this.initialized) return;
this.initialized = true;
this.style.display = "block";
this.appendChild(document.createElement('div'));
}
}
document.registerElement('list-box', {
prototype: listBox
});
但是我得到了错误Class extends value #<HTMLElement> is not a constructor or null
。所以现在我被卡住了,找不到使用类来构造自定义 HTML 元素的方法。
简化:
如何使用 JS 类创建自定义元素来创建元素的属性?
解决方案
这是创建自定义元素的示例
//ListBox.js
export default class ListBox extends HTMLElement {
// observe attributes of custom element
static get observedAttributes() {
return ["disp", "text"];
}
get myAction() {
return this.hasAttribute("open");
}
set myAction(val) {
if (val) {
this.setAttribute("open", "");
} else {
this.removeAttribute("open");
}
}
constructor() {
super();
this.initialized = false;
this.div = document.createElement("div");
// get and assigns value from props "disp"
this.div.style.display = this.getAttribute("disp");
// get and assigns value from props "text"
this.div.innerHTML = this.getAttribute("text");
this.appendChild(this.div);
}
connectedCallback() {
// didMount
// your methode here
this.initialized = true;
console.log("custom element added to page");
}
disconnectedCallback() {
// unmount
console.log("custom element remove from page");
}
attributeChangedCallback(name, oldValue, newValue) {
// observed props
console.log("props", arguments);
// get and assigns value from props "text"
if (name === "text" && oldValue !== newValue) {
this.div.innerHTML = newValue;
}
}
}
在调用 index.js 的脚本标记中的 html 中添加 type="module"
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="app">
<list-box text="Some text here" disp="block"></list-box>
</div>
<script src="src/index.js" type="module"></script>
</body>
</html>
在你的 index.js 中导入你的组件并做一些事情
import ListBox from "./component/ListBox";
customElements.define("list-box", ListBox);
// change props "text value"
document
.querySelector("list-box")
.setAttribute("text", `Change the value of props "text"`);
推荐阅读
- python - pd.read_sas 有什么好的选择吗?将大量数据从 sas 系统加载到 Jypter 笔记本时,我遇到了一些问题
- php - 方法自动执行
- python - SQLAlchemy:在与 `secondary` 参数的关系上使用`(joined|subquery)load` 时出现“不从元素链接”错误
- vue.js - 列表离开动画和 DOM 更新后的回调 - VueJS
- flutter - 如何在颤动中加载数据之前显示进度对话框?
- amazon-web-services - 当我使用 sns 服务触发 cloudcustodian 策略时,SNS 邮件消息以不可读的格式传递
- vb.net - VB.net中的“类程序”和“模块程序”有什么区别
- pyspark - Spark.SQL – 并行聚合分离数据
- python - GSpread 单元格合并
- typescript - 查询 Firebase 集合时出现代码错误 - Typescript