在此代码片段中,我有一个
wc-notifier
组件来显示错误。显示现有错误 (Oh no existing error!
)。
然后显示“表单模式”(
wc-modal-form
),其中包含供用户填写的输入。目前,它错误地出现在错误消息前面(错误消息应该位于顶部)。如果单击下面的“验证”按钮,附加错误消息也会错误地显示在表单模式下方(错误消息应位于顶部)。我不知道如何使错误通知器(对话框)出现在表单模式(对话框)的顶部。
如何改变浏览器中元素的顺序
Top-layer
?
我已经尝试了所有可以使用的技巧,包括定义组件的顺序、创建组件的顺序、打开对话框的顺序。
class NotifierComponent extends HTMLElement {
constructor() {
super().attachShadow({mode:'open'});
const template = document.getElementById("TEMPLATE_notifier");
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
error(msg) {
const errorEl = document.createElement('div');
errorEl.innerText = msg;
this.appendChild(errorEl)
}
}
window.customElements.define('wc-notifier', NotifierComponent);
document.getElementById("NOTIFIER").error("Oh no existing error!")
class FormModalComponent extends HTMLElement {
constructor() {
super().attachShadow({mode:'open'});
const template = document.getElementById("TEMPLATE_modalform");
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
showModal() {
this.shadowRoot.getElementById("MODAL").showModal();
}
}
window.customElements.define('wc-modal-form', FormModalComponent);
const modalFormEl = document.createElement('wc-modal-form');
document.body.appendChild(modalFormEl)
modalFormEl.showModal();
<template id="TEMPLATE_notifier">
<style>
dialog {
display: flex;
gap: 16px;
flex-direction: column;
border: none;
background: none;
top: 0;
margin-left: auto;
margin-right: 0;
}
::slotted(*) {
background: red;
padding: 16px 8px;
}
</style>
<dialog>
<slot></slot>
</dialog>
</template>
<wc-notifier id="NOTIFIER"></wc-notifier>
<template id="TEMPLATE_modalform">
<style>
dialog {
background: cream;
padding: 64px;
width: 100%;
}
</style>
<dialog id="MODAL">
<div>This is the FORM MODAL. It should appear below the errors</div>
<button id="VALIDATE" type="button" onclick="document.getElementById('NOTIFIER').error('Please fill out all the required form fields')">Validate Form</button>
</dialog>
</template>
关键在于在正确的时间申请
.showModal()
。
请阅读:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
这是一个(不完美的)游乐场:
https://jsfiddle.net/WebComponents/gtn86p5c/
<template id="WC-NOTIFIER">
<style>
dialog {
display: block;
width: 50vh;
height: 50vh;
background: lightcoral;
}
::slotted(*) {
/* doesn't work on TEXT nodes only */
background: red;
height: 100%;
}
</style>
<dialog>
<slot></slot>
</dialog>
</template>
<wc-notifier id="NOTIFIER">EXISTING ERROR</wc-notifier>
<template id="WC-MODAL-FORM">
<style>
dialog {
width: 100%;
text-align:center;
}
</style>
<dialog>
<div>This is the FORM MODAL. It should appear below the errors</div>
<button id="VALIDATE" type="button" onclick="this.getRootNode().host.validate()">Validate Form</button>
</dialog>
</template>
<script>
class BaseClass extends HTMLElement {
constructor() {
super()
.attachShadow({mode:'open'})
.append(document.getElementById(this.nodeName).content.cloneNode(true));
}
get dialog(){
return this.shadowRoot.querySelector("dialog");
}
showModal(){
this.close(); /* can not re-open <dialog> as modal */
this.dialog.showModal();
}
close(){
this.dialog.close();
}
open(){
this.dialog.open();
}
connectedCallback() {
this.showModal();
console.log("connected", this.nodeName);
}
}
customElements.define('wc-notifier', class extends BaseClass {
set error(innerText) {
this.innerHTML = "";
this.append(Object.assign(document.createElement('div'), {
innerText,
onclick: evt => this.close()
}));
this.showModal();
}
});
customElements.define('wc-modal-form', class extends BaseClass {
validate() {
// This is tight coupling!! Should do this with Events!!
document.getElementById("NOTIFIER").error = "VERIFY INPUTS!";
}
});
// executed BEFORE <wc-modal-form> !! so NOT stacked at the top!
document.getElementById("NOTIFIER").error = "NEW ERROR";
</script>
<wc-modal-form></wc-modal-form>