html - 如何在自定义元素中制作自定义表格?
问题描述
我正在使用lit-element处理自定义元素。我想制作自己的自定义表格元素,但是有一些问题。
第一的。它似乎浏览器允许tr
,td
标签只table
。
<!-- in html -->
<my-table>
<tr>
<td>A</td>
<td>B</td>
</tr>
</my-table>
<!-- chrome rendered -->
<my-table> A B </my-table>
第二。它可以用CSS模仿,但CSS不能实现colspan。
<my-table> <!-- display: table -->
<my-tr> <!-- display: table-row -->
<my-td>A</my-td> <!-- display: table-cell -->
<my-td colspan="3">B</my-td> <!-- There is no way to implement colspan -->
</my-tr>
</my-table>
第三。我尝试在主机上使用“显示:内容”进行样式设置。这似乎是工作,但主机没有像clientHeight
.
class MyTd extends LitElement {
render() {
return html`
<style>
:host { display: content; }
td {
all: inherit; /* It make to inherit host's style */
display: table-cell;
}
</style>
<td>
${html`<slot></slot>`} // I don't know why it work.
</td>
`;
}
}
// other js file.
const td = document.querySelector('my-td');
td.clientHeight; // 0
我可以覆盖clientHeight
和其他东西(offsetHeight
,getBoundingClientRect
...),但我不知道这是正确的,这是唯一的方法。
有没有其他方法可以创建自定义表,或者我的想法有问题?
解决方案
对于自定义元素来说,这并不是一个很好的用例——问题是我为什么要<my-td>
在<td>
存在时使用并且在任何地方都可以使用?
您可以在 CSS 中使用column-count
来模拟表格,但您有更严重的问题 - 浏览器(和相关的 a11y 工具)将 DOM<table>
视为结构化的数据表格,而您<my-table>
的只是另一个自定义元素。
这也破坏了表格的 DOM 层次结构——即使您的元素包装了相关的表格元素,它们也不会继承或扩展它们。
因此,对于您的第一个示例,您的 DOM 是这样的:
<my-table>
#shadow-root
<tr>
<td>A</td>
<td>B</td>
</tr>
</my-table>
浏览器通常不会将单元格连接到行和将行连接到表格的任何操作都不会跨越这些影子 DOM 边界,并且它<tr>
的呈现方式就像它位于新文档片段的根部一样。
同样,第三次尝试的 DOM 看起来像这样:
<my-table>
#shadow-root
<table>
<my-tr>
#shadow-root
<tr>
<my-td>
#shadow-root
<td>
每一个影子根都是一个新的孤立片段。
问题变成了你想用这个结构做什么?
您是否想要一些看起来像表格但对行和单元格使用自定义元素的东西,请考虑使用display: grid
布局。它比表格更强大,并且在自定义元素中,CSS 比相当不一致的display: table-cell
.
如果您想要将某些东西结构化为表格,请考虑将整个表格放在影子根中并将数据作为属性传递
@customElement('my-table')
class MyTable
extends LitElement {
render() {
return html`
<table>
${this.items.map(i => html`
<tr>
<td>A</td>
<td>B</td>
</tr>`)}
</table>
`;
}
@property({attribute: false})
items: readonly RowRecordType[];
}
然后使用属性前缀调用它:
<my-table .items=${theListOfRows}></my-table>
最后,如果您想扩展 <td>
,您可以使用is=
语法添加它,但这在规范上有点死胡同,在 Safari 或 Opera 上根本不支持,并且在其余部分是不稳定的。
您可以扩展一个单元格:
class MyCell
extends HTMLTableCellElement { ...
customElements.define('my-cell', MyCell, { extends: 'td' });
然后做:
<table>
<tr>
<td is="my-cell">A</td>
<td is="my-cell">B</td>
</tr>
</table>
但是,这不受 LitElement 支持,您最好直接实现自定义 Web 组件。
推荐阅读
- php - unlink(202104241126Dell_Logo.png):没有这样的文件或目录
- windows - DesktopInfo 作为 Windows 服务已启动,但没有任何反应
- django - 我如何使用 Django gabarit 过滤通过模型的条件
- python - Fast.ai & NLP:删除 fast.ai 分词器中的未知词
- java - 使用 Elasticsearch 编译 java 文件
- python - “警告:scheme.data 的值不匹配”当我尝试更新 pip 或安装软件包时
- reactjs - Next js Django Djoser 谷歌认证/
- php - 错误:Apache 意外关闭。怎么修?
- powerbi - 是否可以从嵌入式电源应用程序访问和更改 power bi 报告上的过滤器?
- r - 如何避免 R 中 sqldf 中的 FULL OUTER JOIN