< content>下的Shadow DOM事件如何?有针对性? [英] How are Shadow DOM events from under <content> targeted?

查看:52
本文介绍了< content>下的Shadow DOM事件如何?有针对性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解通过<content>元素在影子DOM中接收到的,来自轻型DOM的事件是什么样的.我正在阅读 Shadow DOM W3C Draft ,但我没有完全理解它,但是从EventListener附件的角度来看,听起来好像事件是重新定向"的.

I'm trying to understand what events that originate in light DOM look like when received in shadow DOM via a <content> element. I'm reading the Shadow DOM W3C Draft, and I don't entirely understand it but it sounds like events are to be "retargeted" from the point of view of the EventListener attachment.

在事件路径跨多个节点树的情况下, 有关事件目标的事件信息会按顺序进行调整 保持封装.事件重新定向是计算的过程 事件所在节点的每个祖先的相对目标 派遣.相对目标是最准确的节点 代表指定祖先的已调度事件的目标,而 保持封装状态.

In the cases where event path is across multiple node trees, the event's information about the target of the event is adjusted in order to maintain encapsulation. Event retargeting is a process of computing relative targets for each ancestor of the node at which the event is dispatched. A relative target is a node that most accurately represents the target of a dispatched event at a given ancestor while maintaining the encapsulation.

在事件分发时:

At the time of event dispatch:

  • Event target和currentTarget属性必须返回相对值 调用事件侦听器的节​​点的目标
  • The Event target and currentTarget attributes must return the relative target for the node on which event listeners are invoked

因此,这是一个简单的Polymer自定义元素,该元素只是将其子元素放入容器中,并向容器(在阴影DOM中)添加了一个ClickEventListener.在这种情况下,孩子是一个按钮.

So here's a simple Polymer custom element that just puts its children into a container, and adds a click EventListener to the container (in the shadow DOM). In this case the child is a button.

<!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 canary上运行此程序时,单击按钮时,我得到:

When I run this on Chrome 38.0.2075.0 canary, when I click on the button I get:

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

当我单击容器时,我得到:

and when I click on the container I get:

MouseEvent {dataTransfer: null, toElement: div#internal-container, fromElement: null, y: 15, x: 82…} test.html:17
DIV internal-container test.html:20

所以我会在灯光或阴影DOM中获得事件目标,具体取决于 source 元素所在的DOM.在两种情况下,我都希望从阴影DOM中获得目标,因为附加EventListener的位置.我的问题是:

So I get an event target in either the light or shadow DOM, depending on which DOM the source element was in. I was expecting to get a target from the shadow DOM in both cases because that's where the EventListener is attached. My questions are:

  1. 这是应该工作的方式吗?
  2. 如果是这样,是否有另一种方法来获取从轻型DOM重新定向到影子DOM冒泡的事件?

万一有人想问:你想做什么?",我除了理解行为之外,没有做其他专门的事情.

In case someone wants to ask, "What are you trying to do?", I'm not trying to do anything specifically other than understand the behavior.

推荐答案

带有影子dom的事件非常棘手.我尝试在下面捕获一个转储.

  1. 这是应该工作的方式

是的.如果您正在Chrome浏览器中进行测试,则会获得本地阴影dom.

Yep. If you're testing in Chrome, you get native shadow dom.

我在 HTML5Rocks中编写了有关事件重定向的部分- Shadow DOM 301 文章.基本上,重新定向意味着源自影子域的事件看起来像是来自元素本身.

I wrote a section on event retargeting in the HTML5Rocks - Shadow DOM 301 article. Basically, retargeting means that events that originate in the shadow dom look like they come from the element itself.

在您的示例中,您正在记录影子dom内部的事件,因此该事件仍然存在.如果您还在元素外部添加"click"侦听器,则目标看起来就像来自元素:

In your example, you're logging the event internal to the shadow dom, so it's still seen there. If you also add a 'click' listener outside of the element, the target will look as if it came from the element:

<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

点击"事件冒泡.这就是为什么您在顶部示例中看到BUTTON的原因.你为什么看到它呢?之所以会看到它,是因为该按钮不是元素的阴影dom的一部分.它是在光域和元素的目标中.重要的是要记住,轻型DOM节点在逻辑上仍位于主文档中.它们不会移入阴影dom,而只是在<content>插入点处呈现.

The 'click' event bubbles. This is why you see BUTTON in your top example. Why do you see it at all? You see it because the button is not part of your element's shadow dom. It's in the light dom and the target of the element. It's important to remember that light DOM nodes are still logically in the main document. They're not moved into the shadow dom, merely rendered at <content> insertion points.

顺便说一句,您的示例有几个聚合修复程序:

BTW, there are a couple of Polymerized fixes to your examples:

  1. this.shadowRoot.querySelector('#internalcontainer')-> this.$.internalcontainer. this.$.ID是Polymer的自动找到节点"功能.
  2. 您根本不需要使用addEventListener().而是使用<div id="internalcontainer" on-click="{{clickHandler}}">.这是一个声明性事件处理程序.
  1. this.shadowRoot.querySelector('#internalcontainer') -> this.$.internalcontainer. this.$.ID is Polymer's "automatic node finding" feature.
  2. You don't need to use addEventListener() at all. Instead , use <div id="internalcontainer" on-click="{{clickHandler}}">. This is a declarative event handler.

这篇关于&lt; content&gt;下的Shadow DOM事件如何?有针对性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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