Reputation: 673
I've run into a problem using the javascript function dispatchEvent in a web app using Polymer. My code runs fine in Chrome, but in Firefox (v31 and v33), I receive the following error:
TypeError: Argument 1 of EventTarget.dispatchEvent does not implement interface Event.
Here is the code that generates the error:
button.dispatchEvent(new CustomEvent('chosen', {'detail': value}));
Alternatively, I also tried:
var event = new Event('chosen');
event.detail = value;
button.dispatchEvent(event);
The result was the same: this code worked fine in Chrome, but it halted execution with the same error message when it reached the dispatchEvent.
I am pretty confident that this code should work in Firefox (see https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events), and indeed, this same code works fine in a non-polymer scenario in Firefox. (In other words, if I try creating and dispatching events in either manner without any of the polymer imports / scripts, it works fine.)
My best guess is that something in the Polymer framework (platform.js or polymer.js) overrides some of the built-ins around events. (I am using version 0.3.4.)
I've tried searching extensively, but I haven't been able to find anyone with quite the same problem. I did find some people who had the same error message, but they were reporting it using other software (e.g., Selenium).
Polymer does supply a "fire" method that is a wrapper around the traditional event dispatching, so I will look into using that. However, I thought I would reach out to the StackOverflow community to see if anyone had any thoughts.
Thanks in advance!
-----------Follow-up------------
Thanks for those who wrote in. No luck getting it to work so far, but I have created a simple repro that illustrates the issue. Here is the code for my html file.
<!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>
Regardless of whether I use the button.fire or the button.dispatchEvent, the code succeeds in chrome and fails in firefox.
Chrome result (either codeline): Button clicked: [object HTMLElement] try_button_event.html:18 Firing custom event foo try_button_event.html:19 Foo fired successfully.
Firefox result (button.fire): Button clicked: [object HTMLElement] Firing custom event foo Fire event failed. TypeError: button.fire is not a function
Firefox result (button.dispatchEvent): Button clicked: [object HTMLElement] Firing custom event foo Fire event failed. TypeError: Argument 1 of EventTarget.dispatchEvent does not implement interface Event.
Upvotes: 0
Views: 2717
Reputation: 11027
By using onclick
you have prevented the ShadowDOM polyfill from managing your button.
You can fix it by wrapping the button
reference inside the click method like so,
function buttonClicked(button)
{
button = wrap(button);
But you are better off avoiding inline event handlers as a general rule. Here is a mod of your example:
<!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>
Upvotes: 1
Reputation: 45321
I'd recommend using button.fire(event)
to solve the immediate issue for you.
Longer term, try your code with the latest version of Polymer, and if dispatchEvent raises an exception there, I'd recommend filing an issue on the paper-button github project with a simple jsbin reproduction.
Upvotes: 0
Reputation: 29
You might try dispatching the event from the window, rather than the object. http://jsfiddle.net/95budad2/
window.dispatchEvent(new CustomEvent('chosen', {'detail': 'test'}));
Upvotes: 0