问题
When working with Custom Elements that leverage Shadow DOM, what is the official approach to injecting 3rd party scripts and elements such as Invisible reCAPTCHA which require scripts such:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>`
for HTML elements such as a <button>
to be leaded and reCAPTCHA to be rendered?
shadowRoot
doesn't seem to have anything like head
, is the script supposed to be added to the created template
's innerHTML
? Or is a <script>
to be appended to the shadowRoot via appendChild
in connectedCallback()
? What is the official approach to working with 3rd party libraries within Shadow DOM? Loading the script on the page containing the rendered Custom Element doesn't seem to trigger a render due to Shadow DOM.
const template = document.createElement('template');
template.innerHTML = `
<form>
<button class="g-recaptcha"
data-sitekey="your_site_key"
data-callback='onSubmit'>Submit</button>
</form>
`;
class CustomElement extends HTMLElement {
constructor() {
super(); // always call super() first in the ctor.
this.attachShadow({mode: 'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
connectedCallback() {
...
}
disconnectedCallback() {
...
}
attributeChangedCallback(attrName, oldVal, newVal) {
...
}
}
Thank you for any guidance you can provide.
回答1:
There's no offical approach because the solution depends on the 3rd party library implementation.
However, in the case of reCaptcha, the workaround is to expose the <button>
in the normal DOM, and inject it in the Shadow DOM via the <slot>
element.
class extends HTMLElement {
constructor() {
super()
this.attachShadow( {mode: 'open'} ).innerHTML= `
<form>
<slot></slot>
</form>`
}
connectedCallback() {
this.innerHTML = `
<button
class="g-recaptcha"
data-sitekey="your_site_key"
data-callback="onSubmit">Submit</button>`
}
})
来源:https://stackoverflow.com/questions/47226529/custom-element-web-component-shadow-dom-vendor-scripts-elements