【问题标题】:Javascript Binding Function to Shadow DOM and Custom ElementsJavascript 绑定函数到 Shadow DOM 和自定义元素
【发布时间】:2015-01-02 20:11:23
【问题描述】:

我在一个项目中使用Polymer。我有一个通用的自定义元素来封装我的整个项目,我们称之为<my-app></my-app>。我希望每当一个按钮(<paper-button><paper-item><my-custom-clickable-item>,...)播放声音。声音的播放是没有问题的,但是我不太清楚如何将函数有效地绑定到我想要的所有元素上。

我知道有一种方法可以到达 fire custom events,但如果 <my-custom-clickable-item> 会在另一个元素 <another-custom-element> 中,我需要在那里捕获它并将其传递给 <my-app>,这并不是一个很好的选择解决方案。

除了只将声音绑定到按钮之外,理想的做法是根据项目是否具有disabled 属性来播放另一种声音。

这是我的应用外观的一些示例代码。

<polymer-element name="my-app">
    <template>
        <audio id="mySound" style="display: none;">
            <source src="assets/mySound.wav" type="audio/wav">
        </audio>
        <paper-button>I make sound!</paper-button>
        <my-custom-clickable-item>I make sound as well!</my-custom-clickable-item>

        <paper-button disabled>I should make another sound though...</paper-button>

        <just-another-element></just-another-element>
    </template>
    <script>
        Polymer('my-app', {
            makeNoise: function(){
                this.$.mySound.play();
            }
        });
    </script>
</polymer-element>

<polymer-element name="just-another-element">
    <template>
        <p>I am another custom element, with other buttons!</p>
        <paper-button>Sound sound sound</paper-button>
    </template>
    <script>
        Polymer();
    </script>
</polymer-element>

【问题讨论】:

  • 如果您的 触发了一个事件,它应该冒泡到您的应用程序的根目录或 。如果您在我的应用程序上设置了一个监听器并在 中触发一个自定义事件,那么 中的监听器应该会捕获它。
  • @user2210274: 以及&lt;just-another-element&gt; 中的&lt;paper-button&gt;(或其他)怎么样?
  • 由于您想要播放不同的声音,因此您可以在使用正确的声音触发事件时附加一个自定义对象,然后在父元素中以相同的方式处理它。 var temp = { sound = 'path' }; this.fire('customEvent', temp);

标签: javascript binding polymer shadow-dom


【解决方案1】:

事件可以毫无问题地冒泡,即使在其他元素中也是如此。您可以使用fire 方法添加有关发件人项目的详细信息,例如它是否被禁用。然后在主事件句柄中,您可以根据该细节播放不同的声音。

这里有一个简单的例子:

<html>
<head>
  <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
  <title>seed-element Demo</title>
  <script src="https://www.polymer-project.org/components/webcomponentsjs/webcomponents.js"></script>
  <link rel="import" href="https://www.polymer-project.org/components/polymer/polymer.html">
  <link rel="import" href="https://www.polymer-project.org/components/core-elements/core-elements.html">
  <link rel="import" href="https://www.polymer-project.org/components/paper-elements/paper-elements.html">

</head>

<body>

  <my-app></my-app>


  <polymer-element name="my-app">
    <template>
      <style>
        paper-button[disabled] {
          pointer-events: all !important;
        }
      </style>
      <audio id="soundWhenEnabled" style="display: none;">
        <source src="assets/mySoundEnabled.wav" type="audio/wav">
      </audio>
      <audio id="soundWhenDisabled" style="display: none;">
        <source src="assets/mySoundDisabled.wav" type="audio/wav">
      </audio>
      <paper-button id="b1" raised on-click="{{onClick}}">I make sound!</paper-button>
      <my-custom-clickable-item id="b2" on-click="{{onClick}}">I make sound as well!</my-custom-clickable-item>

      <paper-button id="b3" disabled raised on-click="{{onClick}}">I should make another sound though...</paper-button>

      <just-another-element></just-another-element>
    </template>
    <script>
      Polymer('my-app', {
        eventDelegates: {
          //click: 'onClick',
          sound: 'makeNoise'
        },
        onClick: function(event, detail, sender) {
          console.log("Click "+sender.hasAttribute('disabled'))
          this.fire('sound', {id:sender.id, disabled: sender.hasAttribute('disabled')});
        },
        makeNoise: function(event, detail, sender){
          console.log(detail)
          if (detail.disabled) {
            //this.$.soundWhenDisabled.play();
            alert("I make noise disabled");
          } else {
            //this.$.soundWhenEnabled.play();
            alert("I make noise enabled");
          }
        }
      });
    </script>
  </polymer-element>

  <polymer-element name="just-another-element">
    <template>
      <p>I am another custom element, with other buttons!</p>
      <paper-button id="b4" raised on-click="{{onClick}}">Sound sound sound</paper-button>
    </template>
    <script>
      Polymer('just-another-element', {
        onClick: function(event, detail, sender) {
          console.log("Click "+sender.hasAttribute('disabled'))
          this.fire('sound', {id:sender.id, disabled: sender.hasAttribute('disabled')});
        }
      });
    </script>
  </polymer-element>

</body>
</html>

Plunker 在这里:http://plnkr.co/edit/SOwYbU3Fvlhp0MgvM60H?p=preview

希望对您有所帮助 :) 像往常一样,请不要犹豫,要求精确

【讨论】:

  • 我喜欢它,但正如我所提到的,如果我不需要手动将onClick-function 附加到每个按钮上会很容易,因为这很容易出错(例如忘记它) .是否有可能,或者制作一个仅包含 &lt;paper-button&gt; 但带有 onClick 的自定义元素是否更好?
  • 在这种情况下,我会做一个自定义的&lt;my-button&gt;,它只包含一个&lt;paper-button&gt; 元素,其eventDelegates 上的click 指向触发onClick 事件的onClick 函数.
  • 今天晚些时候我会尝试做一个例子
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
  • 2011-06-10
  • 2020-07-01
  • 2018-04-23
相关资源
最近更新 更多