2015-02-05 47 views
1

我正在使用Web组件,并尝试将click事件绑定到Shadow DOM内的元素。包括如何将函数绑定到Shadow DOM中的元素?

1. component.html作为<link rel="import" ...>的index.html的内部

<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>(不幸通过#shadow-root隐藏)。喜欢:

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

但那不行。 我该如何做到这一点?

回答

5

你应该能够做到这一点,而不涉及窗口对象上单击<button>时听那个事件。这里有一个完整的例子:

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

+0

嗯,这是令人沮丧的。你的解决方案比我的更聪明:D – morkro 2015-02-06 18:37:59

+0

@morkro你介意把这个答案标记为正确吗? – mudasobwa 2015-02-07 06:22:46

+0

当然!感谢@robdodson为我展示了一种更好的方式:) – morkro 2015-02-07 09:27:22

0

我发现在<template>里面创建一个自定义的createEvent('MouseEvent');就可以了!

TL; DRhttp://jsfiddle.net/morkro/z0vbh11v/


1.首先,你需要将onclick="" -attribute添加到我们的<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对象w自定义元素稍后会被使用。

2.现在我们可以在我们的自定义元素

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