6

我刚刚遇到了一个有趣的情况,我在<button>放置在<form>.

  <form id="one" action="" method="get">
    <s-button>Select</s-button>
      #shadow-root
        <button>...</button>
    <button>Outside</button>
  </form>

我也有一个<button>作为直系子女的<form>

孩子<button>使表单提交。

<button>在 shadow-root 中没有。

在某种程度上,我想这是有道理的。但是有没有人想出一种方法来告诉 shadow-root<button>可以正常工作,<form>或者这是我必须通过 JS 处理的事情?

我知道点击事件在 Shadow DOM 层被阻止,但令我惊讶的是,没有办法让按钮仍然是表单的一部分,可以通过属性或属性进行设置。

当然,我可以捕获单击事件,然后从中发送一个新事件,this但这不会做同样的事情,因为我的事件将不再是用户生成的,并且有大量与之相关的规则。

4

3 回答 3

3

按钮触发提交事件(在 FORM 元素上)

由于事件不能通过影子 DOM 边界(不要冒泡进入父 DOM)

我认为这就是为什么submitFORM 元素没有接收到 shadowDOM 按钮(调度事件)的原因。

需要 Supersharp 解决方法,在 light DOM 中使用隐藏按钮(然后submit在父 DOM 中调度事件)

或者(从轻量级 DOM 开始)您找到(父)FORM 标签并自己发送提交事件:

this.closest('FORM').dispatchEvent(new Event('submit'))


关注 shadowDOM 和 FORM 方面的专家:https ://github.com/w3c/webcomponents/issues/187


customElements.define( 'my-button', class extends HTMLElement {
  connectedCallback() {
    this.attachShadow({mode:'open'}).innerHTML=`<button>Button In Shadow DOM</button>`
    this.onclick = _ => this.closest('FORM').dispatchEvent(new Event('submit'))
  }
})
<form onsubmit="return console.log('submit Event occured')">
    <my-button></my-button>
    <button>button in Document DOM</button>
</form>

嵌套的 shadowDOM

如果 FORM 不是直接祖先,您可以通过以下方式找到它:How to reference to a method in parent component from child component with vanilla JS Web Components?(不是任何框架或库)

于 2019-01-27T09:41:58.833 回答
2

无论如何,您都必须通过 Javascript 来处理它。

<button>一个简单的解决方案是在 light DOM 中添加一个(屏蔽的) ,并将click事件传递给它。

customElements.define( 's-button', class extends HTMLElement {
    connectedCallback() {
        this.attachShadow( {mode: 'open'})
            .innerHTML = `<button>In Shadow</button>`
        var submit = this.appendChild( document.createElement( 'button' ) )
        this.onclick = () => submit.click()
    }
} )
<form onsubmit="console.log('submitted');return false">
    <s-button>Select</s-button>
    <button>Outside</button>
</form>

于 2019-01-25T19:01:03.800 回答
0

您可以做的其他事情不完全是 ShadowDOM 中的按钮,如果您button[type=submit]已被插入 ShadowDOM。所以如果你有类似的东西:

<some-component>
<button type="submit" slot="buttonSlot"></button>
</some-component>

该按钮可用于触发您的表单。该按钮位于轻量级 DOM 中,但可以通过插槽在组件内轻松处理。它还将保留所有适当的键盘、单击、焦点等事件,而不会遇到任何麻烦。

要最小化 light DOM html,你甚至不需要它,type=submit你可以在你的组件中设置它,它仍然会被视为 light DOM 中任何父表单的提交按钮。

奖励(或者可能是麻烦,取决于您如何看待它),它将保留页面上其他按钮的样式(除非您在组件中更改它)。

于 2021-11-14T19:27:53.293 回答