gpt4 book ai didi

javascript - 在 Vanilla JS 中为单个页面创建可重用的 Web 组件?

转载 作者:行者123 更新时间:2023-12-02 22:37:33 26 4
gpt4 key购买 nike

我有一个 HTML 页面,它使用 jQuery 创建一个表来获取我的数据,并使用普通 JavaScript 来创建该表。我想为我的设置表创建方法创建一个类,以便我可以导出它并在整个 HTML 代码中重用它。我走在正确的道路上吗?

当前建表代码

function(data) {
//Rename the variable so I can reuse some code
var data_list = data.dataList;
//Headers for our tables second row
var titles = data.headers;
//HTML table variables
var perRow = 2, html = "<table><tr>";
//Loop through our array of data
for (var i = 0; i < data_list.length; i++) {
//Add our header first, as we want that to appear first
html += "<td>" + titles[i]+ "</td>";
//Then add the correct data piece for the header
html += "<td>" + data_list[i]+ "</td>";
//Break into the next row
var next = i+1;
if (next % perRow == 0 && next != data_list.length) {
//Start new row
html += "</tr><tr>";
}
}
//End the table
html += "</tr><table>";
//Attach the table to the HTML doc when finished
document.getElementById("container").innerHTML = html;
};

我认为它在另一个 .js 文件中会是什么样子

class dataTable extends HTMLElement {
constructor() {
super();

//Get our data
this.dataList = data.dataList;
this.dataHeaders = data.headers;

//HTML attribute for creating our table
this.html = "<table><tr>";
}

createTable() {
//Items we want per roq
var perRow = 2;

//Loop through our data
for (var i = 0; i < this.dataList; i++) {
//Add our headers first
this.html += "<td>" + this.dataHeaders[i] + "</td>";
//Then add the corresponding piece of data
this.html += "<td>" + this.dataList[i] + "</td>";
//Decide when to break into the next row
var next = i+1;

if (next % perRow == 0 && next != this.dataList.length) {
//Add the end row HTML
this. html += "</tr><tr>"
}
}
//End the table
this.html += "</tr><table>";

document.getElementById("container").innerHTML = this.html;
}
}

我走在正确的道路上吗?我应该只使用一个函数吗?如果我将其 .js 文件包含在同一目录中,该类能否正常工作?我只是想在学习框架之前使用一些 OOP 原理来制作自己的 Web 组件。

最佳答案

理想情况下,应该有一个带有元素 html 插槽的shadowRoot,否则可以将表格插入到shadowRoot 中。此示例将通过槽定位 HTML:

在 HTML(静态页面或其他页面)中包含以下内容:<data-grid>data-grid</data-grid>

在加载的模块中,通过导入或脚本 type=module:

/*
this is an example to show basics, it's not ideal, however it answers the question with a working example
*/
class DataTable extends HTMLElement {
constructor() {
super();
// static, or request, or setup default and update later...
this.dataList = [[1,2], [7,9]];
this.dataHeaders = ['one', 'two'];

// only work with shadowRoot in constructor, never the HTML element
// minimize work here too, do that later in lifecycle callbacks
this.attachShadow({mode:'open'}).innerHTML = `
<!-- NOTE how this th styling doesn't work because the table is rendered into the HTML, not the shadowRoot -->
<style>
/* styles shadow content in the host */
:host th{text-align:left;color:blue;}
/* only top-level selectors */
::slotted(table){text-align:right;}
</style>
<table style="width:100%;"><tr><th>ok</th></tr></table>
<button>update table</button>
<slot></slot>
`;
this.shadowRoot.querySelector('button').addEventListener('click', this.updateTable.bind(this));
}
connectedCallback(){
// change attributes, html, etc here
this.createTable();
}
random(){
const max=Date.now();
return Math.floor(Math.random() * Math.floor(max));
}
updateTable(){
this.dataList = this.dataList.map((row, i)=>{
return row.map(this.random);
});
this.createTable();
}
createTable() {
// use the render cycle
cancelAnimationFrame(this._createTable);
this._createTable = requestAnimationFrame(()=>{
// html will go into the shadowRoot slot (default or whatever is targeted)
this.innerHTML = `
<table>
<thead><tr>
${ this.dataHeaders.reduce((html, col, i)=>{
return html + `<th>${i+1} ${col}</th>`;
}, '') }
</tr></thead>
<tbody>
<tr>${ this.dataList.map((row, i)=>{
return `<td>${ row.join('</td><td>') }</td>`;
}).join('</tr><tr>') }</tr>
</tbody>
</table>
`;
});
}
}
// define the element, if not already
customElements.get('data-grid') || customElements.define('data-grid', DataTable);

查看工作 example ( commit ) 以及 Web Components best-practices 的 Google Web Developer 文档.

关于javascript - 在 Vanilla JS 中为单个页面创建可重用的 Web 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58695469/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com