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

时间:2015-02-05 23:48:50

标签: javascript html web-component shadow-dom custom-events

我正在使用Web Components并尝试将click事件绑定到Shadow DOM内部的元素。

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。以后的元素用法:

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

第3。访问元素并将函数绑定到它

现在我想添加 addEventListener()<button> 内部的<my-element>(遗憾的是,{{1}隐藏了#shadow-root })。像:

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

但那不会奏效。 我如何实现这一目标?

2 个答案:

答案 0 :(得分:5)

您应该能够在不涉及窗口对象的情况下执行此操作。这是一个完整的例子:

<!-- 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

答案 1 :(得分:0)

我发现在createEvent('MouseEvent');内创建自定义<template>就可以了!

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


<强> 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>

我在<template>内创建自定义事件,并在以后使用自定义元素时自动将其分派给全局window对象。

<强> 2。现在,我们可以在点击自定义元素

上的<button>时收听该事件
window.addEventListener('oncomponentbtn', function(event) {
    // do stuff
});