标签: shadow-dom

在shadow DOM中执行JS

我正在构建一个模块化的网络应用程序,其中要处理各种用户创建的模型。Shadow DOM 是一个明显的选择,但我不明白 JS 如何在 Shadow DOM 中执行。

我有一个 HTML 内容要使用以下虚拟脚本加载。

<h1>Nice header</h1>
<script type="text/javascript"> 
console.log('hello')
alert('hi');
</script>
Run Code Online (Sandbox Code Playgroud)

我使用之前的脚本加载页面,如下所示:

<div id="shadow-target"></div>
<div id="non-shadow-target"></div>

<script>
    // Called on btn click
    loadShadow = function(module) {
        var root = document.querySelector('#shadow-target').createShadowRoot();
        var lighttarget = document.querySelector('#non-shadow-target');     

        $.get('whatever.html', function (data) { 
            alert(data); 
            $(root).append(data);  // Nothing executed
            $(lighttarget).append(data); // Works fine
            // The header appears in both cases
        });
    }
</script>
Run Code Online (Sandbox Code Playgroud)

正如评论所说,当内容插入到影子 DOM 根时,JS 不会被执行。标头在两种情况下都会出现,但脚本仅在 light DOM 中执行。这是为什么?自定义JS如何在shadow DOM中执行?(没有跨域的东西。)

javascript shadow-dom

5
推荐指数
1
解决办法
3943
查看次数

设置自定义 HTML 元素的样式

我创建了一个普通的自定义元素:

document.registerElement("my-el", { prototype: Object.create(HTMLElement.prototype) }); 
Run Code Online (Sandbox Code Playgroud)

该元素使用 Shadow DOM 和<style>其中的标签。但是,我想让用户在主样式表中定义自定义元素的大小。它通过引用自定义标签来工作,但这是执行此类操作的推荐方法吗?

例如:

my-el {
  width: 300px;
  height: 50px;
  background: green;
}
Run Code Online (Sandbox Code Playgroud)

css web-component shadow-dom custom-element

5
推荐指数
1
解决办法
4959
查看次数

使用链接样式块阴影 DOM 渲染

Shadow DOM 支持使用<link>标签来加载样式,其范围与声明的样式相同<style>,这非常方便,但带来的问题是样式仅在准备就绪时才应用,并且在加载样式时存在 FOUC:defined例如,使用自定义元素的伪选择器无法阻止这种情况。我遇到的另一个问题是在构建或连接自定义元素时测量影子根内部的元素,因为在加载和应用样式表后才知道“真实”尺寸,我不知道什么时候会发生这种情况(也许ResizeObserver实施时会有帮助吗?)
任何人都可以想出一种聪明的方法来解决这些问题(无需手动内联样式或使用构建步骤)?我的担心有道理吗?考虑到<link rel="stylesheet><head>块渲染中并且此功能应该与此类似,是否可以将其视为错误?

styles web-component shadow-dom

5
推荐指数
1
解决办法
1062
查看次数

访问影子根目录内的元素

是否可以使用java和selenium找到Shadow DOM的元素?

我想从影子根中获取元素

<paper-input id="homeSearch" class="home-search-btn home-inputs" placeholder="Where would you like to go?" no-label-float="" tabindex="0" aria-disabled="false"><iron-icon icon="-search-" slot="prefix" class="form-icons search-icon"></iron-icon></paper-input>
Run Code Online (Sandbox Code Playgroud)

我想发送一个输入,homesearch就像driver.findElement(By.id("homesearch"));我在互联网上搜索但没有得到任何适当的解决方案。

在此输入图像描述

任何类型的帮助将非常感激

javascript java selenium xpath shadow-dom

5
推荐指数
1
解决办法
5517
查看次数

如何访问 HTML 自定义元素中的内容文本?

当使用用户嵌入的 JSON 字符串创建 HTML 自定义元素时(尽管字符串的类型与此处不相关)...

<my-elem>
  { "some":"content" }
</my-elem>
Run Code Online (Sandbox Code Playgroud)

我想要JSON.parse这样...

class MyElement extends HTMLElement {
    constructor() {
        super();
        this.root = this.attachShadow({ mode:'open' });
        this.root.appendChild(template.content.cloneNode(true));
    }
    connectedCallback() {
        JSON.parse(this.innerHTML);
    }
}
customElements.define('my-elem', MyElement);

const template = document.createElement('template');
template.innerHTML =  `irrelevant`;
Run Code Online (Sandbox Code Playgroud)

...并使用 Firefox v.63 获得完美结果。

但是用 Chrome v.71 运行这个我得到

Uncaught SyntaxError: Unexpected end of JSON input
Run Code Online (Sandbox Code Playgroud)

由于this.innerHTML返回空字符串。

我还尝试了其他 DOM 方法来访问文本内容,但也都失败了。

现在我对如何让它与 Chrome 一起工作一无所知。

顺便说一句:使用<slot>没有任何帮助,因为我不想渲染文本内容......只能访问它进行解析。

解决

  • 将模板定义放在类定义之前。
  • 确保将定义自定义元素的脚本插入到 HTML 文档中所有自定义元素实例的后面。

html javascript shadow-dom

5
推荐指数
1
解决办法
1834
查看次数

查找元素的可滚动容器,包括在影子 DOM 中

我正在寻找一个通用的解决方案来查找元素的可滚动容器(我想监听滚动事件)。正常的方法是在 DOM 树中向上遍历检查父元素,直到其中一个元素可滚动 -这里有一些类似的解决方案。然而,如果 Shadow DOM 也在图片中,这将会失败。

这是一个示例结构:

<app-home>
  <ion-content>
    #shadow-root
      <div class="inner-scroll">
        <slot>
          -> <my-element> (reveal)
        </slot>
      </div>
    <my-element>...</my-element>
  </ion-content>
</app-home>
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,可滚动元素是.inner-scroll,它位于 的 Shadow dom 内ion-content。由于my-element通过 进入容器slot,向上遍历树将永远不会到达滚动容器(my-element-> ion-content-> app-home)。

我发现它ion-content有一个getScrollElement方法,可以在这种特定情况下使用,但是我想知道是否有一个基于通用 DOM 的解决方案,因为我希望它无论上下文如何都能工作。

更新:

更清楚地说,我希望my-element成为一个独立的、可重用的组件,它可以找到它的滚动容器,无论它放在哪里。我发现,内置scrollIntoView方法适用于 DOM 元素,并且它滚动正确的容器,这意味着浏览器以某种方式找出它,但不会公开返回滚动容器的方法。

另一个想法是在更高级别上侦听滚动事件,而不知道确切的元素,但这也不起作用,因为滚动事件不会传播。

有任何想法吗?

javascript dom shadow-dom ionic4

5
推荐指数
1
解决办法
1987
查看次数

通过querySelectorAll()获取节点列表

给出以下示例代码:

import { LitElement, html, css } from 'lit-element';

class ItemsDisplay extends LitElement {

    static get styles() {...}
    static get properties {...}

    constructor () {
        super();
        ...
    }

    render {
        return html`
            ${this.items.map((item, index, array) => html`
                <div class="name">
                    ...
                </div>
            `)}        
        `;
    }
}
Run Code Online (Sandbox Code Playgroud)

选择类“name”的所有节点的适当方法是什么?

我尝试过以下方法,但均失败;所有时间nodesList都是undefined

  • 里面 constructor
  this.nodesList = this.shadowRoot.querySelectorAll(".name");
Run Code Online (Sandbox Code Playgroud)
  • 使用:
  firstUpdated(changedProperties) {
      return this.nodesList = this.shadowRoot.querySelectorAll(".name");
  }
Run Code Online (Sandbox Code Playgroud)
  • 在自定义函数内部:
  getNodesList() {
      let nodesList = this.shadowRoot.querySelectorAll(".name");
      ...
  }
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

connectedCallback() {
    super.connectedCallback(); …
Run Code Online (Sandbox Code Playgroud)

web-component shadow-dom polymer lit-element

5
推荐指数
1
解决办法
1471
查看次数

如何在自定义元素中使用标题元素?

根据W3C html 规范的这个问题,不鼓励使用具有多个 h1 的嵌套部分,因为没有浏览器实现使它们在语义上工作所需的轮廓算法。

但是,如果我有一个需要使用标题元素的自定义元素,我无法找到推荐的方法来确定标题级别是升级/插入的位置(因此元素可以确定使用哪个 h1-h6)

我发现这篇文章详细介绍了该问题的一些解决方法(更普遍地适用于组件),以及一个特定于 React 的方法,但它们看起来都有些笨拙。

看起来这可能是一个足够普遍的问题,以至于有一个关于如何处理它的推荐模式(比仅仅传递/管理它的属性更好),但我不知道那会是什么(我相当Web 组件的新手)

accessibility html-heading shadow-dom custom-element

5
推荐指数
0
解决办法
130
查看次数

如何将 CSS 文件内容导入 Javascript 变量

考虑一个使用 shadow DOM 的非常简单的自定义元素:

customElements.define('shadow-element', class ShadowElement extends HTMLElement {
  constructor() {
    super();
    this.styleTag = document.createElement('style');
    this.styleTag.textContent= `
.root::before { 
  content: "root here!"; 
  color: green; 
}
    `
    this.shadow = this.attachShadow({mode: 'closed'});
    this.root = null;
  }
  
  connectedCallback() {
    this.root = document.createElement('div');
    this.root.className = 'root';
    this.shadow.append(this.root, this.styleTag);
  }
})
Run Code Online (Sandbox Code Playgroud)
<shadow-element></shadow-element>
Run Code Online (Sandbox Code Playgroud)

为了将 CSS 放入 shadow DOM,我创建了一个style标签,并将其附加到 shadow root 中。到目前为止,这一切都很好。

现在对于更复杂的 CSS,我想shadow-element.css在与 .css 文件位于同一文件夹中的文件中编写它shadow-element.js。除了关注点的分离, 我还需要 IDE 语法突出显示和 CSS 创作的完成,所以我真的希望将 CSS 放在一个单独的专用文件中。

我想将该 CSS 文件的内容导入到 Javascript 变量中,例如

import …
Run Code Online (Sandbox Code Playgroud)

css shadow-dom webpack custom-element es6-modules

5
推荐指数
1
解决办法
3619
查看次数

shadowRoot.getSelection()?

我有一个丰富的编辑器,我正在重写为一个 lit-element 自定义元素。我正在使用 Firefox(最新)进行测试。我正在尝试在自定义元素的 shadowDom 中(在方法中)获取内容可编辑元素的选择。

在 Firefox 调试器中),this.shadowRootshadowRoot 元素看起来是正确的,但this.shadowRoot.getSelection没有定义,即使DocumentOrShadowRootshadowRoot.getSelection()是在 shadow DOM 中获取选择的正确方法。任何人都可以阐明我缺少的东西吗?

非常感谢!

shadow-dom lit-element lit

5
推荐指数
2
解决办法
472
查看次数