javascript - 如何以及在何处将“Esc”侦听器添加到 litElement 组件?
问题描述
我有使用 litElement 呈现的模态组件,我想通过 Escape 键使其可关闭,用于此模态组件的任何和所有实例。
我的问题是我在哪里以及如何做到这一点?在渲染中,在 firstUpdated? 您的帮助将不胜感激。
相关摘录:
close() {
this.hidden = true;
this.dispatchEvent(new CustomEvent('modal-closed'));
}
_addKeyListener() {
this.shadowRoot.addEventListener('keydown', function (event) {
if (event.key === 'Escape') {
this.close(); //presumably
}
});
}
render() {
if (this.hidden) {
return html``;
}
return html`
<div id="background" class="${classMap({'u-is-hidden': this.hidden})}">
<div class="modal">
<div id="modal-close" class="${classMap({'u-is-hidden': !this.closeable})}">
<img src="img/close-icon.svg" @click="${this.close.bind(this)}" alt="close">
</div>
<div id="modal-header">
<slot name="header"></slot>
</div>
<div id="modal-body">
<slot name="body"></slot>
</div>
<div id="modal-footer">
<slot name="footer"></slot>
</div>
</div>
</div>
`;
}
解决方案
我在模态组件中将更新的生命周期函数用于相同的目的:
import { html, LitElement } from "lit";
import { customElement, property, query } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { elementStyles } from "./modal.element.styles";
@customElement('very-custom-modal')
export class ModalElement extends LitElement {
static styles = [elementStyles];
@property({ type: Boolean })
open = false;
private _handlerClose() {
this.dispatchEvent(new CustomEvent("close"));
}
private _keydownHandler(e: Event) {
if ((e as KeyboardEvent).code === 'Escape') {
this._handlerClose();
}
}
updated() {
if (this.open) {
this.getRootNode().addEventListener('keydown', (e: Event) => this._keydownHandler(e));
} else {
this.getRootNode().removeEventListener('keydown', (e: Event) => this._keydownHandler(e));
}
}
render() {
const classes = { 'modal': true, 'open': this.open, 'hidden': !this.open };
return html`
<div class=${classMap(classes)}>
<div class="modal-content">
<span class="close" @click=${this._handlerClose}>×</span>
<p class="text">Some text in the Modal..</p>
</div>
</div>
`;
}
}
和款式:
import { css } from "lit";
export const elementStyles = css`
.modal {
position: fixed;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.8);
top: 0;
left: 0;
z-index: 99;
}
.modal-content {
position: absolute;
top: calc((100vh - 300px) / 2);
left: calc((100vw - 500px) / 2);
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 50%;
top: 30%;
}
.close {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.open {
display: block;
}
.hidden {
display: none;
}
`;
该组件根据状态属性“打开”的依赖性更改其行为。默认情况下它是假的,所以组件有'.hidden'类。更改 'open' 属性后,组件会根据 Lit 文档 ( https://lit.dev/docs/components/lifecycle/#reactive-update-cycle ) 进行更新,并使用 '.open' 类进行更新,以防属性为'真的'。我使用 'updated' 事件来添加/删除 keydown 监听器。作为一个小结论,该组件仅在它处于活动状态(显示)时才挂钩 keydown 事件,否则我们不需要此处理程序,因此如果控制属性为“假”,则可以将其删除。由于属性应该设置在组件之外,我们需要向父组件发出“关闭”事件以将属性更改为“假”。
推荐阅读
- python-3.x - 从具有给定数据结构的二进制文件中读取
- python - 分区未分配给 Kafka 消费者实例
- html - 嵌套循环如何与玉一起使用?
- java - 加载批处理 XML 配置时未找到 Spring bean,但在应用程序上下文中可用
- php - 这个 zend 控制器和动作如何协同工作?
- twitter-bootstrap - 将 Bootstrap 3 网格应用于特殊的屏幕尺寸
- aapt2 - 原因:'C:\Users\Awaisi3\AppData\Local\Android\Sdk\build-tools\27.0.3\aapt2.exe' 上缺少 aapt2
- angular - Angular 5 调用 AzureAD 保护的 WebAPI 导致 CORS
- sharepoint - $expand 不适用于本地 SharePoint 2013 REST API
- spring - 发布请求不适用于 Spring 安全性和 Angular 5