我正在尝试了解通过<content>
元素在shadow DOM中收到的源自light DOM的事件。我正在阅读Shadow DOM W3C Draft,我并不完全理解它,但听起来事件要从EventListener附件的角度“重新定位”。
在事件路径跨越多个节点树的情况下, 事件的有关事件目标的信息将按顺序进行调整 保持封装。事件重定向是一个计算过程 事件所在节点的每个祖先的相对目标 出动。相对目标是最准确的节点 表示给定祖先的调度事件的目标 保持封装。
和
在事件发送时:
- Event target和currentTarget属性必须返回相对值 调用事件侦听器的节点的目标
因此,这是一个简单的Polymer自定义元素,只将其子项放入容器中,并向容器添加一个ClickListener(在shadow DOM中)。在这种情况下,孩子是一个按钮。
<!DOCTYPE html>
<html>
<head>
<script src="bower_components/platform/platform.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html">
</head>
<body unresolved>
<polymer-element name="foo-bar">
<template>
<div id="internal-container" style="background-color:red; width:100%;">
<content></content>
</div>
</template>
<script>
Polymer("foo-bar", {
clickHandler: function(event) {
console.log(event);
var element = event.target;
while (element) {
console.log(element.tagName, element.id);
element = element.parentElement;
}
},
ready: function() {
this.shadowRoot.querySelector('#internal-container').addEventListener('click', this.clickHandler);
}
});
</script>
</polymer-element>
<foo-bar id="custom-element">
<button>Click me</button>
</foo-bar>
</body>
</html>
当我在Chrome 38.0.2075.0金丝雀上运行时,当我点击按钮时,我得到:
MouseEvent {dataTransfer: null, toElement: button, fromElement: null, y: 19, x: 53…}altKey: falsebubbles: truebutton: 0cancelBubble: falsecancelable: truecharCode: 0clientX: 53clientY: 19clipboardData: undefinedctrlKey: falsecurrentTarget: nulldataTransfer: nulldefaultPrevented: falsedetail: 1eventPhase: 0fromElement: nullkeyCode: 0layerX: 53layerY: 19metaKey: falsemovementX: 0movementY: 0offsetX: 45offsetY: 10pageX: 53pageY: 19path: NodeList[0]relatedTarget: nullreturnValue: truescreenX: 472screenY: 113shiftKey: falsesrcElement: buttontarget: buttontimeStamp: 1404078533176toElement: buttontype: "click"view: WindowwebkitMovementX: 0webkitMovementY: 0which: 1x: 53y: 19__proto__: MouseEvent test.html:17
BUTTON test.html:20
FOO-BAR custom-element test.html:20
BODY test.html:20
HTML test.html:20
当我点击容器时,我得到:
MouseEvent {dataTransfer: null, toElement: div#internal-container, fromElement: null, y: 15, x: 82…} test.html:17
DIV internal-container test.html:20
所以我在light或shadow DOM中获得了一个事件目标,具体取决于 source 元素所在的DOM。我希望在两种情况下从shadow DOM获取一个目标,因为那是附加EventListener的位置。我的问题是:
如果有人想问,“你想做什么?”,除了理解这种行为外,我不会做任何具体的事情。
答案 0 :(得分:13)
带阴影dom的事件很棘手。我尝试在下面捕捉一个题库。
- 这是它的运作方式
醇>
是的。如果您在Chrome中进行测试,则会获得原生阴影。
我在HTML5Rocks - Shadow DOM 301文章中写了一个关于事件重定向的部分。基本上,重新定位意味着源于阴影dom的事件看起来像是来自元素本身。
在您的示例中,您将事件记录在阴影dom的内部,因此它仍然可以在那里看到。如果您还在元素之外添加“click”侦听器,则目标看起来好像来自元素:
<script>
var el = document.querySelector('#custom-element');
el.addEventListener('click', function(e) {
console.log(e.target.tagName); // logs FOO-Bar
});
</script>
http://jsbin.com/womususe/1/edit
'click'事件起泡。这就是您在顶部示例中看到BUTTON
的原因。为什么你会看到它?你看到它是因为按钮不是元素阴影dom的一部分。它在光明的dom和元素的目标中。重要的是要记住轻型DOM节点仍然在逻辑上位于主文档中。它们不会移动到阴影dom中,只会在<content>
插入点处渲染。
顺便说一下,您的示例中有几个Polymerized修复程序:
this.shadowRoot.querySelector('#internalcontainer')
- &gt; this.$.internalcontainer
。 this.$.ID
是Polymer的“自动节点查找”功能。addEventListener()
。相反,请使用<div id="internalcontainer" on-click="{{clickHandler}}">
。这是一个声明性事件处理程序。