在Shadow DOM中使用JS库 [英] Using JS libraries inside Shadow DOM

查看:69
本文介绍了在Shadow DOM中使用JS库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图解决这个问题,但无济于事.

I've been trying to figure this out for hours to no avail.

基本上,我正在制作一个Chrome扩展程序,该程序将一堆HTML加载到页面中.为了防止出现很多问题,我想使用Shadow DOM进行封装.CSS封装得很好,一段时间后,我终于也设法将JS加载到DOM中.

Basically, I'm making a Chrome Extension that loads a bunch of HTML into the page. To prevent a lot of issues, I wanted to use Shadow DOM for encapsulation. CSS encapsulates fine, and after a while I finally managed to load JS into the DOM as well.

问题是,我包括2个JS文件:

Problem is, I'm including 2 JS files:

  • vendor.js(我使用的JS库,编译成一个文件.著名的库:jQuery和Angular)
  • extension.js-我自己的代码编译成一个文件(执行一些初始化,引导Angular并定义控制器/指令/等)

问题是,加载 vendor.js 文件后,我无法访问它在其他脚本中应用的内容.

The problem is, after loading the vendor.js file, I can't access things it applied inside the other script.

对于我一生,我无法弄清楚它所登录的上下文并用作将类注入其中的窗口"元素.

For the life of me I can't figure out which context it signs into and uses as a "window" element to inject classes into.

这是我的Shadow DOM初始加载脚本:

Here's my Shadow DOM initial loading script:

// HACK: we need to "bleed" font-faces to outside the shadow dom because of a bug in chrome
document.querySelector('head').innerHTML +=
  '<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />'

let rootElHtml = `
    <div id="cls-root">
      <template id="cls-template">
      </template>
    </div>
  `

document.body.innerHTML += rootElHtml
let rootEl = document.querySelector('#cls-root'),
  templateEl = rootEl.querySelector('template'),
  shadow = rootEl.attachShadow({
    mode: 'open'
  })

let cssLinks = [
  chrome.extension.getURL('dist/css/vendor.css'),
  chrome.extension.getURL('dist/css/extension.css'),
  '//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css'
].map(p => `<link rel="stylesheet" href="${p}" />`).join("\n")

let jsLinks = [
  chrome.extension.getURL('dist/js/vendor.js'),
  chrome.extension.getURL('dist/js/extension.js'),
].map(p => `<script src="${p}" type="text/javascript"></script>`).join("\n")

// inject css/js into template content
let templateNodeContents = document.createElement('div')
templateNodeContents.innerHTML = [cssLinks, jsLinks].join("\n")
for (let node of templateNodeContents.childNodes)
  templateEl.content.appendChild(node)

// load remote HTML template and apply into shadow root template
fetch(chrome.extension.getURL('dist/templates/root.html')).then((data) => {
  data.text().then((body) => {
    let bodyContainer = document.createElement('div')

    shadow.appendChild(document.importNode(templateEl.content, true))
    bodyContainer.innerHTML = body
    shadow.appendChild(bodyContainer.childNodes[0])
  })
})

window._clsExt = shadow

这是我尝试引导Angular的方法:

And here's me trying to bootstrap Angular:

const shadow = document.querySelector('#cls-root').shadowRoot

shadow.APP_NAME = 'myApp'
shadow.app = angular.module(APP_NAME, ['ngStorage'])
  .config(['$localStorageProvider', '$httpProvider',
    ($localStorageProvider, $httpProvider) => {
      $localStorageProvider.setKeyPrefix('myApp');
      $httpProvider.interceptors.push(apiInterceptor);
    }
  ])
shadow.app.constant('APP_ENV', APP_SETTINGS.app_env)
shadow.app.constant('API_BASE', APP_SETTINGS.api_base_url)
angular.bootstrap(shadow, [APP_NAME])

但是,我一直遇到关于角度的错误:

However, I keep encountering errors about angular:

extension.js:21 Uncaught ReferenceError: angular is not defined
    at extension.js:21

我尝试浏览了shadow元素的属性以及其他 window 变体,并尝试在其中查找文档.

I tried looking around inside the properties of the shadow element, as well as other window variations and attempting to find the document inside.

是否可以不通过强制将文件合并在一起?我想保持这种分离.

Is this possible without combining the files together by force? I'd like to have this separation remain.

推荐答案

我看到您将JS文件添加到Shadow DOM范围中.由于访问Shadow dom中的元素是不同的,并且库在其中不起作用,因此无法使用.

I see that you add JS files into the Shadow DOM scope. It doesn't work as accessing the elements in Shadow dom is different and the libraries don't work inside them.

当我说访问DOM时不同

When I say accessing DOM is different

$(#id) //the usual way to access a id using jQuery
parentofShadowtree.shadowRoot.querySelector('#id') //to select a element inside shadow DOM

如您所见,在Shadow DOM中访问DOM元素是不同的,通常的JS库文件无法访问这些元素,并且在这里不起作用

As you can see accessing DOM elements inside Shadow DOM is different, the usual JS library files can't access the elements and don't work here

如果我错了,请纠正我.

Correct me if I am wrong.

这篇关于在Shadow DOM中使用JS库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆