语境:
我正在不同的环境中进行有关Web组件组成的测试.特别是我试图通过在所涉及的组件内DOM/ 通过搜索过程从另一个访问其中一个组件来关联多个web Shadow DOM组件.
问题:
假设我们有一个名为x-foo要求访问另一个的Web组件x-randgen.后一个组件公开了前者使用的业务方法.为了避免两个组件之间紧密耦合的通信,我想使用发现机制x-foo来x-randgen通过搜索过程DOM和Shadow DOM模型进行访问.特别是我确定了两种可能的情况.要么都有x-foo和x-randgen实例都在全球范围内(index.html的),或者他们都出现另一个模板内,说x-bar.问题是搜索过程应该在每种情况下以不同的方式实现.接下来,我用我的方法总结了一个伪代码,实质上是我的问题.(全球范例可以在这里找到:http://jsbin.com/qokif/1/)
Polymer('x-foo', {
...
getRandGen: function () {
if (<<x-foo & x-randgen are in the global context>>)
return document.querySelector('x-randgen');
else if (<<x-foo & x-randgen are in a template>>)
return <<the x-randgen tag within the template>>;
}
});
Run Code Online (Sandbox Code Playgroud)
题:
如果有人可以根据聚合物技术以适当的方式重新制作上面的片段,我将不胜感激.
从文档中可以看出,该<content>元素支持一个select通过简单选择器过滤节点的属性.
那么针对某个内容元素的light dom元素是否应该包含一个css类标签/标签/值,允许浏览器将其映射到在select属性中设置了css标签/标签/值的相应内容元素?是否包含light dom元素,没有这样的标签映射到<content>没有select属性的元素?枚举可能性的一个例子将非常有用.
我想检测将阴影附加到宿主元素的事件。
用例:用于MutationObserver观察任何 DOM 更改并对更改的内容进行后处理,作为绑定(捆绑)框架逻辑的一部分。
为什么我需要检测此事件?为了能够监视 ShadowDOM 中的变化,MutationObserver应该创建另一个并在 ShadowRoot 上设置 - 这工作得很好,所以唯一的问题是检测新创建的阴影。
不用说,这显然MutationObserver无法检测到attachShadow操作,尝试将所有选项标志设置为 true 。
注意:我在这个论坛上知道这个问题,但恕我直言,这不是完全相同的问题。
更新:
我将 @Supersharp 的答案标记为问题的答案,因为看起来代理本机attachShadow方法是目前观察此操作的唯一方法。
然而,与我们不是代理appendChild、removeChild、innerHTML/textContent等,而是依赖定义良好的MutationObserverAPI 的事实类似,在这种情况下,也必须有一种方法来实现相同的目标,而不会潜在地破坏本机 API 行为或追赶和管道任何其他可能的未来方式来附加阴影(并且可能也会删除?,已经有覆盖)等。
attachShadow我已经在MutationObserver 这里发布了支持提案。
我在文档中的任何地方都找不到它,但是当我单击作为父组件一部分的组件中的某个东西时,Node.contains()函数不起作用。
我的父组件如下所示:
<div class="body">
<div class="item" *ngFor="let item of sortedItems;">
<cv-checkbox></cv-checkbox>
<cv-svg-icon></cv-svg-icon>
</div>
<div class="drop-zones" *ngFor="let zone of sortedItems.length + 1 | numberToArrayPipe;>
<div class="drop-zone"></div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
如您所见,我的父组件中有两个Angular组件:cv-checkbox和cv-svg-icon。我向我的父组件添加了一个指令,如下所示:
<cv-layer-manager cvClickOutside (clickOutside)="toggleLayerManager()"></cv-layer-manager>
Run Code Online (Sandbox Code Playgroud)
我在哪里检查单击的节点是否包含在父级中,如下所示:
@HostListener('document:click', ['$event']) public onClick(event: MouseEvent) {
const clickedInside = this._elementRef.nativeElement.contains(event.target);
if (!clickedInside) {
this.clickOutside.emit();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我单击普通的HTML组件,那么一切都会按预期运行,但是当我单击Angular组件时,则不能正常运行。包含不检查Angular组件内部是否正确?
我用普通的 html/css/js 制作了一个简单的复制粘贴组件。我试图将它变成一个 Web 组件,但无法再使复制粘贴行为起作用。
shadow DOM 内部的标记基本上是
<span contenteditable="true">
<slot></slot>
</span>
<button>Copy</button>
Run Code Online (Sandbox Code Playgroud)
Javascript:
class CopyPaste extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(copyPasteTemplate.content.cloneNode(true));
}
connectedCallback() {
let copyButton = this.shadowRoot.querySelector('button');
let textToCopy = this.shadowRoot.querySelector('span');
function selectElementContents(el) {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
function copyText() {
selectElementContents(textToCopy);
document.execCommand('copy');
}
copyButton.addEventListener('click', copyText);
textToCopy.addEventListener('click', copyText);
}
}
window.customElements.define('copy-paste', CopyPaste);
Run Code Online (Sandbox Code Playgroud) 使用 TamperMonkey 简化我这边的页面视图,并希望隐藏部分外部来源的 Twitter 卡片以防止打印。EmbeddedTweet 中的图像无论如何都不会打印,并留下一个大的空白矩形,浪费了宝贵的空间。
DOM 如下图所示 - 我将如何使用类SummaryCard-image(绿色箭头)定位 DIV ?对我来说,DIV 是从 DOM 中删除还是用 CSS 隐藏都无关紧要。
我尝试了以下方法,但都不起作用:
(1) 注入 CSS .SummaryCard-image{display:none !important;}
(2) jQuery: $('.SummaryCard-image').remove();
$('.SummaryCard-image').length 返回 0
(注意
#shadow-root (open)从顶部开始的第二个元素)
有没有办法在webcompoenents上添加css:hover效果(不是来自父级)。
我有以下示例代码
window.customElements.define('a-b', class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'}).innerHTML = `
<style>
:host {
display: block;
height: 100px;
width: 100px;
background: red;
}
:host:hover {
background: blue;
}
:host::selection {
background: rgba(0, 0, 0, 0.15);
}
</style>
<slot></slot>
`;
}
}
Run Code Online (Sandbox Code Playgroud)
该:host::selection物业按预期工作。但是:host:hover似乎没有任何作用。
我知道有解决此问题的方法,例如:
div:hover在父样式表上应用效果但是我想知道我是否只是为了简化代码而错过了一些东西(因为这似乎不太复杂)。
我正在尝试访问元素上的 ShadowRoot 并且该属性element.shadowRoot正在返回null.
在ShadowDOM被定义为mode: 'open',这是正确的,我甚至可以console.log(element)看到所有的属性和shadowRootIS的目的ShadowRoot的类型。
在我的应用程序中,我试图像这样访问该属性:
let el = document.getElementById('elementId');
...
console.log(el);
console.log("this.shadowRoot = ???");
console.log(el.shadowRoot);
Run Code Online (Sandbox Code Playgroud)
这个可以吗?
附件是console.log()控制台的输出,你可以看到shadowRoot肯定在那里。
(来自 Firefox 控制台)

我在最新的 Firefox 和 Chrome 中都试过,结果都一样。
我究竟做错了什么?
谢谢
编辑
我创建了一个小 JSFiddle。
如果您按下F12并查看控制台,您可以看到该元素已被记录并显示该shadowRoot属性,但会记录shadowRoot显示null。
我想知道这是一个错误吗?也许它还没有完全实施?
我在 Firefox 中看到了Element.shadowRoot,但我使用的是最新的 (65) Firefox 和 (72) Chrome。
我试图找出如何设置要在 Angular 的 ngTemplateOutlet 中应用的自定义样式。我有两个组件,一个父组件和一个子组件,我将一个模板从父组件传递给子组件,然后使用 ngTemplateOutlet 打印该模板。我想要做的是使用父级和子级的样式呈现模板,而不仅仅是一种或另一种。
这是我的父组件的 HTML 的样子:
<child-component [template]="myTemplate">
<ng-template #myTemplate>
<p class="paragraph">Hello</p>
</ng-template>
</child-component>
Run Code Online (Sandbox Code Playgroud)
CSS:
.paragraph { color: red; }
Run Code Online (Sandbox Code Playgroud)
还有孩子:
<ng-container *ngTemplateOutlet="myTemplate"></ng-container>
Run Code Online (Sandbox Code Playgroud)
CSS:
.paragraph { font-weight: bold; }
Run Code Online (Sandbox Code Playgroud)
我想要发生的是看到带有红色背景和粗体字母的“Hello”,但是 Angular 的 shadow DOM 封装迫使模板忽略孩子的样式。
我知道我可以通过删除 DOM 封装来解决这个问题,但这不是一个选项,因为我想避免将 CSS 类添加到全局命名空间。所以我想知道是否有一种方法可以在 Angular 中干净地实现期望效果。
我一直在关注如何使用硒自动实现阴影DOM元素的讨论。与#shadow-root (open)元素一起工作。
在通过“ 硒”访问url时出现Clear data的“ 清除浏览数据”弹出窗口中定位按钮的过程中,我无法找到以下元素:chrome://settings/clearBrowserData
#shadow-root (open)
<settings-privacy-page>
Run Code Online (Sandbox Code Playgroud)
快照:
使用Selenium,以下是我的代码试用以及遇到的相关错误:
尝试1:
WebElement root5 = shadow_root4.findElement(By.tagName("settings-privacy-page"));
Run Code Online (Sandbox Code Playgroud)
错误:
Exception in thread "main" org.openqa.selenium.JavascriptException: javascript error: b.getElementsByTagName is not a function
Run Code Online (Sandbox Code Playgroud)尝试2:
WebElement root5 = shadow_root4.findElement(By.cssSelector("settings-privacy-page"));
Run Code Online (Sandbox Code Playgroud)
错误:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"settings-privacy-page"}
Run Code Online (Sandbox Code Playgroud)尝试3:
WebElement root5 = (WebElement)((JavascriptExecutor)shadow_root4).executeScript("return document.getElementsByTagName('settings-privacy-page')[0]");
Run Code Online (Sandbox Code Playgroud)
错误:
Exception in thread "main" java.lang.ClassCastException: org.openqa.selenium.remote.RemoteWebElement cannot be cast to org.openqa.selenium.JavascriptExecutor …Run Code Online (Sandbox Code Playgroud)shadow-dom ×10
javascript ×6
css ×3
angular ×2
dom ×2
html ×2
polymer ×2
events ×1
java ×1
ng-template ×1
polymer-1.0 ×1
selenium ×1
tampermonkey ×1