Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

custom event in IE

399 views
Skip to first unread message

Andrew Poulos

unread,
Jan 9, 2017, 8:08:34 PM1/9/17
to
I'm working on some code that uses CustomEvent and this line

document.getElementById('g').dispatchEvent(new CustomEvent('reset'));

works as expected in Chrome, Edge, and Firefox (in Windows) but when I
test it in IE 11 I get this exception
TypeError: Object doesn't support this action.

MSDN tells me that IE does have basic support of CustomEvent but not
with a constructor. How can custom event be created for IE without using
a constructor?

Andrew Poulos

Andrew Poulos

unread,
Jan 9, 2017, 8:20:19 PM1/9/17
to
I've solved it. I was looking in MDN and not MSDN.

Andrew Poulos

Thomas 'PointedEars' Lahn

unread,
Jan 9, 2017, 8:45:49 PM1/9/17
to
Care to share?

--
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

Andrew Poulos

unread,
Jan 9, 2017, 11:32:32 PM1/9/17
to
On 10/01/2017 12:45 PM, Thomas 'PointedEars' Lahn wrote:
> Andrew Poulos wrote:
>
>> On 10/01/2017 12:08 PM, Andrew Poulos wrote:
>>> I'm working on some code that uses CustomEvent and this line
>>>
>>> document.getElementById('g').dispatchEvent(new CustomEvent('reset'));
>>>
>>> works as expected in Chrome, Edge, and Firefox (in Windows) but when I
>>> test it in IE 11 I get this exception
>>> TypeError: Object doesn't support this action.
>>>
>>> MSDN tells me that IE does have basic support of CustomEvent but not
>>> with a constructor. How can custom event be created for IE without using
>>> a constructor?
>>
>> I've solved it. I was looking in MDN and not MSDN.
>
> Care to share?

I used a try/catch and when it fails for IE the "catch" part uses
initCustomEvent
<https://msdn.microsoft.com/en-us/library/ff975987(v=vs.85).aspx>
to create the event:

function dispatch(elem, theEvent) {
try {
elem.dispatchEvent(new CustomEvent(theEvent));
} catch(err) {
var evt = document.createEvent("CustomEvent");
evt.initCustomEvent(theEvent, true, false, {});
elem.dispatchEvent(evt);
}
}

Andrew Poulos

Thomas 'PointedEars' Lahn

unread,
Jan 10, 2017, 6:53:44 AM1/10/17
to
Andrew Poulos wrote:

> I used a try/catch and when it fails for IE the "catch" part uses
> initCustomEvent
> <https://msdn.microsoft.com/en-us/library/ff975987(v=vs.85).aspx>
> to create the event:
>
> function dispatch(elem, theEvent) {
> try {
> elem.dispatchEvent(new CustomEvent(theEvent));
> } catch(err) {
> var evt = document.createEvent("CustomEvent");
> evt.initCustomEvent(theEvent, true, false, {});
> elem.dispatchEvent(evt);
> }
> }

Because not only “new CustomEvent(theEvent)” may throw an exception, you
should not simply handle all exceptions caused by this statement with the
catch code, but only the specific one. Since there is no compatible way to
catch only a specific type of exception (AFAIK only Mozilla JavaScript has a
way, see the ES Matrix), you should rethrow the exception if it is not the
one that you want to handle. For example:

try {
elem.dispatchEvent(new CustomEvent(theEvent));
} catch (err) {
if (!(err instanceof TypeError)) throw err;

var evt = document.createEvent("CustomEvent");
evt.initCustomEvent(theEvent, true, false, {});
elem.dispatchEvent(evt);
}

In JScript the “number” property of the Error instance referred by “err”
could also help to tell apart this exception from other TypeError
exceptions:

<https://msdn.microsoft.com/en-us/library/hc53e755(v=vs.94).aspx>
<https://msdn.microsoft.com/en-us/library/1dk3k160(v=vs.94).aspx>

But note that a TypeError exception for “new CustomEvent(theEvent)” is not
thrown only in IE/MSHTML, but also in all user agents that do not implement
CustomEvent which was introduced in W3C DOM 4 and the WHATWG DOM:

<https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/initCustomEvent> f.
<http://www.w3.org/TR/2015/REC-dom-20151119/#interface-customevent>


Since the first argument to the CustomEvent constructor and the
initCustomEvent() method is specified to be a DOMString designating the type
of the event, you should name your formal parameter something like
“eventType”; not “theEvent” which conveys the misconception that it would be
a reference to an event object.

James Kirk

unread,
Jan 10, 2017, 9:52:17 PM1/10/17
to
Andrew Poulos <ap_...@hotmail.com> wrote:

> On 10/01/2017 12:45 PM, Thomas 'PointedEars' Lahn wrote:

>> Andrew Poulos wrote:

>>> On 10/01/2017 12:08 PM, Andrew Poulos wrote:

[snip]

>>> I've solved it. I was looking in MDN and not MSDN.

>> Care to share?

> I used a try/catch and when it fails for IE the "catch" part uses
> initCustomEvent
> <https://msdn.microsoft.com/en-us/library/ff975987(v=vs.85).aspx>
> to create the event:

I have always tried to avoid using try/catch. So just out of my own
curiosity, why the try/catch over something liking to the function from:

[url]https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill[/url]

or testing in a similar fashion to that function.

[snip]

--
James Kirk

Thomas 'PointedEars' Lahn

unread,
Jan 10, 2017, 10:09:28 PM1/10/17
to
James Kirk wrote:

> Andrew Poulos <ap_...@hotmail.com> wrote:
>> I used a try/catch and when it fails for IE the "catch" part uses
>> initCustomEvent
>> <https://msdn.microsoft.com/en-us/library/ff975987(v=vs.85).aspx>
>> to create the event:
>
> I have always tried to avoid using try/catch. So just out of my own
> curiosity, why the try/catch over something liking to the function from:
>
> [url]https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill[/url]

If the global object has no CustomEvent property in the MSHTML DOM, then
such a polyfill would be a possibility. If on the other hand it has such a
property but the value of it just cannot be called a constructor, then the
value would be a reference to a host object, and it would be unwise to try
to overwrite the value.

> or testing in a similar fashion to that function.

You cannot determine whether a function can be called as a constructor
unless you try it.

Thomas 'PointedEars' Lahn

unread,
Jan 11, 2017, 2:25:31 AM1/11/17
to
Thomas 'PointedEars' Lahn wrote:

> Because not only “new CustomEvent(theEvent)” may throw an exception, you
> should not simply handle all exceptions caused by this statement with the
> catch code, but only the specific one. Since there is no compatible way
> to catch only a specific type of exception (AFAIK only Mozilla JavaScript
> has a way, see the ES Matrix), you should rethrow the exception if it is
> not the one that you want to handle. For example:
>
> try {
> elem.dispatchEvent(new CustomEvent(theEvent));
> } catch (err) {
> if (!(err instanceof TypeError)) throw err;
>
> var evt = document.createEvent("CustomEvent");
> evt.initCustomEvent(theEvent, true, false, {});
> elem.dispatchEvent(evt);
> }

Also, DRY:

var evt = null;

try {
evt = new CustomEvent(eventType);
} catch (err) {
if (!(err instanceof TypeError)) throw err;

evt = document.createEvent("CustomEvent");
if (evt) evt.initCustomEvent(eventType, true, false, {});
}

if (evt) {
try {
elem.dispatchEvent(evt);
} catch (e) {
console.error(e);

James Kirk

unread,
Jan 11, 2017, 9:31:50 PM1/11/17
to
Thomas 'PointedEars' Lahn <Point...@web.de> wrote:

> James Kirk wrote:

>> Andrew Poulos <ap_...@hotmail.com> wrote:

>>> I used a try/catch and when it fails for IE the "catch" part uses
>>> initCustomEvent

[snip]

>> I have always tried to avoid using try/catch. So just out of my own
>> curiosity, why the try/catch over something liking to the function

[snip]

> If the global object has no CustomEvent property in the MSHTML DOM,
> then such a polyfill would be a possibility. If on the other hand it
> has such a property but the value of it just cannot be called a
> constructor, then the value would be a reference to a host object,
> and it would be unwise to try to overwrite the value.

I would not agree with “unwise”, ill-advised perhaps, I suppose it
really depends on what definition was intended. No argument intended.

I did not intend to infer the usage of the Polyfill example verbatim.

Perhaps something similar to the following:

(function () {

var CustomEvent = function (event, params) {
console.log('petaQ');
params = params || {
bubbles: false,
cancelable: false,
detail: undefined
};
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event,
params.bubbles,
params.cancelable,
params.detail);
return evt;
}
if (typeof (window.CustomEvent) === "function") {
CustomEvent = window.CustomEvent;
}
/*

more script follows

*/

})();

>> or testing in a similar fashion to that function.

> You cannot determine whether a function can be called as a
> constructor unless you try it.

No know evidence to refute that.

In IE 11 typeof window.CustomEvent === 'object'. I am going to surmise
the same for IE 9 & 10.

[url]http://caniuse.com/#feat=customevent[/url]

Presuming that support for anything older then IE 11 is not being
handled. Is there a reason to redetermine if CustomEvent can be called
as a constructor?

As I previously stated, “curiosity, why the try/catch”, in no way do I
oppose the use of try/catch.


--
James Kirk

Thomas 'PointedEars' Lahn

unread,
Jan 12, 2017, 8:21:25 AM1/12/17
to
James Kirk wrote:

> Thomas 'PointedEars' Lahn <Point...@web.de> wrote:
>> James Kirk wrote:
>> If the global object has no CustomEvent property in the MSHTML DOM,
>> then such a polyfill would be a possibility. If on the other hand it
>> has such a property but the value of it just cannot be called a
>> constructor, then the value would be a reference to a host object,
>> and it would be unwise to try to overwrite the value.
>
> I would not agree with “unwise”, ill-advised perhaps, I suppose it
> really depends on what definition was intended. No argument intended.

It is unwise, not just ill-advised, to attempt to overwrite a property of a
host object or a property of an object that refers to a host object. With
host objects, all bets are off:

From

<http://ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,
%201st%20edition,%20June%201997.pdf#page=33>

over

<http://ecma-international.org/ecma-262/5.1/index.html#sec-8.6.2>

to

<http://www.ecma-international.org/ecma-262/7.0/#sec-object-internal-methods-and-internal-slots>

> I did not intend to infer the usage of the Polyfill example verbatim.
>
> Perhaps something similar to the following:
>
> […]

The purpose here is to avoid the deprecated API, not to enforce its use.

<https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent>

>>> or testing in a similar fashion to that function.
>> You cannot determine whether a function can be called as a
>> constructor unless you try it.
>
> No know evidence to refute that.

And that it is true is self-evident.

> In IE 11 typeof window.CustomEvent === 'object'. I am going to surmise
> the same for IE 9 & 10.

First of all, you need to consider versions of DOM implementations, not only
browser versions. Second, there is evidence that this is a jump to
conclusions. The referred object is a host object. As you can see in

<http://www.ecma-international.org/ecma-262/7.0/#sec-typeof-operator>

the “typeof” operation of a conforming implementation ECMAScript 2016 gives
no indication whether the operand implements [[Construct]].

And the current version of JScript is not claimed to be a conforming
implementation of ECMAScript 2016; it is claimed to be a conforming
implementation of ECMAScript Ed. 5:

<https://msdn.microsoft.com/en-us/library/d1et7k7c(v=vs.94).aspx>

For those implementations, too, “typeof” gives no indication whether an
object implements [[Construct]]:

<http://ecma-international.org/ecma-262/5.1/#sec-11.4.3>

And there is evidence that Microsoft’s claims about the standards compliance
of several JScript versions are false:

<http://PointedEars.de/es-matrix/#features>
<https://msdn.microsoft.com/en-us/library/s4esdbwz(v=vs.94).aspx>

So, all bets are off.

> [url]http://caniuse.com/#feat=customevent[/url]

This is a Usenet newsgroup, not a Web forum.

> Presuming that support for anything older then IE 11 is not being
> handled.

You cannot make that assumption in a Web application yet.

> Is there a reason to redetermine if CustomEvent can be called
> as a constructor?

Yes.

Thomas 'PointedEars' Lahn

unread,
Jan 12, 2017, 8:22:48 AM1/12/17
to
James Kirk wrote:

> Thomas 'PointedEars' Lahn <Point...@web.de> wrote:
>> James Kirk wrote:
>> If the global object has no CustomEvent property in the MSHTML DOM,
>> then such a polyfill would be a possibility. If on the other hand it
>> has such a property but the value of it just cannot be called a
>> constructor, then the value would be a reference to a host object,
>> and it would be unwise to try to overwrite the value.
>
> I would not agree with “unwise”, ill-advised perhaps, I suppose it
> really depends on what definition was intended. No argument intended.

It is unwise, not just ill-advised, to attempt to overwrite a property of a
host object or a property of an object that refers to a host object. With
host objects, all bets are off:

From

<http://ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,
%201st%20edition,%20June%201997.pdf#page=33>

over

<http://ecma-international.org/ecma-262/5.1/index.html#sec-8.6.2>

to

<http://www.ecma-international.org/ecma-262/7.0/#sec-object-internal-methods-and-internal-slots>

> I did not intend to infer the usage of the Polyfill example verbatim.
>
> Perhaps something similar to the following:
>
> […]

The purpose here is to avoid the deprecated API, not to enforce its use.

<https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent>

>>> or testing in a similar fashion to that function.
>> You cannot determine whether a function can be called as a
>> constructor unless you try it.
>
> No know evidence to refute that.

And that it is true is self-evident.

> In IE 11 typeof window.CustomEvent === 'object'. I am going to surmise
> the same for IE 9 & 10.

First of all, you need to consider versions of DOM implementations, not only
browser versions. Second, there is evidence that this is a jump to
conclusions. The referred object is a host object. As you can see in

<http://www.ecma-international.org/ecma-262/7.0/#sec-typeof-operator>

the “typeof” operation of a conforming implementation of ECMAScript 2016
gives no indication whether the operand implements [[Construct]].

And the current version of JScript is not claimed to be a conforming
implementation of ECMAScript 2016; it is claimed to be a conforming
implementation of ECMAScript Ed. 5:

<https://msdn.microsoft.com/en-us/library/d1et7k7c(v=vs.94).aspx>

For those implementations, too, “typeof” gives no indication whether an
object implements [[Construct]]:

<http://ecma-international.org/ecma-262/5.1/#sec-11.4.3>

And there is evidence that Microsoft’s claims about the standards compliance
of several JScript versions are false:

<http://PointedEars.de/es-matrix/#features>
<https://msdn.microsoft.com/en-us/library/s4esdbwz(v=vs.94).aspx>

So, all bets are off.

> [url]http://caniuse.com/#feat=customevent[/url]

This is a Usenet newsgroup, not a Web forum.

> Presuming that support for anything older then IE 11 is not being
> handled.

You cannot make that assumption in a Web application yet.

> Is there a reason to redetermine if CustomEvent can be called
> as a constructor?

Yes.

Scott Sauyet

unread,
Jan 14, 2017, 6:03:32 PM1/14/17
to
Thomas 'PointedEars' Lahn wrote:

> You cannot determine whether a function can be called as a constructor
> unless you try it.

What would count as positive evidence that a function can actually be
called *reasonably* as a constructor function?

Clearly, we can find evidence that it cannot be. Many function will
throw TypeErrors if one attempts to call them as constructor functions.
But the fact that a particular function doesn't do so is clearly not
sufficient to show that it can reasonably be used as a constructor
function. For example:

var fn = (function() {
var g = {};
return function() {return g;};
}());

// no errors here
var obj1 = new fn();
var obj2 = new fn();

obj1.foo = 'bar'
obj2; //=> {foo: 'bar'}

`fn` cannot reasonably be used as a constructor function.

So are there any clear criteria to make clear that a function *can* be
used as a constructor?

-- Scott

Michael Haufe (TNO)

unread,
Jan 15, 2017, 12:51:44 PM1/15/17
to
That's where code-conventions come into play.

new Point(2,4)

vs.

new point(2,4)

Thomas 'PointedEars' Lahn

unread,
Jan 15, 2017, 4:37:33 PM1/15/17
to
Yes, but:

The fallacies here are to confuse native objects with host objects, and a
straw man argument. So apparently my killfile is working fine. (To
determine whether the second fallacy includes an affirmation of a consequent
or a denial of an antecedent is left as an exercise to the reader.)

You *can* tell whether *this* *object* can be called as a constructor in the
way that is specified. There are two possibilities: either it throws an
exception or it returns an unsuitable object. There is no evidence to
suggest that any host object called as a constructor would return an
unsuitable object when that kind of call would be unsupported, and obviously
there is evidence that several host objects, including *this* one, behave as
described (i.e. not supporting to be called as a constructor with such an
argument in the MSHTML DOM). There is also a lot of evidence to suggest
that a “typeof” test would be insufficient.

So it is unwise to test with “typeof”, and wise to use a try-catch statement
with a more detailed investigation into the thrown exception here instead.

Scott Sauyet

unread,
Jan 15, 2017, 6:17:20 PM1/15/17
to
Michael Haufe (TNO) wrote:
> Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>
>>> You cannot determine whether a function can be called as a
>>> constructor unless you try it.

>> [ ... ]
>> [A]re there any clear criteria to make clear that a function *can* be
>> used as a constructor?
>
> That's where code-conventions come into play.
>
> new Point(2,4)
>
> vs.
>
> new point(2,4)

Of course. But I was responding to Thomas Lahn's straightforward
observation above. In most realistic situations, one would know the name
of the function; one would know what it's supposed to do; one might even
be able to inspect the source of the function before deciding to use it.

But if we had none of that, are there any techniques that we could use to
determine whether the object would act as a reasonable constructor
function? Clearly I'm being sloppy here; I haven't defined the term
"reasonable constructor function", and I'm still not quite sure how to do
so precisely. But I think it's relatively obvious what's meant by this.

Code conventions are important for day-to-day use.

But my question was about more fundamental language issues. Can we tell
at all? I don't see a way, but was wondering if I'm missing something
that might be useful.

-- Scott

Scott Sauyet

unread,
Jan 15, 2017, 6:41:26 PM1/15/17
to
Thomas 'PointedEars' Lahn wrote:
> Michael Haufe (TNO) wrote:
>> Scott Sauyet wrote:

>>> `fn` cannot reasonably be used as a constructor function.
>>> So are there any clear criteria to make clear that a function *can* be
>>> used as a constructor?
>>
>> That's where code-conventions come into play.
>>
>> new Point(2,4)
>>
>> vs.
>>
>> new point(2,4)

>
> Yes, but:
>
> The fallacies here are to confuse native objects with host objects, and
> a straw man argument. [ ... ]

I'm not sure where you're seeing fallacies. If it's in the original
thread, that's fine; I wasn't paying a great deal of attention, until a
single sentence in one of your posts spurred an interesting question for
me. It it's in my response -- which, I apologize, I forgot to rename --
I can't see why, as all I really did was to ask questions. If it's in
Michael Haufe's response, while it didn't really answer the question I
was asking, it certainly does not seem even slightly fallacious.


> You *can* tell whether *this* *object* can be called as a constructor in
> the way that is specified. [ ... ]

Ah, but I was inspired by your statement to ask a broader question. Do
you have any thoughts on that question?

-- Scott

Michael Haufe (TNO)

unread,
Jan 16, 2017, 1:36:31 AM1/16/17
to
Scott Sauyet wrote:

> But if we had none of that, are there any techniques that we could use to
> determine whether the object would act as a reasonable constructor
> function? Clearly I'm being sloppy here; I haven't defined the term
> "reasonable constructor function", and I'm still not quite sure how to do
> so precisely. But I think it's relatively obvious what's meant by this.
>
> Code conventions are important for day-to-day use.
>
> But my question was about more fundamental language issues. Can we tell
> at all? I don't see a way, but was wondering if I'm missing something
> that might be useful.

I *think* it *will* be possible by testing for the existence of one of the standard symbols. The current browser support seems pretty flaky so I haven't discovered any useful results:

<https://github.com/lukehoban/es6features/blob/master/README.md#subclassable-built-ins>

<http://www.ecma-international.org/ecma-262/7.0/#sec-well-known-symbols>

This may be worth raising in es-discuss

Thomas 'PointedEars' Lahn

unread,
Jan 16, 2017, 6:54:53 AM1/16/17
to
Michael Haufe (TNO) wrote:

> Scott Sauyet wrote:
>> But my question was about more fundamental language issues. Can we tell
>> at all [whether an object can be reasonably called as a constructor]? I
>> don't see a way, but was wondering if I'm missing something that might be
>> useful.
>
> I *think* it *will* be possible by testing for the existence of one of the
> standard symbols.

How?

> The current browser support seems pretty flaky so I
> haven't discovered any useful results:
>
>
<https://github.com/lukehoban/es6features/blob/master/README.md#subclassable-built-ins>

While an interesting summary, I do not see anything relevant to this problem
there.

> <http://www.ecma-international.org/ecma-262/7.0/#sec-well-known-symbols>

I see a relevant symbol to tell whether an object implements [[Construct]],
but none that could tell if it makes sense to call it as a constructor.
“Symbol.hasInstance” is not it (tested in Chromium 53¹):

| > ({})[Symbol.hasInstance]
| undefined
|
| > (function () {})[Symbol.hasInstance]
| [Symbol.hasInstance]() { [native code] }
|
| > var f = function () {};
| > delete f[Symbol.hasInstance];
| > f[Symbol.hasInstance]
| [Symbol.hasInstance]() { [native code] }

Also:

| > HTMLLIElement[Symbol.hasInstance]
| [Symbol.hasInstance]() { [native code] }

(it has to, for HTMLLIElement.prototype)

But:

| > new HTMLLIElement
| Uncaught TypeError: Illegal constructor(…)

See also

,-<http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype-@@hasinstance>
|
| Function.prototype [ @@hasInstance ] ( V )#
|
| When the @@hasInstance method of an object F is called with value V, the $
| following steps are taken:
|
| 1. Let F be the this value.
| 2. Return ? OrdinaryHasInstance(F, V).
|
| The value of the name property of this function is "[Symbol.hasInstance]".
|
| This property has the attributes { [[Writable]]: false,
| [[Enumerable]]: false, [[Configurable]]: false }.
|
| NOTE
| This is the default implementation of @@hasInstance that most functions
| inherit. @@hasInstance is called by the instanceof operator to determine
| whether a value is an instance of a specific constructor. An expression
| such as
|
| v instanceof F
|
| evaluates as
|
| F[@@hasInstance](v)
|
| A constructor function can control which objects are recognized as its
| instances by instanceof by exposing a different @@hasInstance method on
| the function.

> This may be worth raising in es-discuss

Yes.

___________
¹ navigator.userAgent === "Mozilla/5.0 (X11; Linux x86_64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143
Safari/537.36"

Michael Haufe (TNO)

unread,
Jan 16, 2017, 5:18:53 PM1/16/17
to
Thomas 'PointedEars' Lahn wrote:
> Michael Haufe (TNO) wrote:
> > This may be worth raising in es-discuss
>
> Yes.
>

FYI:

<https://mail.mozilla.org/pipermail/es-discuss/2017-January/047571.html>

Thomas 'PointedEars' Lahn

unread,
Jan 16, 2017, 6:25:04 PM1/16/17
to
thx
0 new messages