javascript - 使 JavaScript 脚本可用于影子 DOM
问题描述
是否可以在影子 DOM 中启用 JavaScript?我已经尝试了以下方法,但它不起作用。如果没有,有什么替代方案:
@Component({
selector: 'app-website-layout',
templateUrl: './website-layout.component.html',
encapsulation: ViewEncapsulation.ShadowDom
})
export class WebsiteLayoutComponent implements OnInit, AfterViewInit {
private static appendCssToShadowRoot(shadowRoot, src) {
const link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', src);
link.setAttribute('type', 'text/css');
shadowRoot.prepend(link);
}
private static appendJs(src) {
const script = document.createElement('script');
script.src = src;
document.getElementsByTagName('head')[0].appendChild(script);
}
ngAfterViewInit() {
const shadowRoot: DocumentFragment = this.element.nativeElement.shadowRoot;
WebsiteLayoutComponent.appendJs('https://code.jquery.com/jquery-3.4.1.min.js');
WebsiteLayoutComponent.appendJs('https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js');
WebsiteLayoutComponent.appendJs('https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js');
WebsiteLayoutComponent.appendCssToShadowRoot(shadowRoot, 'assets/css/website.css');
WebsiteLayoutComponent.appendCssToShadowRoot(shadowRoot, 'assets/css/page.css');
WebsiteLayoutComponent.appendCssToShadowRoot(shadowRoot, 'assets/css/fonts.css');
}
}
我也尝试了以下方法,但它不起作用
private static appendJsToShadowRoot(shadowRoot, src) {
const link = document.createElement('script');
link.setAttribute('src', src);
shadowRoot.prepend(link);
}
WebsiteLayoutComponent.appendJsToShadowRoot(shadowRoot, 'assets/js/popper.min.js');
WebsiteLayoutComponent.appendJsToShadowRoot(shadowRoot, 'assets/js/bootstrap.min.js');
WebsiteLayoutComponent.appendJsToShadowRoot(shadowRoot, 'assets/js/jquery.min.js');
但是,我可以确认以下内容
WebsiteLayoutComponent.appendJsToShadowRoot(shadowRoot, 'assets/js/test.js');
test.js 的内容在哪里
alert('hello');
奇怪的是,它不适用于 jquery 和 bootstrap,即使我在 HTML 源代码中看到它们。
解决方案
由于库依赖于文档根而不是 shadowroot,因此需要覆盖代码中的文档变量。我最近遇到了一个类似的问题,但它不包括大型库。您可以检查这是否适合您:
function documentParse() {
var element = document.getElementById('shadow_root').shadowRoot
element.createElement = function createElement(type) {
return document.createElement(type)
}
element.head = document.head
return element
}
script.textContent = `(function(document) {
//script source text
}(documentParse()));`
....
以这种方式包装脚本将使对文档的每次搜索都进入 shadowroot dom 内的元素范围。您可能还需要克隆其他文档功能。
推荐阅读
- java - 为什么 for 循环可以保存返回的布尔值但不能保存原始布尔值?
- r - 在 shinyapps.io RShiny 应用程序中使用 h2o 包
- kubernetes - 仅在 tidb 集群中由于 tidb pod 中的连接被拒绝而导致准备就绪问题失败
- python - 如何在 Python 中“堆叠”嵌套列表?
- influxdb-python - 如何从 Python 客户端为 InfluxDB 指定 range() 中的绝对时间?
- go - What errors are outputted to http.Server's ErrorLog struct field?
- python - 如何在字典中附加所有重复的字符串名称以使其成为对象列表?
- javascript - 为什么未定义元素数组上的`join()`在javascript中返回少1个元素?
- javascript - Whatsapp 只分享 window.location.search 的第一个参数
- spring-boot - 部署一个 Spring Boot 应用的战争到本地 Tomcat 服务器:404 响应