【问题标题】:Trouble using dispatchEvent using Polymer and Firefox使用 Polymer 和 Firefox 使用 dispatchEvent 时遇到问题
【发布时间】:2014-12-18 13:28:08
【问题描述】:

我在使用 Polymer 的 Web 应用程序中使用 javascript 函数 dispatchEvent 时遇到了问题。我的代码在 Chrome 中运行良好,但在 Firefox(v31 和 v33)中,我收到以下错误:

TypeError: Argument 1 of EventTarget.dispatchEvent does not implement interface Event.

这是产生错误的代码:

button.dispatchEvent(new CustomEvent('chosen', {'detail': value}));

或者,我也尝试过:

var event = new Event('chosen');
event.detail = value;
button.dispatchEvent(event);

结果是一样的:这段代码在 Chrome 中运行良好,但它在到达 dispatchEvent 时停止执行并显示相同的错误消息。

我非常有信心这段代码应该在 Firefox 中运行(请参阅https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events),事实上,同样的代码在 Firefox 的非聚合物场景中运行良好。 (换句话说,如果我尝试在没有任何聚合物导入/脚本的情况下以任何一种方式创建和调度事件,它就可以正常工作。)

我的最佳猜测是 Polymer 框架(platform.js 或 polymer.js)中的某些内容会覆盖一些围绕事件的内置函数。 (我使用的是 0.3.4 版本。)

我已经尝试过广泛搜索,但我无法找到遇到完全相同问题的任何人。我确实发现有些人有相同的错误消息,但他们使用其他软件(例如 Selenium)进行报告。

Polymer 确实提供了一个“fire”方法,它是传统事件调度的包装器,所以我会考虑使用它。但是,我想我会联系 StackOverflow 社区,看看是否有人有任何想法。

提前致谢!

-----------跟进------------

感谢那些写信的人。到目前为止没有运气让它工作,但我创建了一个简单的重现来说明这个问题。这是我的 html 文件的代码。

<!DOCTYPE html>
<html>
  <head>
    <script src="http://www.polymer-project.org/components/platform/platform.js"></script>

    <link rel="import" href="http://www.polymer-project.org/components/font-roboto/roboto.html"/>
    <link rel="import" href="http://www.polymer-project.org/components/paper-button/paper-button.html"/>

    <style>
      body {
        font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
        text-align: left;
      }
    </style>
    <script type="text/javascript">
      function buttonClicked(button)
      {
        alert("Button clicked: " + button);
        alert("Firing custom event foo");
        try {
          // button.dispatchEvent(new CustomEvent('foo'));
          button.fire('foo');
          alert("Foo fired successfully.");
        } catch (err) {
          alert("Fire event failed.");
          alert(err);
        }        
      }
    </script>
  </head>
  <body>
    <paper-button onclick="buttonClicked(this);">Click</paper-button>
  </body>
</html>

不管我使用的是button.fire还是button.dispatchEvent,代码在chrome中成功,在firefox中失败。

Chrome 结果(任一代码行): 点击按钮:[object HTMLElement] try_button_event.html:18 触发自定义事件 foo try_button_event.html:19 Foo 成功发射。

Firefox 结果(button.fire): 单击的按钮:[对象 HTMLElement] 触发自定义事件 foo 火灾事件失败。 TypeError: button.fire 不是函数

Firefox 结果(button.dispatchEvent): 单击的按钮:[对象 HTMLElement] 触发自定义事件 foo 火灾事件失败。 TypeError: EventTarget.dispatchEvent 的参数 1 没有实现接口 Event。

【问题讨论】:

  • 什么是button?一个纸按钮元素?
  • 好问题。是的,按钮是 。我最初可能应该澄清这一点,但我认为这发生在所有元素上。仔细观察,我调用 dispatchEvent 的元素类型确实很重要。 elem.dispatchEvent(new Event()) 如果 elem 是一个普通的 div 或者它是我创建的自定义(聚合物)元素,则可以正常工作。所以这似乎是 (可能还有其他纸张元素)所特有的。

标签: javascript firefox polymer


【解决方案1】:

通过使用onclick,您阻止了 ShadowDOM polyfill 管理您的按钮。

您可以通过 包装 click 方法中的 button 引用来修复它,就像这样,

  function buttonClicked(button)
  {
    button = wrap(button);

但作为一般规则,您最好避免使用内联事件处理程序。这是您示例的模型:

<!DOCTYPE html>
<html>
  <head>
    <script src="http://www.polymer-project.org/components/platform/platform.js"></script>

    <link rel="import" href="http://www.polymer-project.org/components/font-roboto/roboto.html"/>
    <link rel="import" href="http://www.polymer-project.org/components/paper-button/paper-button.html"/>

    <style>
      body {
        font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
        text-align: left;
      }
    </style>
  </head>
  <body>

    <paper-button>Click</paper-button>

    <script type="text/javascript">
      document.querySelector('paper-button').addEventListener('click', buttonClicked);
      function buttonClicked()
      {
        alert("Button clicked: " + this);
        alert("Firing custom event foo");
        try {
          // button.dispatchEvent(new CustomEvent('foo'));
          this.fire('foo');
          alert("Foo fired successfully.");
        } catch (err) {
          alert("Fire event failed.");
          alert(err);
        }        
      }
    </script>
  </body>
</html>

【讨论】:

  • 谢谢!包装效果很好。我从您的回复中得知,以这种方式使用 wrap() 并不是这样做的首选方式。是否有任何附加事件处理程序的声明方式(例如,on-click 与 onclick?)。以编程方式附加事件侦听器似乎增加了不必要的复杂性。再次感谢您的帮助!
  • 浏览器供应商自己希望您使用命令式代码来附加事件侦听器 (addEventListener),on&lt;event&gt; 语法通常被认为是有害的。 Polymer 的on-&lt;event&gt; 语法有所不同,因为您没有将代码放入属性中,只放入处理程序的名称,但您必须通过使用 Polymer 模板选择加入此支持。如果您不想使用完整元素,可以使用自动绑定模板 (polymer-project.org/docs/polymer/…) 选择加入。
【解决方案2】:

您可以尝试从窗口而不是对象分派事件。 http://jsfiddle.net/95budad2/

window.dispatchEvent(new CustomEvent('chosen', {'detail': 'test'}));

【讨论】:

  • 嗯,我也许能做到。在这种特殊情况下,我自己的自定义元素(称为 )包含许多 ,并且我让按钮调度事件作为与父 对象,它监听事件。因此,由顶级文档提出它可能不起作用,但我也许可以让它由按钮的祖先提出。我会调查的。
【解决方案3】:

我建议使用button.fire(event) 为您解决眼前的问题。

从长远来看,使用最新版本的 Polymer 尝试您的代码,如果 dispatchEvent 在那里引发异常,我建议使用简单的 jsbin 复制在 paper-button github 项目上提交问题。

【讨论】:

  • 谢谢。当我尝试调用 button.fire 时,我实际上得到了一个错误,即 fire 不是函数。 (这也仅在 Firefox 中发生 - 在 chrome 中,它工作正常。)我还尝试升级到 Polymer 4.2 - 没有运气。我将尝试只用一个纸质按钮构建一个简单的复制品:如果仍然有问题,我会按照你的建议做并提交一个错误。
  • 嗯,也许你在 Firefox 中得到了不同的元素对象?或者,聚合物准备就绪还没有被解雇?如果你有时间把一个放在一起,我很想看看复制品。
  • 我编辑了原始帖子以包含复制品。
  • .fire() 已从 Polymer.Element(在 v2 中)中删除,但在 lib/legacy/legacy-element-mixin.html 中可用。
猜你喜欢
  • 2016-02-21
  • 2014-11-14
  • 2011-06-20
  • 2017-08-23
  • 2014-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多