Web 组件思路:创建 if 元素
我非常喜欢 Web Components,它们超级实用。但是你有没有想过把它们用作 if 语句呢?
如果用户选择“猫”单选按钮,则会显示“没错,猫最棒了!”的信息。如果他们选择“狗”单选按钮,则会显示另一条信息。
用于创作内容的 Web 组件
人们往往把网页开发等同于构建应用程序。但这忽略了人们在网络上进行的另一项重要活动:创建文档!过去,人们直接将原始 HTML 代码写入 Web 服务器。但现在,我们会在内容管理系统 (CMS) 或像这样的博客系统中编写文档。在这些系统中,我们通常会使用富文本编辑器或 Markdown 语言。
不过,HTML 仍然是创建文档的绝佳选择!如果你想制作真正自定义的内容,HTML 是一个很棒的工具。使用 Web Components 可以让你做更多有趣的事情,而不仅仅是粗体、斜体和标题。你还可以创建自定义逻辑!这才是超文本应该发挥的作用。
如果您维护的网站、博客或内容管理系统 (CMS) 的作者喜欢创作有趣的内容,那么您应该尝试使用 Web Components。它们易于编写,并且可以根据您的需求进行定制!
HTML代码是什么样的?
在这个例子中,我想创建一个类似 if 语句的功能,根据单选按钮中选择的选项来改变显示的内容。我首先编写了 HTML 代码,以便了解它的工作原理:
<label>
<input type="radio" name="animal" value="cat">
Cat
</label>
<label>
<input type="radio" name="animal" value="dog">
Dog
</label>
<ben-if name="animal" value="cat">
<p>
Yep, cats are the best!
</p>
<img src="http://placekitten.com/200/100" alt="kitten">
</ben-if>
<ben-if name="animal" value="dog">
<p>
Dogs are pretty good, but have you tried cats?
</p>
</ben-if>
您可以看到,我在这里创建了一个名为 `<customElement>` 的自定义元素ben-if,它有两个属性:`<select>`name和value`<select>`。其思路是,如果匹配的单选框被选中,则显示该 `<customElement>` 元素;否则,隐藏该元素。
因为它们只是 HTML,所以我可以毫无问题地在里面添加其他 HTML 元素。如果你使用的 Markdown 解析器支持 HTML,你也可以在 HTML 中插入 Markdown 内容。这使得它非常灵活,所以我仅凭这一个技巧就能创建各种各样的东西。
使用 Web 组件还有很多其他好处。你不需要引入任何第三方库,也不需要设置渲染上下文。它适用于任何框架,包括 React、Vue、Svelte 等。这是浏览器工作方式的一部分!
创建模板
为了编写我的 Web 组件,我需要一个模板。这个模板非常简单,因为它功能不多。以下是它的 HTML 代码:
<template id="ben-if">
<style>
:host {
display: none;
}
</style>
<slot></slot>
</template>
这里的样式:host指的是我正在构建的 Web 组件。我已将display: none其设置为默认隐藏。<slot></slot>子内容将放置在该元素内部。
编写 JavaScript
这个逻辑稍微复杂一些。首先,我设置了一些样板代码。这些代码会将我创建的模板渲染到 Web 组件中,并跟踪 `<template>` 和name` value<textarea>` 属性。它还会将我创建的自定义元素定义为 `<div>` ben-if。
class IfElement extends HTMLElement {
static get observedAttributes() {
return ['name', 'value'];
}
constructor() {
super();
this.attachShadow({mode: 'open'});
const template = document.getElementById('ben-if');
const clone = template.content.cloneNode(true);
this.shadowRoot.appendChild(clone);
}
attributeChangedCallback(name, oldValue, newValue) {
this[name] = newValue;
}
}
// Define this custom element
customElements.define('ben-if', IfElement);
现在我已经完成了样板代码,接下来要编写逻辑了。我创建了一个checkIf方法IfElement来显示或隐藏我的元素:
checkIf() {
const radio = document.querySelector(`[name="${this.name}"][value="${this.value}"]:checked`);
if (radio) {
this.style.display = "block";
} else {
this.style.display = "none";
}
}
这将查询文档以查找具有匹配的选中元素name。value如果存在,则将该元素设置为 true display: block。如果不存在,则将该元素设置为 false display: none。
现在我们只需要把这个呼叫连接起来。我把它放在了两个地方:
-
作为页面上发生任何更改事件时都会调用的事件
-
属性改变之后。
// ...
constructor() {
// ...
document.addEventListener('change', () => {
this.checkIf();
});
}
attributeChangedCallback(name, oldValue, newValue) {
// ...
this.checkIf();
}
好了,就这些!现在应该都能正常运行了。这里有一个 Codepen 示例:
对 Web 组件感兴趣吗?
我将于 2021 年 9 月 17 日和 24 日在Web Directions: Code 大会上就Web 组件的实际应用发表演讲。如果您感兴趣,可以使用优惠券享受 20% 的折扣!bensentme

