使用语义 HTML+CSS 编写原生 Web Components 组件

如果您需要设计和编写一个组件来将内容隐藏在警报栏后面,您会怎么做?今天我使用语义 HTML 结合 CSS 完成这个组件,这也意味着无论在哪里 反应 , Vue 它可以插入两者,但它们不是今天的主角。接下来介绍如何封装一个native HTML网页组件 组件,让我们开始吧!

HTML结构

首先,让我们了解一下 HTML 中的[ ** <details>**](https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FHTML%2FElement%2Fdetails) 元素,可用于创建带有附加信息的小部件,这些信息仅在小部件“打开”时可见, <details> 元素中可以包含的内容没有任何限制。

默认情况下,元素创建的小部件 <details> 已关闭” ( 打开 选项卡将其打开)。通过单击小部件以显示或隐藏标签、内部标签中包含的附加信息,在“开”和“关”状态之间切换[ <summary>](https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FHTML%2FElement%2Fsummary) 元素提供零件的摘要。

一个简单的例子如下:

 <详情>  
 < summary > 不能说的秘密  </ summary >  
 藏的这么深,可还是被你发现了  
 </ details >  
 复制代码 细节 {  
 边框:1px 实心#aaa;  
 边框半径:4px;  
 填充:。 5em5em 0;  
 }  
  
 概括 {  
 字体粗细:粗体;  
 利润: -。 5em -。 5em 0;  
 填充:。 5em;  
 }  
  
 详情 [打开] {  
 填充:。 5em;  
 }  
  
 详情 [打开] 摘要 {  
 边框底部:1px 实心#aaa;  
 边距底部:。 5em;  
 }  
 复制代码

2022-09-12 11.16.09.gif

使用语义 HTML 优点:页面内容结构更清晰,方便开发者阅读,更有利于浏览器理解加载、搜索引擎分析和SEO优化。

添加亿点样式

原生元素的默认样式很简单,所以我们需要为其自定义样式。我们已经简要介绍了这些内容,只解释了关键部分。样式内容被省略。详细信息可以在文章末尾找到。 掘金代码 看渲染效果。

 .ContentWarning > 摘要 {  
 位置:相对;  
 列表样式:无; /** 移除默认样式 **/  
 用户选择:无;  
 光标:指针;  
 /** 添加斜线背景**/  
 --条纹颜色:rgb(0 0 0 / 0.1);  
 背景图像:重复线性渐变(45度,  
 透明的,  
 透明 0.5em,  
 var(--stripe-color) 0.5em,  
 var(--stripe-color) 1em);  
 }  
  
 /** 通过 var 变量调整悬停时的颜色样式**/  
 .ContentWarning> 摘要:悬停,  
 .ContentWarning>总结:重点{  
 --条纹颜色:rgb(150 0 0 / 0.1);  
 }  
 复制代码

2022-09-12 15.19.27.gif

包模板

现在我们把它封装成一个完整的组件,首先需要 HTML 用模板写的 模板 其中,并设置一个 ID ,如下:

 < 模板 id = "警告卡" >  
 <详细信息类=“内容警告”>  
 <总结>  
 < strong >⚠️ 注意: </ strong > 以下为隐藏内容  
 </ summary >  
 < slot  name = "desc" > 藏的这么深,可还是被你发现了  </ slot >  
 </ details >  
 </ template >  
 复制代码

熟悉的 Vue 上面的代码应该很容易理解,结构很相似,但是网页不会直接渲染它包装的内容。另外我们还为这个模板设置了一个槽 投币口 , 其作用将在后面讨论。

定义组件

有了上面封装的模板,我们需要 JS 定义为可用组件,以便可以使用,调用 窗户 customElements.define 方法,第一个参数是传入的组件名,我们定义组件名: 警告卡 ,第二个参数传入一个继承的 HTML元素 类,在其构造函数中获取并克隆一个新的 HTML 节点,它将通过 追加子 渲染到页面中。

 窗户。自定义元素。定义('警告卡',  
 类扩展 HTMLElement {  
 构造函数(){  
 极好的();  
 var templateElem = 文档。 getElementById('警告卡');  
 var 内容 = 模板元素。内容。克隆节点(真);  
 这个。附加孩子(内容);  
 }  
 })  
 复制代码

然后我们可以将它作为页面中的一个组件来使用:

 <警告卡></ warning-card >  
 复制代码

槽位和参数

回顾我们在上面的模板中设置的插槽 投币口 ,此时还没有生效,我们需要稍微改写构造函数中的渲染方法,将web组件定义为 影子 DOM ,它被构造为一个单独的元素,可以隐藏标记结构、样式和行为,并将其与页面上的其他代码隔离,确保不同的部分不会混淆,并在最后使用它[ Node.cloneNode()](https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FAPI%2FNode%2FcloneNode) 方法将模板的副本添加到 阴影 在根节点上。

 窗户。自定义元素。定义('警告卡',  
 类扩展 HTMLElement {  
 构造函数(){  
 极好的();  
 var 模板 = 文档。 getElementById('警告卡')。内容;  
 这个。 attachShadow({模式:'打开'})。 appendChild(template.cloneNode(true));  
 }  
 })  
 复制代码

现在我们尝试使用以下组件,在其内容中添加一个图像,指向名称 描述 投币口 在插槽中:

 <警告卡>  
 < img slot = "desc" src = "https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ba825ffee78c4a1b9c0232e5d2f1d048~tplv-k3u1fbpfcp-watermark.image?" />  
 </ warning-card >  
 复制代码

然后你会发现图片被插入到了 细节 在元素的隐藏区域, 投币口 已经成功生效,但是样式消失了,因为组件已经 完全隔离 ,我们需要将样式应用到它的 内部的 将生效。

 < 模板 id = "警告卡" >  
 <风格>  
 <!-- TODO: Component style -->  
 </ style >  
    
 <详细信息类=“内容警告”>  
 <总结>  
 < strong >⚠️ 注意: </ strong >  
 </ summary >  
 < 插槽名称 = "desc" >描述</ slot >  
 </ details >  
 </ template >  
 复制代码

这个组件是正常的:

2022-09-12 15.45.07.gif

除了自定义模板中的slots,我们还可以通过 HTML 标记属性来实现一些简单的参数传递,比如在 概括 标签中显示一个标题:

 <warning-card title = "前方高能" >  
 </ warning-card >  
 复制代码

我们只需要在模板中定义这个标题的位置:

 < 模板 id = "警告卡" >  
 <详细信息类=“内容警告”>  
 <总结>  
 <!-- TODO: Add a span tag to the template -->  
 < strong >⚠️ 注意: </ strong >  < span  id = "title" > </ span >  
 </ summary >  
 </ details >  
 </ template >  
 复制代码

最后在构造函数中我们通过 文档 可以将本机方法写入模板:

 窗户。自定义元素。定义('警告卡',  
 类扩展 HTMLElement {  
 构造函数(){  
 极好的();  
 var 模板 = 文档。 getElementById('警告卡')。内容;  
 // TODO: 找到title标签,写入传入组件的title属性值  
 模板。查询选择器('#title')。内部文本 = 这个。 getAttribute('title');  
 这个。 attachShadow({模式:'打开'})。 appendChild(template.cloneNode(true));  
 }  
 })  
 复制代码

结束

到目前为止,我们已经学会了如何编写一个简单的原生组件 网页组件 ,可以在以下代码掘金中查看所有具体源码:

如果您觉得文章对您有帮助,希望给予更多的点赞和支持!也欢迎关注,我会不断更新前端实用知识和实用技巧共同成长。

美好的过去

# Vue 实现无限树选择器(无第三方依赖)

# Chrome 浏览器中颜色选择器(颜色吸管)的最快实现

# 学习一行 CSS 提高页面滚动性能

# 为掘金写了一个有趣好玩的一键三连插件 |模仿B站的效果

# 超级简单的Vue+Electron多终端在线笔记本快速开发

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议。转载请附上原文出处链接和本声明。

这篇文章的链接: https://homecpp.art/3213/7961/0947

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/35070/05191400

posted @   哈哈哈来了啊啊啊  阅读(399)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示