简体   繁体   English

如何将函数绑定到Shadow DOM内部的元素?

[英]How do I bind a function to elements inside of a Shadow DOM?

I'm working with Web Components and try to bind a click event to an element inside of the Shadow DOM. 我正在使用Web组件,并尝试将click事件绑定到Shadow DOM内部的元素。

1. component.html included as <link rel="import" ...> inside of index.html 1. component.html作为index.html内的<link rel="import" ...>包含在内

<template id="my-element">
    <section>
        <header>
            <content select="h1"></content>
            <button></button>
        </header>
        <content select="div"></content>
    </section>
</template>

2. later element usage: 2.以后的元素用法:

<my-element>
    <h1>Headline</h1>
    <div>...</div>
</my-element>

3. Access element and bind a function to it 3.访问元素并将功能绑定到它

Now I want to add an addEventListener() to the <button> inside of my <my-element> (which is unfortunately hidden through the #shadow-root ) . 现在,我想在我的<my-element>内的<button> 添加一个addEventListener() (不幸的是,它已通过#shadow-root隐藏) Like: 喜欢:

var elemBtn = document.querySelector('my-element button');
elemBtn.addEventListener('click', function(event) {
    // do stuff
});

But that won't work. 但这行不通。 How do I achieve that? 我该如何实现?

You should be able to do this without involving the window object. 您应该能够在不涉及window对象的情况下执行此操作。 Here's a full example: 这是一个完整的示例:

<!-- Define element template -->
<template>
  <h1>Hello World</h1>
  <button id="btn">Click me</button>
</template>

<!-- Create custom element definition -->
<script>
  var tmpl = document.querySelector('template');

  var WidgetProto = Object.create(HTMLElement.prototype);

  WidgetProto.createdCallback = function() {
    var root = this.createShadowRoot();
    root.appendChild(document.importNode(tmpl.content, true));
    // Grab a reference to the button in the shadow root
    var btn = root.querySelector('#btn');
    // Handle the button's click event
    btn.addEventListener('click', this.fireBtn.bind(this));
  };

  // Dispatch a custom event when the button is clicked
  WidgetProto.fireBtn = function() {
    this.dispatchEvent(new Event('btn-clicked'));
  };

  var Widget = document.registerElement('my-widget', {
    prototype: WidgetProto
  });
</script>

<!-- Use the element -->
<my-widget></my-widget>

<!-- Listen for its click event -->
<script>
  var widget = document.querySelector('my-widget');
  widget.addEventListener('btn-clicked', function() {
    alert('the button was clicked');
  });
</script>

Example on jsbin jsbin上的示例

I found out that creating a custom createEvent('MouseEvent'); 我发现创建一个自定义的createEvent('MouseEvent'); inside of <template> will do the trick! <template>里面就能解决问题!

TL;DR http://jsfiddle.net/morkro/z0vbh11v/ TL; DR http://jsfiddle.net/morkro/z0vbh11v/


1. First, you need to add the onclick="" -attribute to our <template> and create a custom event: 1.首先,您需要将onclick=""属性添加到我们的<template>并创建一个自定义事件:

<template id="my-element">
    <section>
        <header>
            <content select="h1"></content>
            <button onclick="callEventOnBtn()"></button>
        </header>
        <content select="div"></content>
    </section>

    <script>
        var btnEvent = document.createEvent('MouseEvent');
        btnEvent.initEvent('oncomponentbtn', true, true);
        var callEventOnBtn = function() {
            window.dispatchEvent(btnEvent);
        };
    </script>
</template>

I create the custom event inside of the <template> and automatically dispatch it to the global window object when the Custom Element gets used later. 我在<template>内创建自定义事件,并在以后使用“自定义元素”时自动将其分派到全局window对象。

2. Now we can listen to that event, when clicking the <button> on our custom element 2.现在,当我们单击自定义元素上的<button>时,我们可以收听该事件

window.addEventListener('oncomponentbtn', function(event) {
    // do stuff
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM