网页元件中 , 常会使用 Modal 这种类型的元件
如果我们将其制作成一个 <Modal>
的 WebComponent , 之後在使用时 , 应该会轻松不少吧 !
下面我们来制作 <Modal>
吧 !
解压缩後 , 观察 html 中的 pop-up-container 结构
我们可以发现 Modal
的大致结构如下
<div class="pop-up-container" style="display: none;">
<div class="pop-up-container-root">
<div class="pop-up-box">
<div class="pop-up-title">
<h3>Title</h3>
<close-icon/>
</div>
<div class="pop-up-content">
</div>
<div class="pop-up-action">
<button onclick='closeModal()'>取消</button>
<button onclick='closeModal()'>确定送出</button>
</div>
</div>
</div>
</div>
区块名称 | 描述 |
---|---|
pop-up-container | Modal 的容器 , 黑底遮罩放在这 , 不会改变 |
pop-up-container-root | Modal 的卷动区块 , 不会改变 |
pop-up-box | Modal 的内容放在其中 , 不会改变 |
pop-up-title | 标题区块 , 可能会修改其内容 |
pop-up-content | 内文区块 , 可能会修改其内容 |
pop-up-action | 按钮区域 , 可能会修改其内容 |
有 pop-up-title
. pop-up-content
. pop-up-action
这 3 个区块需要塞入 html 内容
在 Day02 介绍 wired-element
时 , 我们了解到 slot 可以塞入 html 内容
不过 , 需要区分 pop-up-title
. pop-up-content
. pop-up-action
3 个区块的 slot 要如何制作呢 ?
Name Slot 的介绍
我们可以在 shadow-dom
中设定 <slot name="modal-body">
在使用 <Modal>
时设定 slot="modal-body"
,
// in html usage
<Modal>
<h2 slot="modal-body">
这是内文...这是内文...这是内文...这是内文...
</h2>
</Modal>
// in web component
class Modal extends HTMLElement {
connectedCallback() {
const htmlStr = `
<div>
其他文字
<div class="pop-up-content">
<h2 slot="modal-body">
这是内文...这是内文...这是内文...这是内文...
</h2>
</div>
</div>
`
// 启用 shadow dom
this.attachShadow({mode: 'open'}).innerHTML = htmlStr
}
}
window.customElements.define('my-modal', Modal);
其实做法跟 Vue 的 Slot 是相似的
建立 customElements - my-modal
class Modal extends HTMLElement {
}
window.customElements.define('my-modal', Modal);
将 shadow-dom
开启 & 将 html 结构复制到 class 中
class Modal extends HTMLElement {
connectedCallback() {
const styleStr = `<link rel="stylesheet" href="./modal.css">`
const htmlStr = `
<div class="pop-up-container" style="display: none;">
<div class="pop-up-container-root">
<div class="pop-up-box">
<div class="pop-up-title flex justifyContent">
<h3>这是 Modal 的 Title</h3>
<img class='close' src="./close.png" />
</div>
<div class="pop-up-content">
这是 Modal 的 Body
</div>
<div class="pop-up-action flex justifyContent">
<button class='close'>取消</button>
<button class='confirm'>确定送出</button>
</div>
</div>
</div>
</div>
`
// 启用 shadow dom
this.attachShadow({mode: 'open'}).innerHTML = styleStr + htmlStr
}
}
window.customElements.define('my-modal', Modal);
将 Name Slot 设定到 html 中
pop-up-title
. pop-up-content
. pop-up-action
设定对应的 slot区块名称 | Slot 名称 |
---|---|
pop-up-title | modal-title |
pop-up-content | modal-body |
pop-up-action | modal-action |
<div class="pop-up-box">
<div class="pop-up-title flex justifyContent">
+ <slot name="modal-title"><h3>这是 Modal 的 Title</h3></slot>
<img class='close' src="" />
</div>
<div class="pop-up-content">
+ <slot name="modal-body">这是 Modal 的 Body</slot>
</div>
<div class="pop-up-action flex justifyContent">
+ <slot name="modal-action">
<button class='close'>取消</button>
<button class='confirm'>确定送出</button>
+ </slot>
</div>
</div>
设定 Modal 的 open . close 事件
class Modal extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: 'open'}).innerHTML = styleStr + htmlStr
this.shadowRoot.querySelector('.close:nth-child(1)').addEventListener('click', () => this._close())
this.shadowRoot.querySelector('.close:nth-child(2)').addEventListener('click', () => this._close())
this.shadowRoot.querySelector('.confirm').addEventListener('click', () => this._confirm())
}
_open() {
const shadowRoot = this.shadowRoot;
const modalWrap = shadowRoot.querySelector('.pop-up-container');
const popup = modalWrap.querySelector('.pop-up-box');
modalWrap.style.display = 'flex';
popup.style.transform = 'scale(0)';
setTimeout(() => popup.style.transform = 'scale(1)', 0)
}
_close() {
const shadowRoot = this.shadowRoot;
const modalWrap = shadowRoot.querySelector('.pop-up-container');
const popup = modalWrap.querySelector('.pop-up-box');
popup.style.transform = 'scale(0)';
setTimeout(() => modalWrap.style.display = 'none', 300)
}
}
window.customElements.define('my-modal', Modal);
在页面中使用 my-modal
<body>
<my-modal @confirm="() => console.log('确定送出 !')">
<h2 slot="modal-title">
表头写入
</h2>
<h2 slot="modal-body">
这是内文...这是内文...这是内文...这是内文...
</h2>
</my-modal>
<script src="./modal-wc.js"></script>
</body>
</html>
建立按钮来开启今天制作的 Modal
<button onclick='showModal()'>
开启 Modal
</button>
<script>
function showModal() {
document.querySelector('my-modal')._open()
}
</script>
完成 !!
如果想直接体验成果 , 请到 web-component-modal.html 查看
其实 HTML Tag 有一个 <dialog>
跟今天制作的元件很相似
<<: 案例:AWS MLOps Framework - 解决方案介绍
>>: Azure - Day6 Azure Function
软件当机每次来得都是猝不及防,Word 也不例外。辛辛苦苦在 Word 编辑的文档因突然当机丢失了,...
有了总体经济的图表之後,接下来就要来制作各国股市的资讯站,笔者最常看的就是台股的资讯,其次则是美股、...
今天要来介绍类别实作介面, 介面型别我觉得很大的一个优势是可以重复使用, 因此我们就来说说这个吧。 ...
集合物件 集合物件代表 "一个放置一堆东西的地方" 它可以是有序 有可以是无序的...
摧毁阶段 这个阶段负责元件的移除,适合用来移除所有的事件监听以及任何会造成记忆体泄漏(memory ...