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

Script in <a > tag in IE

43 views
Skip to first unread message

Tim Slattery

unread,
Feb 7, 2013, 2:32:07 PM2/7/13
to
I have a tag that looks like this:

<a href="#" onclick="addAttachments();return false;">Add
Attachments</a>

The "addAttachments" function adds a row to a table and populates it.
It's supposed to do only that, and nothing else. That's why "return
false;" is there, to disable the normal click function for the tag

In Firefox and Chrome, this works just fine. Each time I click "Add
Attachments" another row is added to the table. But in IE, it
malfunctions.

On the first click in IE, it works fine. The second time, it acts like
Javascript has been disabled. No new row is added, and it jumps to the
top of the page (the "#" in the href, I presume). Also: there is a
button in the newly added row to delete it. If I click that and delete
the row, the next click on "Add Attachments" works fine. But anytime I
click it with a newly added row in the table, it jumps to the top of
the page.

Anybody have a clue?

--
Tim Slattery
Slatt...@bls.gov

Evertjan.

unread,
Feb 7, 2013, 2:47:27 PM2/7/13
to
Yes, you have an js-error in addAttachments();,
so return false; is not reached. If only this occurs in IE,
could be a DOM-method that fails,
or a syntax difference you did not show.

Don't use <a> for executing javascript onclick,
us a properly css-ed <div>, <span> or <button>.

<button onclick="addAttachments();">Add Attachments</button>

<a> is for hyperlinks.



--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

Thomas 'PointedEars' Lahn

unread,
Feb 7, 2013, 3:02:19 PM2/7/13
to
Tim Slattery wrote:

> I have a tag that looks like this:
>
> <a href="#" onclick="addAttachments();return false;">Add
> Attachments</a>

That is an _element_, not a tag. This “a” element (because “a” is the name
of its type) consists of tags,

<a href="#" onclick="addAttachments();return false;">

(start-tag, with attribute specifications), and

</a>

(end-tag), and (text) content:

Add Attachments

See also: <http://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2.1>

> The "addAttachments" function adds a row to a table and populates it.
> It's supposed to do only that, and nothing else. That's why "return
> false;" is there, to disable the normal click function for the tag
>
> In Firefox and Chrome, this works just fine. Each time I click "Add
> Attachments" another row is added to the table. But in IE, it
> malfunctions.
>
> On the first click in IE, it works fine. The second time, it acts like
> Javascript has been disabled. No new row is added, and it jumps to the
> top of the page (the "#" in the href, I presume). Also: there is a
> button in the newly added row to delete it. If I click that and delete
> the row, the next click on "Add Attachments" works fine. But anytime I
> click it with a newly added row in the table, it jumps to the top of
> the page.
>
> Anybody have a clue?

The addAttachments() function has caused a runtime error in IE/MSHTML,
therefore afterwards no further script code in that document is being
executed. There should be a yellow icon on the left-hand side of the status
bar which you can double-click and see (to some extent) what the problem is
and where it is located (while the line number is close to the erroneous
one, the filename may be wrong).

If you have IE 7 or IE ≥ 8, you can use the IE Developer Tools to find out
more; for IE 7 there is an add-on, for IE ≥ 8 you can press F12. There is
also Firebug Lite which, after loaded (e.g. via bookmarklet), responds to
the same keyboard shortcut.

However, you should not be using that approach because it does not work
without client-side script support; use a script-augmented HTML form
instead.

If at all necessary, at least generate the “a” element dynamically so that
users where it cannot work do not have to bother with the non-working
element in the first place.

--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Tim Slattery

unread,
Feb 7, 2013, 3:08:53 PM2/7/13
to
"Evertjan." <exxjxw.h...@inter.nl.net> wrote:


>Yes, you have an js-error in addAttachments();,
>so return false; is not reached. If only this occurs in IE,
>could be a DOM-method that fails,
>or a syntax difference you did not show.

You got it. I'm using the firstElementChild property of a "td" object.
But I'm running IE8 and firstElementChild doesn't exist in IE until
version 9. I'm trying to get the <input > element in that cell.

Ahh..looks like firstChild works just as well as firstElementChild in
this case.

--
Tim Slattery
Slatt...@bls.gov

Thomas 'PointedEars' Lahn

unread,
Feb 7, 2013, 3:20:38 PM2/7/13
to
Tim Slattery wrote:

> "Evertjan." <exxjxw.h...@inter.nl.net> wrote:
>> Yes, you have an js-error in addAttachments();,
>> so return false; is not reached. If only this occurs in IE,
>> could be a DOM-method that fails,
>> or a syntax difference you did not show.
>
> You got it. I'm using the firstElementChild property of a "td" object.
> But I'm running IE8 and firstElementChild doesn't exist in IE until
> version 9.

To be precise, it is not supported by the MSHTML DOM until before version 9.

> I'm trying to get the <input > element in that cell.

You should use names or IDs, the former being backwards-compatible, instead.

> Ahh..looks like firstChild works just as well as firstElementChild in
> this case.

Add whitespace before the input element or change its position and it will
not work anymore. Can you afford such glitches in your software? Think
again.
Message has been deleted

Denis McMahon

unread,
Feb 8, 2013, 2:08:33 AM2/8/13
to
On Thu, 07 Feb 2013 21:30:51 +0000, Tim Streater wrote:

> In article <XnsA160D37E...@194.109.133.133>,
> Does this need to be:
>
> <button type='button' onclick=...

It depends .... If the button is inside a form element and Tim doesn't
want the button to also submit the form, he may need stop it doing so -
but his onclick returns false already.

As Evertjan said, a css styled div or span is also a possibility, as it
provides an onclick action without needing to worry about other related
functions (like form submitting, or jumping to bookmarks etc). It's not
difficult with CSS to style spans to appear to be buttons or links.

--
Denis McMahon, denismf...@gmail.com

Christoph Becker

unread,
Feb 8, 2013, 10:30:01 AM2/8/13
to
Denis McMahon wrote:

> It depends .... If the button is inside a form element and Tim doesn't
> want the button to also submit the form, he may need stop it doing so -
> but his onclick returns false already.

In this case one can set the `type' attribute of the `button' element to
`button':

<button type="button" ...>...</button>

See <http://www.w3.org/TR/REC-html40/interact/forms.html#adef-type-BUTTON>

--
Christoph M. Becker
Message has been deleted

Eric Bednarz

unread,
Feb 8, 2013, 6:19:45 PM2/8/13
to
Thomas 'PointedEars' Lahn <Point...@web.de> writes:

> Tim Slattery wrote:

> <a href="#" onclick="addAttachments();return false;">

> If at all necessary, at least generate the “a” element dynamically so that
> users where it cannot work do not have to bother with the non-working
> element in the first place.

But that would rather reliably enable user interaction without a
pointing device, and without jumping through hoops in terms of
implementation. How would that be better than just plonking some SPAN or
DIV element in the HTML source and unconditionally style it as an
interactive element, just in case, as has been suggested earlier in
this threat?

(In military markup, we call that strategy 'the element of suprise'.)

Eric Bednarz

unread,
Feb 8, 2013, 6:25:42 PM2/8/13
to
Eric Bednarz <bed...@fahr-zur-hoelle.org> writes:

> Thomas 'PointedEars' Lahn <Point...@web.de> writes:
>
>> Tim Slattery wrote:
>
>> <a href="#" onclick="addAttachments();return false;">

As the attribution and content flow still suggest, Tim wrote that, not
Thomas. I must have messed up the quotation level manually, and feel
rather inconsolable about it.

Thomas 'PointedEars' Lahn

unread,
Feb 9, 2013, 8:35:12 AM2/9/13
to
Eric Bednarz wrote:

[Quotation fixed]

> Thomas 'PointedEars' Lahn <Point...@web.de> writes:
>> Tim Slattery wrote:
>>> <a href="#" onclick="addAttachments();return false;">
>>
>> If at all necessary, at least generate the “a” element dynamically so
>> that users where it cannot work do not have to bother with the
>> non-working element in the first place.
>
> But that would rather reliably enable user interaction without a
> pointing device,

What good is a clickable element if nothing happens – or worse, something
unexpected and unwanted happens, like scrolling to the top of the document –
when it is clicked?

> and without jumping through hoops in terms of implementation.

IBTD.

<script type="text/javascript">
document.write(
'<a href="#" onclick="addAttachments();return false;">…<\/a>');
</script>

or

<script type="text/javascript">
(function () {
var a = document.createElement("a");
a.href = "#";
a.onclick = function () {
addAttachments();
return false;
};

var scripts = document.getElementsByTagName("script");
var lastScript = scripts[scripts.length - 1];
lastScript.parentNode.insertBefore(a, lastScript.nextSibling);
}());
</script>

or something along those lines (the simplest way without document.write()
would be to use an element node with an ID as reference node; implementation
of that is left as an exercise to the reader).

> How would that be better than just plonking some SPAN or
> DIV element in the HTML source and unconditionally style it as an
> interactive element, just in case, as has been suggested earlier in
> this threat?

An element that is not there in the first place when it could not do
anything useful cannot be activated in order to do nothing useful. An
element that is merely styled can still be activated even when it cannot
do anything useful; the implementation of CSS is optional on top of that.

Good user interface design aims to reduce the probability of user errors.

SAM

unread,
Feb 9, 2013, 10:42:44 AM2/9/13
to
Le 07/02/13 21:08, Tim Slattery a �crit :
>
> You got it. I'm using the firstElementChild property of a "td" object.
> But I'm running IE8 and firstElementChild doesn't exist in IE until
> version 9. I'm trying to get the <input > element in that cell.

theInput = thatTD.getElementsByTagName('INPUT')[0];



--
St�phane Moriaux avec/with iMac-intel

Cezary Tomczyk

unread,
Feb 9, 2013, 2:33:21 PM2/9/13
to
W dniu 2013-02-07 20:32, Tim Slattery pisze:
> I have a tag that looks like this:
>
> <a href="#" onclick="addAttachments();return false;">Add
> Attachments</a>
[...]

My "5 cents":

1. Don't mix behaviours with logic. Move "onclick" outside of element
<a>. A good example was provided by Thomas Lahn (he's second example).

2. Do not use href="#" which means that users without JavaScript (there
are several situations where JavaScript is not available) can not get
into data which are behind "#". Rather use normal URL that provide a
simple form where user can send file. This is fall-back.

--
Cezary Tomczyk
http://www.ctomczyk.pl/

Eric Bednarz

unread,
Feb 9, 2013, 4:27:16 PM2/9/13
to
Thomas 'PointedEars' Lahn <Point...@web.de> writes:

> Eric Bednarz wrote:
>
> [Quotation fixed]
>
>> Thomas 'PointedEars' Lahn <Point...@web.de> writes:
>>> Tim Slattery wrote:
>>>> <a href="#" onclick="addAttachments();return false;">
>>>
>>> If at all necessary, at least generate the “a” element dynamically so
>>> that users where it cannot work do not have to bother with the
>>> non-working element in the first place.
>>
>> But that would rather reliably enable user interaction without a
>> pointing device,
>
> What good is a clickable element if nothing happens – or worse, something
> unexpected and unwanted happens, like scrolling to the top of the document –
> when it is clicked?

What good is my sarcasm? No good at all, apparently. Sorry about
that. Constructive answer, though.

Thomas 'PointedEars' Lahn

unread,
Feb 9, 2013, 6:08:47 PM2/9/13
to
Cezary Tomczyk wrote:

> W dniu 2013-02-07 20:32, Tim Slattery pisze:
>> I have a tag that looks like this:
>>
>> <a href="#" onclick="addAttachments();return false;">Add
>> Attachments</a>
> [...]
>
> My "5 cents":
>
> 1. Don't mix behaviours with logic. Move "onclick" outside of element
> <a>.

You have not said why. I think there is no good reason why. That script
code here is short enough so that it is maintainable when in an event
handler attribute value, and it is only needed when that particular “a”
element is needed. Loading it always would be a waste of resources.

> A good example was provided by Thomas Lahn (he's second example).

Which “second example” are you referring to?

> 2. Do not use href="#" which means that users without JavaScript (there
> are several situations where JavaScript is not available) can not get
> into data which are behind "#". Rather use normal URL that provide a
> simple form where user can send file. This is fall-back.

Usually good advice (probably in the FAQ). In this case, however, it might
be better to use form controls instead. One cannot be certain as not all
the code was posted.

Cezary Tomczyk

unread,
Feb 9, 2013, 6:52:16 PM2/9/13
to
W dniu 2013-02-10 00:08, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
>
>> W dniu 2013-02-07 20:32, Tim Slattery pisze:
>>> I have a tag that looks like this:
>>>
>>> <a href="#" onclick="addAttachments();return false;">Add
>>> Attachments</a>
>> [...]
>>
>> My "5 cents":
>>
>> 1. Don't mix behaviours with logic. Move "onclick" outside of element
>> <a>.
>
> You have not said why. I think there is no good reason why. That script
> code here is short enough so that it is maintainable when in an event
> handler attribute value, and it is only needed when that particular “a”
> element is needed. Loading it always would be a waste of resources.

I am referring to:

*
http://en.wikipedia.org/wiki/Unobtrusive_JavaScript#Separation_of_behavior_from_markup
*
http://www.w3.org/wiki/The_principles_of_unobtrusive_JavaScript#Separation_of_structure_and_behaviour

There is a lot of materials in internet about (let's use some keywords)
"separate behavior content javascript".

Plus ( from my memory :-) ):

* HTML files are bigger by using inline events and are not cached, while
JavaScript files can be cached by browsers

>> A good example was provided by Thomas Lahn (he's second example).
>
> Which “second example” are you referring to?

[...]
a.onclick = function () {
addAttachments();
return false;
};
[...]

which means that attaching method to event could be done, for example,
in that way. Not by using inline events.

>> 2. Do not use href="#" which means that users without JavaScript (there
>> are several situations where JavaScript is not available) can not get
>> into data which are behind "#". Rather use normal URL that provide a
>> simple form where user can send file. This is fall-back.
>
> Usually good advice (probably in the FAQ). In this case, however, it might
> be better to use form controls instead. One cannot be certain as not all
> the code was posted.

Yes. Small form could be very usefully and if HTML5 features are
available (like multiple upload) then developer can even add progress
bar, show file size, etc.

Thomas 'PointedEars' Lahn

unread,
Feb 9, 2013, 7:07:23 PM2/9/13
to
Utter nonsense, all of the above.

>>> A good example was provided by Thomas Lahn (he's second example).
>> Which “second example” are you referring to?
>
> [...]
> a.onclick = function () {
> addAttachments();
> return false;
> };
> [...]
>
> which means that attaching method to event could be done, for example,
> in that way. Not by using inline events.

This code is part of an example in which the “a” element is created
dynamically. It has nothing to do with some misguided idea of “Unobtrusive
JavaScript”.

Cezary Tomczyk

unread,
Feb 9, 2013, 7:20:03 PM2/9/13
to
W dniu 2013-02-10 01:07, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
[...]
The code contains an fragment of adding event and method. That part I
wanted to cite as an example of way how to add events and methods in a
proper way. Not by inline events. Also, I provided links that contains
explanations "why not inline events". You do not have to agree with them.

Thomas 'PointedEars' Lahn

unread,
Feb 9, 2013, 7:27:28 PM2/9/13
to
Cezary Tomczyk wrote:

> W dniu 2013-02-10 01:07, Thomas 'PointedEars' Lahn pisze:
>> Cezary Tomczyk wrote:
> [...]
>>>>> 1. Don't mix behaviours with logic. Move "onclick" outside of element
>>>>> <a>.
>>>>
>>>> You have not said why. I think there is no good reason why. That
>>>> script code here is short enough so that it is maintainable when in an
>>>> event handler attribute value, and it is only needed when that
>>>> particular “a”
>>>> element is needed. Loading it always would be a waste of resources.
>>>
>>> I am referring to:
>>>
>>> *
http://en.wikipedia.org/wiki/Unobtrusive_JavaScript#Separation_of_behavior_from_markup
>>> *
http://www.w3.org/wiki/The_principles_of_unobtrusive_JavaScript#Separation_of_structure_and_behaviour
>>>
>>> There is a lot of materials in internet about (let's use some keywords)
>>> "separate behavior content javascript".
>>>
>>> Plus ( from my memory :-) ):
>>>
>>> * HTML files are bigger by using inline events and are not cached, while
>>> JavaScript files can be cached by browsers
>>
>> Utter nonsense, all of the above.
>
> You have not said why.

True, because we have been over this ad nauseam here already.

>>>>> A good example was provided by Thomas Lahn (he's second example).
>>>> Which “second example” are you referring to?
>>>
>>> [...]
>>> a.onclick = function () {
>>> addAttachments();
>>> return false;
>>> };
>>> [...]
>>>
>>> which means that attaching method to event could be done, for example,
>>> in that way. Not by using inline events.
>> This code is part of an example in which the “a” element is created
>> dynamically. It has nothing to do with some misguided idea of
>> “Unobtrusive JavaScript”.
>
> The code contains an fragment of adding event and method. That part I
> wanted to cite as an example of way how to add events and methods in a
> proper way. Not by inline events.

My example has nothing to do with that mindbogglingly stupid approach.
Do not cite it as an example of that.

> Also, I provided links that contains explanations "why not inline events".
> You do not have to agree with them.

I do not, because they are utter nonsense.

Cezary Tomczyk

unread,
Feb 9, 2013, 7:43:23 PM2/9/13
to
W dniu 2013-02-10 01:27, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
>
>> W dniu 2013-02-10 01:07, Thomas 'PointedEars' Lahn pisze:
>>> Cezary Tomczyk wrote:
>> [...]
>>>>>> 1. Don't mix behaviours with logic. Move "onclick" outside of element
>>>>>> <a>.
>>>>>
>>>>> You have not said why. I think there is no good reason why. That
>>>>> script code here is short enough so that it is maintainable when in an
>>>>> event handler attribute value, and it is only needed when that
>>>>> particular “a”
>>>>> element is needed. Loading it always would be a waste of resources.
>>>>
>>>> I am referring to:
>>>>
>>>> *
> http://en.wikipedia.org/wiki/Unobtrusive_JavaScript#Separation_of_behavior_from_markup
>>>> *
> http://www.w3.org/wiki/The_principles_of_unobtrusive_JavaScript#Separation_of_structure_and_behaviour
>>>>
>>>> There is a lot of materials in internet about (let's use some keywords)
>>>> "separate behavior content javascript".
>>>>
>>>> Plus ( from my memory :-) ):
>>>>
>>>> * HTML files are bigger by using inline events and are not cached, while
>>>> JavaScript files can be cached by browsers
>>>
>>> Utter nonsense, all of the above.
>>
>> You have not said why.
>
> True, because we have been over this ad nauseam here already.

Hm, it would maybe good to collect all results of previous discussions
somewhere in FAQ place, you know. I know that writing the same things
over and over again is a maybe little bit waste of time.

But on the other hand answer like "Utter nonsense, all of the above."
doesn't contains useful informations. Just make more confuses.

>>>>>> A good example was provided by Thomas Lahn (he's second example).
>>>>> Which “second example” are you referring to?
>>>>
>>>> [...]
>>>> a.onclick = function () {
>>>> addAttachments();
>>>> return false;
>>>> };
>>>> [...]
>>>>
>>>> which means that attaching method to event could be done, for example,
>>>> in that way. Not by using inline events.
>>> This code is part of an example in which the “a” element is created
>>> dynamically. It has nothing to do with some misguided idea of
>>> “Unobtrusive JavaScript”.
>>
>> The code contains an fragment of adding event and method. That part I
>> wanted to cite as an example of way how to add events and methods in a
>> proper way. Not by inline events.
>
> My example has nothing to do with that mindbogglingly stupid approach.
> Do not cite it as an example of that.

As you wish.

Could be written like this:

var doAction = function () {
addAttachments();
return false;
};

var m = function () {
var a = document.getElementById('mylinkelement');
a.onclick = doAction;
};

m();

But let's leave it as is and close this case.

>> Also, I provided links that contains explanations "why not inline events".
>> You do not have to agree with them.
>
> I do not, because they are utter nonsense.

Without any evidences I can not say that you have right. Anyway, let's
leave it as is.

Thomas 'PointedEars' Lahn

unread,
Feb 10, 2013, 7:55:45 AM2/10/13
to
Yes. Thank you for your volunteering.

> But on the other hand answer like "Utter nonsense, all of the above."
> doesn't contains useful informations. Just make more confuses.

You can find indication that it is utter nonsense when you evaluate the
truth value of the statement “HTML files […] by using inline events […] are
not cached”. The fact aside that there are no “inline events” (there are
event-handler attributes on elements, many of them defined in HTML
Specifications HTML 4.01 [REC] and HTML5 [CR]): *Why* would such a document
_not_ be cached by an HTTP client?

> Could be written like this:
>
> var doAction = function () {
> addAttachments();
> return false;
> };
>
> var m = function () {
> var a = document.getElementById('mylinkelement');
> a.onclick = doAction;
> };
>
> m();

Could be, but should not.

> But let's leave it as is and close this case.

This is not a matter of opinion. There are good reasons why this is harder
to maintain bloat code – directly contradicting your thesis that the
separation would make a smaller footprint and would make things easier –,
and there are few if any reasons why it is not. You can see that when you
count the number of characters required for implementing either approach.
You can see it again when you calculate the code distance in either case.
You can see it yet again when you consider the compatibility of either
approach.

Your approach can be useful – if augmented – if the same functionality is
needed in several places and the event does not bubble. Which is not the
case here.

>>> Also, I provided links that contains explanations "why not inline
>>> events". You do not have to agree with them.
>> I do not, because they are utter nonsense.
>
> Without any evidences I can not say that you have right. Anyway, let's
> leave it as is.

No, truth must be told, and you have not thought this through.

Cezary Tomczyk

unread,
Feb 10, 2013, 2:38:41 PM2/10/13
to
W dniu 2013-02-10 13:55, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
>
>> W dniu 2013-02-10 01:27, Thomas 'PointedEars' Lahn pisze:
>>> Cezary Tomczyk wrote:
[...]
>>>> You have not said why.
>>> True, because we have been over this ad nauseam here already.
>>
>> Hm, it would maybe good to collect all results of previous discussions
>> somewhere in FAQ place, you know. I know that writing the same things
>> over and over again is a maybe little bit waste of time.
>
> Yes. Thank you for your volunteering.

:-) I have created a site based on MediaWiki:

http://faq.jscode.info/index.php/Main_Page

If this can helps then site could be improved by adding new contributors
and content. Otherwise just say: "Not this time" :-)

>> But on the other hand answer like "Utter nonsense, all of the above."
>> doesn't contains useful informations. Just make more confuses.
>
> You can find indication that it is utter nonsense when you evaluate the
> truth value of the statement “HTML files […] by using inline events […] are
> not cached”. The fact aside that there are no “inline events” (there are
> event-handler attributes on elements, many of them defined in HTML
> Specifications HTML 4.01 [REC] and HTML5 [CR]): *Why* would such a document
> _not_ be cached by an HTTP client?

Sorry, I went to far. HTML files may of course be cached. I probably had
some delusions. :-)

>> Could be written like this:
>>
>> var doAction = function () {
>> addAttachments();
>> return false;
>> };
>>
>> var m = function () {
>> var a = document.getElementById('mylinkelement');
>> a.onclick = doAction;
>> };
>>
>> m();
>
> Could be, but should not.

More or less I agree.

>> But let's leave it as is and close this case.
>
> This is not a matter of opinion. There are good reasons why this is harder
> to maintain bloat code – directly contradicting your thesis that the
> separation would make a smaller footprint and would make things easier –,
> and there are few if any reasons why it is not. You can see that when you
> count the number of characters required for implementing either approach.
> You can see it again when you calculate the code distance in either case.
> You can see it yet again when you consider the compatibility of either
> approach.

Well, I never use event-handler attributes on elements. Just separate
behaviours and logic. For me is just easier for maintenance.

Another thing is when user has no JavaScript* (for whatever reason) then
HTML code is just slightly bigger to download. Not maybe big difference,
but it is. Because contains event-handler attributes which will not be
used when JavaScript is not available.

I wouldn't worry so much about some few kilobytes more in JavaScript
files. There is more important in my opinion problems like: too much
requests to server (files are not combined into one file, a lot of
requests for some data, etc.), not efficient code, files not cached, etc.

> Your approach can be useful – if augmented – if the same functionality is
> needed in several places and the event does not bubble. Which is not the
> case here.

Hm, this topic should be also in FAQ: "When and when not to use
event-handler attributes?".

>>>> Also, I provided links that contains explanations "why not inline
>>>> events". You do not have to agree with them.
>>> I do not, because they are utter nonsense.
>>
>> Without any evidences I can not say that you have right. Anyway, let's
>> leave it as is.
>
> No, truth must be told, and you have not thought this through.

Unfortunately, I like evidences instead of trusting :-) Descriptions
(articles or something similar) that are convincing or examples that works.

* There is no "JavaScript", I know.

Thomas 'PointedEars' Lahn

unread,
Feb 10, 2013, 3:28:51 PM2/10/13
to
Cezary Tomczyk wrote:

> W dniu 2013-02-10 13:55, Thomas 'PointedEars' Lahn pisze:
>> Cezary Tomczyk wrote:
>>> W dniu 2013-02-10 01:27, Thomas 'PointedEars' Lahn pisze:
>>>> Cezary Tomczyk wrote:
> [...]
>>>>> You have not said why.
>>>> True, because we have been over this ad nauseam here already.
>>> Hm, it would maybe good to collect all results of previous discussions
>>> somewhere in FAQ place, you know. I know that writing the same things
>>> over and over again is a maybe little bit waste of time.
>> Yes. Thank you for your volunteering.
>
> :-) I have created a site based on MediaWiki:
>
> http://faq.jscode.info/index.php/Main_Page
>
> If this can helps then site could be improved by adding new contributors
> and content. Otherwise just say: "Not this time" :-)

Thanks but no, thanks. We have already discussed the problems of a Wiki
approach; the arguments as to that, and my reasons against that, have not
changed. Conclusions reached from discussion which can be mutually agreed
on should become FAQ Notes, editable only by very few people who can be
trusted that they would not use their influence to propagate their personal
opinions, in order to ensure integrity.

Besides, there are many misconceptions waiting to be promoted from reading
the text that is already there because it is poorly worded and contains
factual errors.

>>> Could be written like this:
>>>
>>> var doAction = function () {
>>> addAttachments();
>>> return false;
>>> };
>>>
>>> var m = function () {
>>> var a = document.getElementById('mylinkelement');
>>> a.onclick = doAction;
>>> };
>>>
>>> m();
>>
>> […]
>> This is not a matter of opinion. There are good reasons why this is
>> harder to maintain bloat code – directly contradicting your thesis that
>> the separation would make a smaller footprint and would make things
>> easier –, and there are few if any reasons why it is not. You can see
>> that when you count the number of characters required for implementing
>> either approach. You can see it again when you calculate the code
>> distance in either case. You can see it yet again when you consider the
>> compatibility of either approach.
>
> Well, I never use event-handler attributes on elements.

So much the pity. I use event-handler attributes whenever there is no
better alternative, for the already named reasons at least.

> Just separate behaviours and logic.

You are under the delusion that “behavior” and “(business) logic” are
separate things. Business logic *is* the behavior of the application; what
it does when it receives certain input. Perhaps you meant to say “separate
presentation and layout” (which can be a reasonable approach, but _not_ /per
se/); still your confusing that already shows how little you actually
*understand* of what you are talking about.

> For me is just easier for maintenance.

Each time you edit you will have to switch between the script code and the
markup, even for tasks that require no more than a one-liner with an event-
handler attribute, and – proven already – considerably more (if done
properly) with that so-called “unobtrusive JavaScript” approach. How can
*greater* code distance and *unnecessarily* *complicated*, *larger* code
ease maintenance?

> Another thing is when user has no JavaScript* (for whatever reason) then
> HTML code is just slightly bigger to download. Not maybe big difference,
> but it is. Because contains event-handler attributes which will not be
> used when JavaScript is not available.

Your logic is flawed. In general, you need *more* source code if you do not
use event-handler attributes at all, to make it work reliably. The user
needs to download that *larger* code base the *same* as with event-handler
attributes, *no matter* whether client-side scripting is supported.
Browsers do not skip downloading script code when client-side script support
is disabled, because it could be re-enabled afterwards.

> I wouldn't worry so much about some few kilobytes more in JavaScript
> files. There is more important in my opinion problems like: too much
> requests to server (files are not combined into one file, a lot of
> requests for some data, etc.), not efficient code, files not cached, etc.

Files (better: resources) are cacheable in both cases. And you are
*increasing* the number of requests if you move code to external resources,
even when not necessary. Again I ask you: Where is the logic in that?

>>>>> Also, I provided links that contains explanations "why not inline
>>>>> events". You do not have to agree with them.
>>>> I do not, because they are utter nonsense.
>>> Without any evidences I can not say that you have right. Anyway, let's
>>> leave it as is.
>> No, truth must be told, and you have not thought this through.
>
> Unfortunately, I like evidences instead of trusting :-)

You should not and you do not have to take this on trust; neither should you
take the statements of anyone else, including Douglas Crockford, on trust or
even faith. Look for *well-founded*, *provable* and *proven* arguments, not
authority. Keep in mind: An argument from authority is a fallacy, because
the *assumed* authority can be wrong. This is probably the best advice that
can be given in this field where, due to a stream of beginners that think
they are experts even after a considerably short exposure and experience,
superficially logical sounding utter nonsense is commonplace.

I have pointed out to you again the evidence that shows why your assumptions
are wrong, even though they should be obvious to a reasonable person. All
you need to do now is accept them so that you can evaluate them.

Thomas 'PointedEars' Lahn

unread,
Feb 10, 2013, 3:37:07 PM2/10/13
to
Thomas 'PointedEars' Lahn wrote:

> Cezary Tomczyk wrote:
>> Just separate behaviours and logic.
>
> You are under the delusion that “behavior” and “(business) logic” are
> separate things. Business logic *is* the behavior of the application;
> what it does when it receives certain input. Perhaps you meant to say
> “separate presentation and layout” (which can be a reasonable approach,

That should have been “markup”, not “layout”; as in “avoid inline styles
(when not necessary)”.

--
PointedEars

Cezary Tomczyk

unread,
Feb 10, 2013, 4:56:41 PM2/10/13
to
W dniu 2013-02-10 21:28, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
[...]
>> :-) I have created a site based on MediaWiki:
>>
>> http://faq.jscode.info/index.php/Main_Page
>>
>> If this can helps then site could be improved by adding new contributors
>> and content. Otherwise just say: "Not this time" :-)
>
> Thanks but no, thanks. We have already discussed the problems of a Wiki
> approach; the arguments as to that, and my reasons against that, have not
> changed. Conclusions reached from discussion which can be mutually agreed
> on should become FAQ Notes, editable only by very few people who can be
> trusted that they would not use their influence to propagate their personal
> opinions, in order to ensure integrity.
>
> Besides, there are many misconceptions waiting to be promoted from reading
> the text that is already there because it is poorly worded and contains
> factual errors.

Ok.

[...]
>> Well, I never use event-handler attributes on elements.
>
> So much the pity. I use event-handler attributes whenever there is no
> better alternative, for the already named reasons at least.
>
>> Just separate behaviours and logic.
>
> You are under the delusion that “behavior” and “(business) logic” are
> separate things. Business logic *is* the behavior of the application; what
> it does when it receives certain input. Perhaps you meant to say “separate
> presentation and layout” (which can be a reasonable approach, but _not_ /per
> se/); still your confusing that already shows how little you actually
> *understand* of what you are talking about.

Well, I think about exactly what was described in links which I
specified in one of the previous post.

>> For me is just easier for maintenance.
>
> Each time you edit you will have to switch between the script code and the
> markup, even for tasks that require no more than a one-liner with an event-
> handler attribute, and – proven already – considerably more (if done
> properly) with that so-called “unobtrusive JavaScript” approach. How can
> *greater* code distance and *unnecessarily* *complicated*, *larger* code
> ease maintenance?

Even, if changes is about "one-liner with an event-handler attribute"
then I prefer always to make a script code in a separate file. I do not
want to mix html markup with any script code. It will keep my html
document clean.

>> Another thing is when user has no JavaScript* (for whatever reason) then
>> HTML code is just slightly bigger to download. Not maybe big difference,
>> but it is. Because contains event-handler attributes which will not be
>> used when JavaScript is not available.
>
> Your logic is flawed. In general, you need *more* source code if you do not
> use event-handler attributes at all, to make it work reliably. The user
> needs to download that *larger* code base the *same* as with event-handler
> attributes, *no matter* whether client-side scripting is supported.

I use reusable patterns which means that I do not need every time to
create separate code for every behaviour. Even, if this will take a few
lines more it doesn't matter.

Arguments, with which I agree:

http://stackoverflow.com/a/11742769/896702

> Browsers do not skip downloading script code when client-side script support
> is disabled, because it could be re-enabled afterwards.

I created the test page
http://www.ctomczyk.pl/lab/script_loading/test.html and for example
Firefox 18.0.2 do not downloading script when scripts are disabled in
browsers.

>> I wouldn't worry so much about some few kilobytes more in JavaScript
>> files. There is more important in my opinion problems like: too much
>> requests to server (files are not combined into one file, a lot of
>> requests for some data, etc.), not efficient code, files not cached, etc.
>
> Files (better: resources) are cacheable in both cases. And you are
> *increasing* the number of requests if you move code to external resources,
> even when not necessary. Again I ask you: Where is the logic in that?

I am not increasing the number of requests if I move code to external
resources. This only happens while developing. Later all script code are
combined into one file during build process.

>>>>>> Also, I provided links that contains explanations "why not inline
>>>>>> events". You do not have to agree with them.
>>>>> I do not, because they are utter nonsense.
>>>> Without any evidences I can not say that you have right. Anyway, let's
>>>> leave it as is.
>>> No, truth must be told, and you have not thought this through.
>>
>> Unfortunately, I like evidences instead of trusting :-)
>
> You should not and you do not have to take this on trust; neither should you
> take the statements of anyone else, including Douglas Crockford, on trust or
> even faith. Look for *well-founded*, *provable* and *proven* arguments, not
> authority. Keep in mind: An argument from authority is a fallacy, because
> the *assumed* authority can be wrong. This is probably the best advice that
> can be given in this field where, due to a stream of beginners that think
> they are experts even after a considerably short exposure and experience,
> superficially logical sounding utter nonsense is commonplace.

That conclusion sounds good for me.

> I have pointed out to you again the evidence that shows why your assumptions
> are wrong, even though they should be obvious to a reasonable person. All
> you need to do now is accept them so that you can evaluate them.

Sometimes I may disagree with some of arguments. Discuss is the best
option to change the mind.

Eric Bednarz

unread,
Feb 10, 2013, 6:09:30 PM2/10/13
to
Cezary Tomczyk <cezary....@gmail.com> writes:

[event attributes versus DOM*]

> Arguments, with which I agree:
>
> http://stackoverflow.com/a/11742769/896702

| if an event is specified inline, the JS is specified as a string
| (attribute values are always strings) and evaluated when the event
| fires. Evaluation is evil.

Newsflash: event attribute value literals are *not* eval'ed. This BS
theory just seems to keep coming back like a bad song whenever
arguments, common sense and experience are exhausted.

| you are faced with having to reference named functions. This is not
| always ideal (event handlers normally take anonymous functions)

The what? 'Normally', 'event handlers' are objects that implement the
EventListener interface. The fantasy nomenclature for function
declarations and expressions aside, function objects created by event
handlers don't have an identifier, so they should be alright (eyeroll).

Eric Bednarz

unread,
Feb 10, 2013, 6:30:57 PM2/10/13
to
Eric Bednarz <bed...@fahr-zur-hoelle.org> writes:

> [...] function objects created by event handlers

*attributes*

Cezary Tomczyk

unread,
Feb 10, 2013, 6:43:26 PM2/10/13
to
W dniu 2013-02-11 00:09, Eric Bednarz pisze:
> Cezary Tomczyk <cezary....@gmail.com> writes:
>
> [event attributes versus DOM*]
>
>> Arguments, with which I agree:
>>
>> http://stackoverflow.com/a/11742769/896702
>
> | if an event is specified inline, the JS is specified as a string
> | (attribute values are always strings) and evaluated when the event
> | fires. Evaluation is evil.
>
> Newsflash: event attribute value literals are *not* eval'ed. This BS
> theory just seems to keep coming back like a bad song whenever
> arguments, common sense and experience are exhausted.

I thought that the code is eval'ed :/

> | you are faced with having to reference named functions. This is not
> | always ideal (event handlers normally take anonymous functions)
>
> The what? 'Normally', 'event handlers' are objects that implement the
> EventListener interface. The fantasy nomenclature for function
> declarations and expressions aside, function objects created by event
> handlers don't have an identifier, so they should be alright (eyeroll).

Ok, this source provides more consistent information:
http://www.w3.org/html/wg/drafts/html/master/webappapis.html#event-handler-content-attributes

"7. Set up the script's global object [...]" + "This is typically a
Window object. In JavaScript, this corresponds to the global object."
(http://www.w3.org/html/wg/drafts/html/master/webappapis.html#script%27s-global-object)

If I understood it correctly the code inside event-handler attribute is
executed in global context, right?

Thomas 'PointedEars' Lahn

unread,
Feb 10, 2013, 6:48:08 PM2/10/13
to
Cezary Tomczyk wrote:

> W dniu 2013-02-10 21:28, Thomas 'PointedEars' Lahn pisze:
>> Cezary Tomczyk wrote:
> [...]
>>> Well, I never use event-handler attributes on elements.
>>
>> So much the pity. I use event-handler attributes whenever there is no
>> better alternative, for the already named reasons at least.
>>
>>> Just separate behaviours and logic.
>>
>> You are under the delusion that “behavior” and “(business) logic” are
>> separate things. Business logic *is* the behavior of the application;
>> what it does when it receives certain input. Perhaps you meant to say
>> “separate presentation and layout” (which can be a reasonable approach,
>> but _not_ /per se/); still your confusing that already shows how little
>> you actually *understand* of what you are talking about.
>
> Well, I think about exactly what was described in links which I
> specified in one of the previous post.

So, misconceptions by wannabes.

>>> For me is just easier for maintenance.
>>
>> Each time you edit you will have to switch between the script code and
>> the markup, even for tasks that require no more than a one-liner with an
>> event- handler attribute, and – proven already – considerably more (if
>> done properly) with that so-called “unobtrusive JavaScript” approach.
>> How can *greater* code distance and *unnecessarily* *complicated*,
>> *larger* code ease maintenance?
>
> Even, if changes is about "one-liner with an event-handler attribute"
> then I prefer always to make a script code in a separate file.

That course of action is not indicative of a logical thought process.

> I do not want to mix html markup with any script code. It will keep my
> html document clean.

Since HTML 4.01 at the latest, client-side script code inherently belongs to
a scripted HTML document. HTML *includes* the facilities for that in the
form of “script” elements and event-handler attributes.

<http://www.w3.org/TR/REC-html40/interact/scripts.html>

To force parts apart that belong together so that the resulting code is more
complex, *no matter what*, is not logical.

>>> Another thing is when user has no JavaScript* (for whatever reason) then
>>> HTML code is just slightly bigger to download. Not maybe big difference,
>>> but it is. Because contains event-handler attributes which will not be
>>> used when JavaScript is not available.
>>
>> Your logic is flawed. In general, you need *more* source code if you do
>> not use event-handler attributes at all, to make it work reliably. The
>> user needs to download that *larger* code base the *same* as with
>> event-handler attributes, *no matter* whether client-side scripting is
>> supported.
>
> I use reusable patterns which means that I do not need every time to
> create separate code for every behaviour.

I can accept that as an general argument in favor of your approach, but …

> Even, if this will take a few lines more it doesn't matter.

… your conclusion is wrong. It *does* matter, as you can see below.

> Arguments, with which I agree:
>
> http://stackoverflow.com/a/11742769/896702

You have much to learn. *All* of the arguments there, without exception,
are either specious or plain wrong.

See also: <http://en.wikipedia.org/wiki/False_attribution>

| 1) For a long time now there has been a sensible emphasis on a clear split
| between content, style and script.

No, there has not; there has been a recommendation by the W3C, through HTML
4.01's support for CSS, that *markup* (content) and *presentation* be
separated when feasible, in order to reuse code and DRY, among other
advantages:

<http://www.w3.org/TR/REC-html40/present/styles.html>

Even if so, *by whom* has there been an emphasis, *why* does their opinion
matter, and *why* is that emphasis “sensible”? This so-called “argument” is
in fact just theory finding.

<http://en.wikipedia.org/wiki/Thought-terminating_clich%C3%A9#Thought-
terminating_clich.C3.A9> comes to mind here.

| 2) […]
| - you can bind only one event of each kind with DOM-zero events (which is
| what the inline ones are), so you can't have two click event handlers

Wrong (and wrong terminology on top of that – events are not “bound”, for
example; event *listeners* are *added* for an event). An event-handler
attribute value causes the creation of the primary event listener for an
event on an element. You can add listeners to that by using (emulations of)
addEventListener(). BTDT. This was even true before HTML5, but it is first
going to be standardized there.

| - if an event is specified inline, the JS is specified as a string
| (attribute values are always strings) and evaluated when the event
| fires.

Wrong. Source code in event-handler attribute values is being *compiled*
into a(n anonymous) Function instance as it is parsed (like other script
code), so that it is available through content attribute properties, like
“onclick”. That function is simply *called* when the event is being
propagated to the element.

With HTML5, those content attribute properties even are going to be
*standardized* (and are implemented already) as part of the HTML DOM API the
same as content attributes (event-handler attributes) had been before in
HTML 4.01.

See also:

<http://www.w3.org/TR/REC-html40/interact/scripts.html#h-18.2.3>
<http://www.w3.org/TR/DOM-Level-2-HTML/>
<http://www.w3.org/TR/2012/CR-html5-20121217/webappapis.html#events>

| Evaluation is evil.

Now this is *clearly* a thought-terminating cliché (see above).

| - you are faced with having to reference named functions.

That much is true. However, it is an irrelevant conclusion. The statement
is a tautology because at some point a named function needs to be called by
non-native code *in any case*.

<http://en.wikipedia.org/wiki/Ignoratio_elenchi>

| This is not always ideal (event handlers normally take anonymous
| functions) and has implications on the function needing to be global

Wrong, those functions do _not_ need to be methods of the Global Object.
In fact, it is strongly recommended that they not be global, but only
globally available.

<http://en.wikipedia.org/wiki/Red_herring>

>> Browsers do not skip downloading script code when client-side script
>> support is disabled, because it could be re-enabled afterwards.
>
> I created the test page
> http://www.ctomczyk.pl/lab/script_loading/test.html and for example
> Firefox 18.0.2 do not downloading script when scripts are disabled in
> browsers.

Your test case is flawed as it is based on circular reasoning. You cannot
test *using* scripting whether a script is *downloaded* when script support
is disabled, which was the point here. Your test case shows that script
code is not *executed* when script support is disabled, which nobody doubted
as it is tautological.

<http://en.wikipedia.org/wiki/Circular_reasoning>

However, I stand corrected (you were in some way faster than me). After
posting I have observed this in Chromium “Version 24.0.1312.68 Built on
Debian wheezy/sid, running on Debian 7.0 (180326)” through the “Network” tab
of its Developer Tools, and in Iceweasel 18.0.1 through the “Net” tab of
Firebug 1.11.1. So it is safe to say that *some* browsers do not download
script code then.

Still, I do not consider that a sound argument in favor of *unnecessary*
code separation. Because the cases I have been talking about contain a
considerably small amount of script code in event listeners that merely
calls code located elsewhere, and the resulting code is *in total* still
smaller when it has the same degree of compatibility as wholly separated
code.

Here is another example of that: It takes considerably less to write

<a href="foo"
onclick="if (typeof event != 'undefined') return bar(event)">…</a>

than to write in the markup

<script type="text/javascript" src="bar.js"></script>

<a href="foo" id="baz">…</a>

(or worse) and in script resource bar.js something along the following
(kids, do not try that at home!):

window.onload = function () {
var baz = document.getElementById("baz");
if (baz)
{
var f = function (ev) {
var ev2 = (typeof ev == "undefined")
? (typeof window != "undefined"
&& typeof window.event != "undefined")
? window.event
: null)
: ev;

if (ev2)
{
bar(ev2);
}
};

var t = typeof baz.addEventListener;
if (/^\s*unknown\s*$/i.test(t)
|| /^\s*(function|object)\s*$/i.test(t)
&& baz.addEventListener)
{
try
{
baz.addEventListener("click", f, false);
}
catch (e)
{
// stub
}
}
else
{
try
{
baz.onclick = f;
}
catch (e)
{
// stub
}
}
}
};

That the majority of the latter code is (or should be) implemented as
library methods (isHostMethod() etc.) does not change the fact that the
latter code in total is larger and more complex, and still cannot achieve
the same degree of compatibility as the former code, because it can target
only known DOM implementations and it reserves an ID (the latter can only be
worked around with even more complex and potentially incompatible code).

The latter code also does not provide the same user experience as the former
one because there is no event listener added to the element before the
document has been *fully* parsed. If the user activates the element during
loading, they will experience either the (non-script) fallback approach or a
malfunction. That outcome is not acceptable with a *consistent* user
interface.

>>> I wouldn't worry so much about some few kilobytes more in JavaScript
>>> files. There is more important in my opinion problems like: too much
>>> requests to server (files are not combined into one file, a lot of
>>> requests for some data, etc.), not efficient code, files not cached,
>>> etc.
>> Files (better: resources) are cacheable in both cases. And you are
>> *increasing* the number of requests if you move code to external
>> resources, even when not necessary. Again I ask you: Where is the
>> logic in that?
>
> I am not increasing the number of requests if I move code to external
> resources. […]

Certainly you do. It is simple arithmetic: In the trivial case, with event-
handler attributes only *one* HTML resource is required; with “Unobtrusive
JavaScript” *at least* *two* resources are required: one HTML resource and
*at least* one script resource. 2 > 1. So be slow to do that.

--
PointedEars

Thomas 'PointedEars' Lahn

unread,
Feb 10, 2013, 7:02:21 PM2/10/13
to
Cezary Tomczyk wrote:

> W dniu 2013-02-11 00:09, Eric Bednarz pisze:
>> Cezary Tomczyk <cezary....@gmail.com> writes:
>> [event attributes versus DOM*]
>>> Arguments, with which I agree:
>>>
>>> http://stackoverflow.com/a/11742769/896702
>>
>> | if an event is specified inline, the JS is specified as a string
>> | (attribute values are always strings) and evaluated when the event
>> | fires. Evaluation is evil.
>>
>> Newsflash: event attribute value literals are *not* eval'ed. This BS
>> theory just seems to keep coming back like a bad song whenever
>> arguments, common sense and experience are exhausted.

ACK.

> I thought that the code is eval'ed :/

Apparently there are at least two people who think/thought that. AISB,
utter nonsense being told is more the rule than the exception in this field.

[But if I consider postings elsewhere, for example in de.sci.ALL, perhaps
this is true of any field. It has always been easier to post nonsense than
a sound argument. Insofar it appears to be prudent to limit one's rebuttal
to the key points so as not to be overwhelmed by nonsense to be refuted. On
the other hand, a short, to-the-point rebuttal invites even more nonsense.
It is a difficult decision.]

>> | you are faced with having to reference named functions. This is not
>> | always ideal (event handlers normally take anonymous functions)
>>
>> The what? 'Normally', 'event handlers' are objects that implement the
>> EventListener interface. The fantasy nomenclature for function
>> declarations and expressions aside, function objects created by event
>> handlers don't have an identifier, so they should be alright (eyeroll).
>
> Ok, this source provides more consistent information:
> http://www.w3.org/html/wg/drafts/html/master/webappapis.html#event-
handler-content-attributes

That is an Editor's Draft.

> "7. Set up the script's global object [...]" + "This is typically a
> Window object. In JavaScript, this corresponds to the global object."
> (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#script%27s-
global-object)

You keep on quoting irrelevant sources.

> If I understood it correctly the code inside event-handler attribute is
> executed in global context, right?

Wrong, because the scope chain of that code includes more than the global
object:

<http://stackoverflow.com/a/9160009/855543>

Thomas 'PointedEars' Lahn

unread,
Feb 10, 2013, 7:09:30 PM2/10/13
to
Thomas 'PointedEars' Lahn wrote:

> Cezary Tomczyk wrote:
>> W dniu 2013-02-10 21:28, Thomas 'PointedEars' Lahn pisze:
>>> Browsers do not skip downloading script code when client-side script
>>> support is disabled, because it could be re-enabled afterwards.
>> [<http://www.ctomczyk.pl/lab/script_loading/test.html>]
>
> [<http://en.wikipedia.org/wiki/Circular_reasoning>]
>
> However, I stand corrected […]
>
> Still, I do not consider that a sound argument in favor of *unnecessary*
> code separation. Because the cases I have been talking about contain a
> considerably small amount of script code in event listeners that merely
^^^^^^^^^^^^^^^
_event-handler attribute values_

> calls code located elsewhere, and the resulting code is *in total* still
> smaller when it has the same degree of compatibility as wholly separated
> code.
>
> Here is another example of that: […]

Eric Bednarz

unread,
Feb 10, 2013, 7:16:46 PM2/10/13
to
Cezary Tomczyk <cezary....@gmail.com> writes:

> W dniu 2013-02-11 00:09, Eric Bednarz pisze:

>> Newsflash: event attribute value literals are *not* eval'ed. This BS
>> theory just seems to keep coming back like a bad song whenever
>> arguments, common sense and experience are exhausted.
>
> I thought that the code is eval'ed :/

| <ul>
| <li onclick="var quux; alert(delete quux);">Foo</li>
| <li id="bar">Bar</li>
| </ul>
|
| <script>
| document.getElementById('bar').onclick = function () {
| eval("var quux; alert(delete quux);");
| };
| </script>

> Ok, this source provides more consistent information:
> http://www.w3.org/html/wg/drafts/html/master/webappapis.html#event-handler-content-attributes
>
> "7. Set up the script's global object [...]" + "This is typically a
> Window object. In JavaScript, this corresponds to the global object."
> (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#script%27s-global-object)
>
> If I understood it correctly the code inside event-handler attribute
> is executed in global context, right?

What do you mean by 'context'? The execution context of the function
body specified with an event attribute literal is the function object
that it creates.

Thomas 'PointedEars' Lahn

unread,
Feb 10, 2013, 7:38:52 PM2/10/13
to
Eric Bednarz wrote:

> Cezary Tomczyk <cezary....@gmail.com> writes:
>
> [event attributes versus DOM*]
>
>> Arguments, with which I agree:
>>
>> http://stackoverflow.com/a/11742769/896702
>
> […]
> | you are faced with having to reference named functions. This is not
> | always ideal (event handlers normally take anonymous functions)
>
> The what? 'Normally', 'event handlers' are objects that implement the
> EventListener interface.

No, that would be event *listeners* which are implemented in user code.
Event *handlers*, on the other hand, are implemented as built-in code that
calls added event listeners (per W3C DOM Level 3 Events explicitly, in order
of addition for an event). (AISB)

Therefore, you would write

el.addEventListener(eventType, eventListener, capturing);

to add an event listener for an event type to the represented element or

el["on" + eventType.toLowerCase()] = eventListener;

to set the primary event listener for that event as non-capturing on the
represented element.

Event listeners are called by the event handler for an event if they have
not been removed later, and an event of a matching type is being propagated
to the element. As an (AFAIK undocumented) peculiarity of standards-
compliant DOM implementations, the object does not require the handleEvent()
method of the EventListener interface to be implemented by the user; it
suffices that the Function instance that is the event listener implements is
callable, and it is called with the same arguments as handleEvent() would
have been. [However, IMHO a DOM event library should augment the Function
instance with such a method, for maximum compatibility.
jsx.dom.createEventListener() in JSX:events.js does that.]

The distinction is necessary because before W3C DOM Level 2 Events it was
not possible to have more than one event listener for an event on an
element. (Which is why assigning to a then-proprietary event-handler
property was often described misleadingly as assigning an “event handler” or
an “event”, although the actual implementation did not differ much from the
current ones. The wrong terminology is [or was] prevalent in the MSDN
Library.)

<https://developer.mozilla.org/en-US/docs/DOM/EventListener> p.

> The fantasy nomenclature for function
> declarations and expressions aside, function objects created by event
> handlers don't have an identifier, so they should be alright (eyeroll).

ACK :)

Thomas 'PointedEars' Lahn

unread,
Feb 10, 2013, 7:49:58 PM2/10/13
to
Eric Bednarz wrote:

> Cezary Tomczyk <cezary....@gmail.com> writes:
>> W dniu 2013-02-11 00:09, Eric Bednarz pisze:
>>> Newsflash: event attribute value literals are *not* eval'ed. This BS
>>> theory just seems to keep coming back like a bad song whenever
>>> arguments, common sense and experience are exhausted.
>> I thought that the code is eval'ed :/
>
> | <ul>
> | <li onclick="var quux; alert(delete quux);">Foo</li>
> | <li id="bar">Bar</li>
> | </ul>
> |
> | <script>
> | document.getElementById('bar').onclick = function () {
> | eval("var quux; alert(delete quux);");
> | };
> | </script>

Not that I doubt your conclusions (they are the same as mine), but what
exactly is this code supposed to prove?

(BTW, please do not use quoting marks with code that is to be tested. TIA.)

>> Ok, this source provides more consistent information:
>> http://www.w3.org/html/wg/drafts/html/master/webappapis.html#event-
handler-content-attributes
>>
>> "7. Set up the script's global object [...]" + "This is typically a
>> Window object. In JavaScript, this corresponds to the global object."
>> (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#script%27s-
global-object)
>>
>> If I understood it correctly the code inside event-handler attribute
>> is executed in global context, right?
>
> What do you mean by 'context'? The execution context of the function
> body specified with an event attribute literal is the function object

I do not think that “event attribute literal” is proper terminology.
Try “event-handler attribute value” instead.

> that it creates.

An actual object cannot be the abstract entity that is an execution context.
Probably you meant to say that if and when the function is called, execution
enters that function's local context (as opposed to the global execution
context).

dhtml

unread,
Feb 11, 2013, 10:30:05 AM2/11/13
to
On Feb 9, 3:52 pm, Cezary Tomczyk <cezary.tomc...@gmail.com> wrote:
> W dniu 2013-02-10 00:08, Thomas 'PointedEars' Lahn pisze:
>
[...]
> *http://www.w3.org/wiki/The_principles_of_unobtrusive_JavaScript#Separ...
>

Quote:
| This is very easy to do when the script is properly separated from
the
| HTML:
| var x = document.getElementById('somewhereLink');
| if (x) {
| x.onmouseover = ''x.onfocus ='' hideAll;
|}

Not the greatest example.
--
Garrett

Eric Bednarz

unread,
Feb 11, 2013, 11:59:37 AM2/11/13
to
Thomas 'PointedEars' Lahn <Point...@web.de> writes:

> Eric Bednarz wrote:

>> | <ul>
>> | <li onclick="var quux; alert(delete quux);">Foo</li>
>> | <li id="bar">Bar</li>
>> | </ul>
>> |
>> | <script>
>> | document.getElementById('bar').onclick = function () {
>> | eval("var quux; alert(delete quux);");
>> | };
>> | </script>
>
> Not that I doubt your conclusions (they are the same as mine), but what
> exactly is this code supposed to prove?

Variables declared in eval code (that isn't in in strict mode) can be
deleted, but I suppose this is a trick question of sorts.

Thomas 'PointedEars' Lahn

unread,
Feb 11, 2013, 12:19:56 PM2/11/13
to
ACK. But nobody said that it would be part of eval code; just that the code
would be evaluated.

> but I suppose this is a trick question of sorts.

I knew, but did not think of that.

Scott Sauyet

unread,
Feb 11, 2013, 4:03:56 PM2/11/13
to
Thomas 'PointedEars' Lahn wrote:
> Eric Bednarz wrote:
>
>> Variables declared in eval code (that isn't in in strict mode) can be
>> deleted,
>
> ACK.  But nobody said that it would be part of eval code; just that the code
> would be evaluated.

I'm not clear on the distinction you're making here. The discussion
has been that the code would be run through `eval`, has it not? Of
course the code would have to be evaluated in some sense, by some
compiler or interpreter, or it wouldn't do anything. What distinction
are you drawing here, then?

-- Scott

Thomas 'PointedEars' Lahn

unread,
Feb 11, 2013, 4:09:19 PM2/11/13
to
Scott Sauyet wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Eric Bednarz wrote:
>>> Variables declared in eval code (that isn't in in strict mode) can be
>>> deleted,
>>
>> ACK. But nobody said that it would be part of eval code; just that the
>> code would be evaluated.
>
> I'm not clear on the distinction you're making here. The discussion
> has been that the code would be run through `eval`, has it not?

No, it has not. It has been claimed on Stack Overflow that – in proper
language – code in event-handler attribute values would be evaluated when
the event is propagated to the element; Eric's example shows only that it is
not *eval code*. Although I do not doubt that the original claim is false –
there is a Function instance available before the event occurs – those are
two separate things.

Scott Sauyet

unread,
Feb 11, 2013, 4:59:29 PM2/11/13
to
Thomas 'PointedEars' Lahn wrote:
> Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> Eric Bednarz wrote:
>>>> Variables declared in eval code (that isn't in in strict mode) can be
>>>> deleted,
>
>>> ACK.  But nobody said that it would be part of eval code; just that the
>>> code would be evaluated.
>
>> I'm not clear on the distinction you're making here.  The discussion
>> has been that the code would be run through `eval`, has it not?
>
> No, it has not.  It has been claimed on Stack Overflow that – in proper
> language – code in event-handler attribute values would be evaluated when
> the event is propagated to the element; Eric's example shows only that it is
> not *eval code*.  Although I do not doubt that the original claim is false –
> there is a Function instance available before the event occurs – those are
> two separate things.

Thank you. Obviously I read the thread in too much of a hurry. And I
didn't even open the Stack Overflow links.

I've never given much thought to the basic question. I had done
similar tests to Eric's to prove the same point he made, but I had not
really considered the question of when the Function instances are
created. I'm quite certain that no sane implementor would create a
new Function instance every time the event listener is needed. But
beyond that, it's not clear to me whether a lazy instantiation would
be better because the listener might never be called, or if there is
some spin-up time for the compiler that would make it simpler to pre-
compile them all. And then there is the question of redefining the
event-handler attributes...

Interesting.

-- Scott

Richard Cornford

unread,
Feb 17, 2013, 7:15:54 PM2/17/13
to
Scott Sauyet wrote:
> Thomas 'PointedEars' Lahn wrote:
<snip>
>> No, it has not. It has been claimed on Stack Overflow that - in
>> proper language - code in event-handler attribute values would
>> be evaluated when the event is propagated to the element; Eric's
>> example shows only that it is not *eval code*. Although I do not
>> doubt that the original claim is false - there is a Function
>> instance available before the event occurs - those are two separate
>> things.
>
> Thank you. Obviously I read the thread in too much of a hurry. And
> I didn't even open the Stack Overflow links.
>
> I've never given much thought to the basic question. I had done
> similar tests to Eric's to prove the same point he made, but I had
> not really considered the question of when the Function instances are
> created.

If I am remembering correctly then if you did you would find that the
actual behaviour differs between browsers and has differed over time.

> I'm quite certain that no sane implementor would create a
> new Function instance every time the event listener is needed.

Yes, that would be an odd thing to do.

> But
> beyond that, it's not clear to me whether a lazy instantiation would
> be better because the listener might never be called, or if there is
> some spin-up time for the compiler that would make it simpler to pre-
> compile them all.

Variations in compiler behaviour might be a factor in finding the
behaviour differing between browsers, but I would suspect that current
compilers are easily fast enough to get the job of
compiling/instantiating g a small function object done without
impacting on any user interaction.

The draw back with lazy compilation of intrinsic event attributes (or
rather the advantage in pre-compiling them) is when you are going to
shown any error reports relating to possible syntax errors in your
attribute code. With pre-compiling you will see the errors when the page
loads (for all of the problematic intrinsic event attributes on that
page), while with lazy compiling you will only see those errors as the
individual events are triggered (so they may slip past any less then
rigorous testing).

And this is the clue to an appropriate test procedure for finding out
when the intrinsic attribute code is used to create function object; put
syntax errors in that code and watch for the moments when those syntax
errors are reported, as it should be at the moment an attempt is made to
compile the code.

I have tried this (a few years back), and as I remember Firefox and
Chrome where actually first instantiating the compiling/function objects
at the moment of reading the, for example, - onclick - property of the
offending element. That is, it appear to be the getters for the
intrinsic event properties that were actually creating the function
object. Which makes more sense than waiting for an actual event needing
to be handled because it is, in principle, possible for javascript code
to access the property prior to any events being triggered, but the
event handling process is still going to have to get the function object
before it can call it.

> And then there is the question of redefining the
> event-handler attributes...
>
> Interesting.
>

Presumably the test to see if the intrinsic event function was
re-created each time it was used (called, or the event handling property
was accessed) would be to store a reference to the function object at
one point, re-trigger the event and then compare the identity of the
function stored with the one directly read from element post-event.

Richard.

--
Gratuitous third-party plug:-
http://doubtfulnews.com/

Cezary Tomczyk

unread,
Feb 19, 2013, 6:07:06 PM2/19/13
to
W dniu 2013-02-11 00:48, Thomas 'PointedEars' Lahn pisze:
> Cezary Tomczyk wrote:
[...]
>> I do not want to mix html markup with any script code. It will keep my
>> html document clean.
>
> Since HTML 4.01 at the latest, client-side script code inherently belongs to
> a scripted HTML document. HTML *includes* the facilities for that in the
> form of “script” elements and event-handler attributes.
>
> <http://www.w3.org/TR/REC-html40/interact/scripts.html>
>
> To force parts apart that belong together so that the resulting code is more
> complex, *no matter what*, is not logical.
>
[...]

>> I use reusable patterns which means that I do not need every time to
>> create separate code for every behaviour.
>
> I can accept that as an general argument in favor of your approach, but …
>
>> Even, if this will take a few lines more it doesn't matter.
>
> … your conclusion is wrong. It *does* matter, as you can see below.

I think that everyone can do at least in a both ways: 1) using
event-handler attribute or 2) use addEventListener (attachEvent) to
register a single event listener on a single target.

By the way:
https://developer.mozilla.org/en-US/docs/DOM/element.addEventListener#Older_way_to_register_event_listeners

"older way"? Hmm.

>> Arguments, with which I agree:
>>
>> http://stackoverflow.com/a/11742769/896702
>
> You have much to learn. [...]

There is no such thing as a "I know everything". Every day each of us
makes mistakes, changes mind and learns. :-)

> See also: <http://en.wikipedia.org/wiki/False_attribution>
>
> | 1) For a long time now there has been a sensible emphasis on a clear split
> | between content, style and script.
>
> No, there has not; there has been a recommendation by the W3C, through HTML
> 4.01's support for CSS, that *markup* (content) and *presentation* be
> separated when feasible, in order to reuse code and DRY, among other
> advantages:
>
> <http://www.w3.org/TR/REC-html40/present/styles.html>
>
> Even if so, *by whom* has there been an emphasis, *why* does their opinion
> matter, and *why* is that emphasis “sensible”? This so-called “argument” is
> in fact just theory finding.
>
> <http://en.wikipedia.org/wiki/Thought-terminating_clich%C3%A9#Thought-
> terminating_clich.C3.A9> comes to mind here.

Recommendation doesn't means "must be used in that way".

> | 2) […]
> | - you can bind only one event of each kind with DOM-zero events (which is
> | what the inline ones are), so you can't have two click event handlers
>
> Wrong (and wrong terminology on top of that – events are not “bound”, for
> example; event *listeners* are *added* for an event). An event-handler
> attribute value causes the creation of the primary event listener for an
> event on an element. You can add listeners to that by using (emulations of)
> addEventListener(). BTDT. This was even true before HTML5, but it is first
> going to be standardized there.

You right. I even created the test:
http://ctomczyk.pl/lab/event_handler_attribute/test.html to prove it myself.

> | - if an event is specified inline, the JS is specified as a string
> | (attribute values are always strings) and evaluated when the event
> | fires.
>
> Wrong. Source code in event-handler attribute values is being *compiled*
> into a(n anonymous) Function instance as it is parsed (like other script
> code), so that it is available through content attribute properties, like
> “onclick”. That function is simply *called* when the event is being
> propagated to the element.
>
> With HTML5, those content attribute properties even are going to be
> *standardized* (and are implemented already) as part of the HTML DOM API the
> same as content attributes (event-handler attributes) had been before in
> HTML 4.01.
>
> See also:
>
> <http://www.w3.org/TR/REC-html40/interact/scripts.html#h-18.2.3>
> <http://www.w3.org/TR/DOM-Level-2-HTML/>
> <http://www.w3.org/TR/2012/CR-html5-20121217/webappapis.html#events>

Thanks for explanation.

> | Evaluation is evil.
>
> Now this is *clearly* a thought-terminating cliché (see above).

I even remember my own topic about "eval"-uation.

[...]
> | This is not always ideal (event handlers normally take anonymous
> | functions) and has implications on the function needing to be global
>
> Wrong, those functions do _not_ need to be methods of the Global Object.
> In fact, it is strongly recommended that they not be global, but only
> globally available.

Make sense.

>>> Browsers do not skip downloading script code when client-side script
>>> support is disabled, because it could be re-enabled afterwards.
>>
>> I created the test page
>> http://www.ctomczyk.pl/lab/script_loading/test.html and for example
>> Firefox 18.0.2 do not downloading script when scripts are disabled in
>> browsers.
>
> Your test case is flawed as it is based on circular reasoning. You cannot
> test *using* scripting whether a script is *downloaded* when script support
> is disabled, which was the point here. Your test case shows that script
> code is not *executed* when script support is disabled, which nobody doubted
> as it is tautological.
>
> <http://en.wikipedia.org/wiki/Circular_reasoning>
>
> However, I stand corrected (you were in some way faster than me). After
> posting I have observed this in Chromium “Version 24.0.1312.68 Built on
> Debian wheezy/sid, running on Debian 7.0 (180326)” through the “Network” tab
> of its Developer Tools, and in Iceweasel 18.0.1 through the “Net” tab of
> Firebug 1.11.1. So it is safe to say that *some* browsers do not download
> script code then.

Yes. That what I meant. There is no 100% guarantee that all browsers
will not download scripts in above case.

> Still, I do not consider that a sound argument in favor of *unnecessary*
> code separation. Because the cases I have been talking about contain a
> considerably small amount of script code in event listeners that merely
> calls code located elsewhere, and the resulting code is *in total* still
> smaller when it has the same degree of compatibility as wholly separated
> code.

Maybe in a simple cases using event-handler attributes make sense, but
in a bigger projects *for me* doesn't make sense at all.

> Here is another example of that: It takes considerably less to write
[...]

(cutted code due to problems with aioe.org)

> That the majority of the latter code is (or should be) implemented as
> library methods (isHostMethod() etc.) does not change the fact that the
> latter code in total is larger and more complex, and still cannot achieve
> the same degree of compatibility as the former code, because it can target
> only known DOM implementations and it reserves an ID (the latter can only be
> worked around with even more complex and potentially incompatible code).
>
> The latter code also does not provide the same user experience as the former
> one because there is no event listener added to the element before the
> document has been *fully* parsed. If the user activates the element during
> loading, they will experience either the (non-script) fallback approach or a
> malfunction. That outcome is not acceptable with a *consistent* user
> interface.

Thomas, I didn't said that using event-handler attributes is a wrong
way. I've just said that I prefer to do it in a separate file.
Especially, as I said, when I am working on a big project with a big team.

[...]
>> I am not increasing the number of requests if I move code to external
>> resources. […]
>
> Certainly you do. It is simple arithmetic: In the trivial case, with event-
> handler attributes only *one* HTML resource is required; with “Unobtrusive
> JavaScript” *at least* *two* resources are required: one HTML resource and
> *at least* one script resource. 2 > 1. So be slow to do that.

True. In trivial case, but mostly I have a more complex cases :-/

Scott Sauyet

unread,
Feb 21, 2013, 3:33:45 PM2/21/13
to
Richard Cornford wrote:
> Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> No, it has not. It has been claimed on Stack Overflow that - in
>>> proper language - code in event-handler attribute values would
>>> be evaluated when the event is propagated to the element; Eric's
>>> example shows only that it is not *eval code*. Although I do not
>>> doubt that the original claim is false - there is a Function
>>> instance available before the event occurs - those are two separate
>>> things.
>
>> Thank you.  Obviously I read the thread in too much of a hurry.  And
>> I didn't even open the Stack Overflow links.
>
>> I've never given much thought to the basic question.  I had done
>> similar tests to Eric's to prove the same point he made, but I had
>> not really considered the question of when the Function instances are
>> created.
>
> If I am remembering correctly then if you did you would find that the
> actual behaviour differs between browsers and has differed over time.

Obviously with open-source browsers, it's easy enough to find the
truth of the matter if we're interested enough, but it's not clear to
me how you would determine this for other browsers. I'm simply not
follolwing your suggestion below about the reporting of syntax
errors. I don't remember seeing errors reported in inline handlers
before they were called, but as I rarely use inline handlers, I don't
really have a strong notion that they wouldn't be. But even if
they're not reported until later, the parsing of these attributes
might still not run in the same process that parses SCRIPT elements
and reports errors in Javascript programs. So, while we could
certainly obtain evidence that this parsing is done early, a lack of
that evidence will not imply that it is not done early, as far as I
can tell.

>> I'm quite certain that no sane implementor would create a
>> new Function instance every time the event listener is needed.
>
> Yes, that would be an odd thing to do.

But we both know that some of the implementors out there have done
some fairly odd things over the years...


>> But
>> beyond that, it's not clear to me whether a lazy instantiation would
>> be better because the listener might never be called, or if there is
>> some spin-up time for the compiler that would make it simpler to pre-
>> compile them all.
>
> Variations in compiler behaviour might be a factor in finding the
> behaviour differing between browsers, but I would suspect that current
> compilers are easily fast enough to get the job  of
> compiling/instantiating g a small function object  done without
> impacting on any user interaction.

One, a few, or a few hundred, certainly. But I can see this being a
usful optimization on a page that has many thousands or tens of
thousands of inline event listener attributes. There are certainly
still sites written like that, I'm sorry to say. I wouldn't really
expect it; I simply hadn't given the question any significant
thought. And I still haven't done any actual research. :-)


> The draw back with lazy compilation of intrinsic event attributes (or
> rather the advantage in pre-compiling them) is when you are going to
> shown any error reports relating to possible syntax errors in your
> attribute code. With pre-compiling you will see the errors when the page
> loads (for all of the problematic intrinsic event attributes on that
> page), while with lazy compiling you will only see those errors as the
> individual events are triggered (so they may slip past any less then
> rigorous testing).
>
> And this is the clue to an appropriate test procedure for finding out
> when the intrinsic attribute code is used to create function object; put
> syntax errors in that code and watch for the moments when those syntax
> errors are reported, as it should be at the moment an attempt is made to
> compile the code.

I have a very anemic set of browsers on this machine, but I did run
that test on IE8, Chrome 24, and Firefox 10. IE reports an error on
loading the page. Chrome and Firefox do not note it on page load.
They note it if I try to invoke the event or if I try to assign a
variable to the value of that element's event handler. I don't need
to try to invoke the function stored in that variable, simply to make
the assignment:

<p id="a" onclick="vart x = [};">error here in IE</p>

// ...
var p = document.getElementById("a");
var handler = p.onclick; // error here in Chrome and FF
handler(); // error here again, of course.


> I have tried this (a few years back), and as I remember Firefox and
> Chrome where actually first instantiating the compiling/function objects
> at the moment of reading the, for example, - onclick - property of the
> offending element. That is, it appear to be the getters for the
> intrinsic event properties that were actually creating the function
> object. Which makes more sense than waiting for an actual event needing
> to be handled because it is, in principle, possible for javascript code
> to access the property prior to any events being triggered, but the
> event handling process is still going to have to get the function object
> before it can call it.

My test confirms your result with Chrome 24 and FF 10. The behavior
in IE8 is significantly different.


> [ ... ]

Thank you for the interesting information.


> --
> Gratuitous third-party plug:-http://doubtfulnews.com/

I hadn't seen that before. A lot of fun. Is this simply a site you
enjoy, or do you have a hand in creating / maintaining it?

-- Scott

Thomas 'PointedEars' Lahn

unread,
Feb 21, 2013, 7:12:59 PM2/21/13
to
Scott Sauyet wrote:

> […] I'm quite certain that no sane implementor would create a
> new Function instance every time the event listener is needed. But
> beyond that, it's not clear to me whether a lazy instantiation would
> be better because the listener might never be called, or if there is some
> spin-up time for the compiler that would make it simpler to pre-compile
> them all.

Certainly. That there is a Function instance when the property is accessed
does not need to mean that there is also a Function instance when it is not.
It appears to be prudent that there is a getter that creates the Function
instance and returns a reference to it not before the property is accessed,
or there may be a factory that creates the Function instance when the event
is dispatched to the element.

Insofar one should generally expect event-handler attributes to be more
efficient than event-handler properties (and their correspondent API
features) because with the latter the Function instance needs to be created
first (by the developer).

> And then there is the question of redefining the event-handler
> attributes...

What is the question?

Richard Cornford

unread,
Feb 21, 2013, 7:59:31 PM2/21/13
to
Scott Sauyet wrote:
> Richard Cornford wrote:
>> Scott Sauyet wrote:
<snip>
>>> I've never given much thought to the basic question. I had done
>>> similar tests to Eric's to prove the same point he made, but I had
>>> not really considered the question of when the Function instances
>>> are created.
>>
>> If I am remembering correctly then if you did you would find that
>> the actual behaviour differs between browsers and has differed
>> over time.
>
> Obviously with open-source browsers, it's easy enough to find the
> truth of the matter if we're interested enough,

And know the language in which it is written and have the time to
understand the specifics of a complex piece of software.

> but it's not clear
> to me how you would determine this for other browsers. I'm simply
> not follolwing your suggestion below about the reporting of syntax
> errors.

Interesting, as you appear to have done an entirely serviceable job of
implanting it below.

> I don't remember seeing errors reported in inline handlers
> before they were called, but as I rarely use inline handlers, I
> don't really have a strong notion that they wouldn't be.

You probably also don't/wouldn't tend put syntax errors , so not seeing
them reported should not be surprising. However, over the years there
have been a fair few questions asked on this group where the cause of
the issue being questioned was syntax errors in intrinsic event
attribute code. (With one of the more common causes of javascript syntax
errors being inappropriate HTML entity use (or lack thereof) and/or
escaping in intrinsic event attribute code.)

> But even
> if they're not reported until later, the parsing of these attributes
> might still not run in the same process that parses SCRIPT elements
> and reports errors in Javascript programs.

Looking back at it I noticed that the last time I tried this Opera was
not reporting syntax errors in its error console. This represented a
change from earlier Opera versions which reported those syntax errors as
the page loaded, from which I concluded that they had switched from
compiling them as the page loads to lazy compiling them as needed, but
had filed to sort the error reporting out.

> So, while we could
> certainly obtain evidence that this parsing is done early, a lack of
> that evidence will not imply that it is not done early, as far as I
> can tell.

No, but demonstrating that you can provoke the syntax error report at
any specific later time by performing a specified actions (such as
reading a DOM element's pertinent intrinsic event property) can be used
as evidence that the compiling is being done at that point. Opera (at
least in the state it was in when I last tried this) may not be
providing any positive evidence of how it is behaving in this regard,
but all of IE, Firefox and Chrome are.

>>> I'm quite certain that no sane implementor would create a
>>> new Function instance every time the event listener is needed.
>>
>> Yes, that would be an odd thing to do.
>
> But we both know that some of the implementors out there have done
> some fairly odd things over the years...

Yes we do :)

>>> But
>>> beyond that, it's not clear to me whether a lazy instantiation
>>> would be better because the listener might never be called, or
>>> if there is some spin-up time for the compiler that would make
>>> it simpler to pre-compile them all.
>>
>> Variations in compiler behaviour might be a factor in finding the
>> behaviour differing between browsers, but I would suspect that
>> current compilers are easily fast enough to get the job of
>> compiling/instantiating a small function object done without
>> impacting on any user interaction.
>
> One, a few, or a few hundred, certainly. But I can see this being
> a usful optimization on a page that has many thousands or tens of
> thousands of inline event listener attributes. There are certainly
> still sites written like that, I'm sorry to say. I wouldn't really
> expect it; I simply hadn't given the question any significant
> thought. And I still haven't done any actual research. :-)
>
>> The draw back with lazy compilation of intrinsic event attributes
>> (or rather the advantage in pre-compiling them) is when you are
>> going to shown any error reports relating to possible syntax errors
>> in your attribute code. With pre-compiling you will see the errors
>> when the page loads (for all of the problematic intrinsic event
>> attributes on that page), while with lazy compiling you will only
>> see those errors as the individual events are triggered (so they
>> may slip past any less then rigorous testing).
>>
>> And this is the clue to an appropriate test procedure for finding
>> out when the intrinsic attribute code is used to create function
>> object; put syntax errors in that code and watch for the moments
>> when those syntax errors are reported, as it should be at the
>> moment an attempt is made to compile the code.
>
> I have a very anemic set of browsers on this machine, but I did run
> that test on IE8, Chrome 24, and Firefox 10. IE reports an error on
> loading the page.

Looking back at what I wrote I notice that I did not remember to mention
that this is what I was expecting from IE (and it is still the same up
to at least IE9). In fact it was this extreme that I was alluding to
when I wrote of "behaviour differs between browsers", and in my opinion
is a sensible behaviour for a browser as it effetely allows you to
syntax check all of the intrinsic event attribute code on a page in one
shot, while the lazy compiling approach needs more hands-on testing to
achieve the same level of code syntax verification.

This has also been the historic behaviour (including, as I mentioned,
previous versions of Opera, and in the original versions of
Mozilla/Firefox). That history possibly gives me a bit of a
pre-conception prejudice; this is what I see as normal, and the lazy
compiling is one of those new fangled novelties ;-)

> Chrome and Firefox do not note it on page load.
> They note it if I try to invoke the event or if I try to assign a
> variable to the value of that element's event handler.

Which I will maintain is specifically the necessary reading of the
intrinsic event property rather than the actual assignment operation
(Implying that it is implemented in the getter for the property).

And that is pretty much exactly the test I was proposing.

> I don't need
> to try to invoke the function stored in that variable, simply to
> make the assignment:

Yes, any implied reading of the property should do. That would be
necessary to facilitate doing things like - if(typeof p.onclick !=
'undefined') - and getting an appropriate result.

> <p id="a" onclick="vart x = [};">error here in IE</p>
>
> // ...
> var p = document.getElementById("a");
> var handler = p.onclick; // error here in Chrome and FF
> handler(); // error here again, of course.
>
>
>> I have tried this (a few years back), and as I remember Firefox
>> and Chrome where actually first instantiating the compiling/
>> function objects at the moment of reading the, for example,
>> - onclick - property of the offending element. That is, it appear
>> to be the getters for the intrinsic event properties that were
>> actually creating the function object. Which makes more sense than
>> waiting for an actual event needing to be handled because it is,
>> in principle, possible for javascript code to access the property
>> prior to any events being triggered, but the event handling
>> process is still going to have to get the function object before
>> it can call it.
>
> My test confirms your result with Chrome 24 and FF 10. The behavior
> in IE8 is significantly different.

Yes, I did intend citing IE's behaviour.

>> [ ... ]
>
> Thank you for the interesting information.
>
>
>> --
>> Gratuitous third-party plug:-
>> http://doubtfulnews.com/
>
> I hadn't seen that before. A lot of fun. Is this simply a site
> you enjoy, or do you have a hand in creating / maintaining it?

Third-party means just that. Technically, I think the site is pretty
much 100% off the shelf software (so not interesting in itself, and
pretty much what you expect these days). It is a site that I enjoy; for
the subject(s) covered and the attitude towards them.

Thomas 'PointedEars' Lahn

unread,
Feb 21, 2013, 8:00:10 PM2/21/13
to
Richard Cornford wrote:

> I have tried this (a few years back), and as I remember Firefox and
> Chrome where actually first instantiating the compiling/function objects
> at the moment of reading the, for example, - onclick - property of the
> offending element. That is, it appear to be the getters for the
> intrinsic event properties that were actually creating the function
> object. Which makes more sense than waiting for an actual event needing
> to be handled because it is, in principle, possible for javascript code
> to access the property prior to any events being triggered, but the
> event handling process is still going to have to get the function object
> before it can call it.

Although it looks as though a DOM implementation's event handler would
[[Call]] the Function instance that is the event listener, it is actually
calling code that results from compiling the Function code into either
bytecode for a Virtual Machine or native machine code. So it is possible
that with event-handler attributes no Function instance at all is being
created unless user code accesses the corresponding event-handler property.
(AFAIK there is no built-in way to retrieve an event listener added with
EventTarget::addEventListener().)

In addition to those possible factory-getters, I have learned recently that
with Chromium/Chrome the issue is even more complex. By contrast to e. g.
Mozilla SpiderMonkey, which compiles to and executes bytecode, Google V8
compiles to and executes native machine code (which I knew before); however,
I did not know that code generation does not happen before the function is
called and usually does not happen again (because different code paths are
handled with hidden classes). Finally, optimized machine code is being
generated (once) for objects that are accessed often, so that subsequent
accesses to them are faster.

See also <http://code.google.com/p/v8/>; I can highly recommend especially
the second video.

Scott Sauyet

unread,
Feb 23, 2013, 10:54:37 AM2/23/13
to
Richard Cornford wrote:
> Scott Sauyet wrote:
>> Richard Cornford wrote:
>>> Scott Sauyet wrote:
> <snip>
>>>> I've never given much thought to the basic question. I had done
>>>> similar tests to Eric's to prove the same point he made, but I had
>>>> not really considered the question of when the Function instances
>>>> are created.
>
>>> If I am remembering correctly then if you did you would find that
>>> the actual behaviour differs between browsers and has differed
>>> over time.
>
>> Obviously with open-source browsers, it's easy enough to find the
>> truth of the matter if we're interested enough,
>
> And know the language in which it is written and have the time to
> understand the specifics of a complex piece of software.

Yes, I did mean that the collective "we" can find out. I'm assuming
that a group as diverse as the contributors to this ng, for instance,
would probably have among them the requisite skills to discover this
and report to the group, even if one of us in particular didn't
personally didn't know the implementation language of the engine in
question. But I wasn't really proposing that research.

>> but it's not clear
>> to me how you would determine this for other browsers.  I'm simply
>> not follolwing your suggestion below about the reporting of syntax
>> errors.
>
> Interesting, as you appear to have done an entirely serviceable job of
> implanting it below.

I feel as though this technique does not distinguish between an
implementation that parses all the inline event listeners as it parses
the document but doesn't report them unless a request is made for one
and an implementation that doesn't parse them at all until such a
request is made. Perhaps since there's no real difference to the end
user, the distinction is purely academic, but it's still a somewhat
interesting one to me.

>> I don't remember seeing errors reported in inline handlers
>> before they were called, but as I rarely use inline handlers, I
>> don't really have a strong notion that they wouldn't be.
>
> You probably also don't/wouldn't tend put syntax errors , so not seeing
> them reported should not be surprising.

Well, I don't do so *intentionally*, but there are times... :-)

> However, over the years there
> have been a fair few questions asked on this group where the cause of
> the issue being questioned was syntax errors in intrinsic event
> attribute code. (With one of the more common causes of javascript syntax
> errors being inappropriate HTML entity use (or lack thereof) and/or
> escaping in intrinsic event attribute code.)

I guess my test-in-Chrome-first methodology, which replaced my test-in-
Firefox-first one, (and in-Firebird, in-Phoenix, in-Netscape before
that!) means that I may not often run into the difference in behavior
between the browsers. As soon as I can determine that such a problem
is caused by a common cause and is not browser-specific, I'm not
likely to test in other browsers; or, even if I do, I'm less likely to
pay attention to slight differences in how the error manifests.

>> But even
>> if they're not reported until later, the parsing of these attributes
>> might still not run in the same process that parses SCRIPT elements
>> and reports errors in Javascript programs.
>
> Looking back at it I noticed that the last time I tried this Opera was
> not reporting syntax errors in its error console. This represented a
> change from earlier Opera versions which reported those syntax errors as
> the page loaded, from which I concluded that they had switched from
> compiling them as the page loads to lazy compiling them as needed, but
> had filed to sort the error reporting out.

As I said, I do think there is a third possibility, but there seems to
be no practical way to distinguish it from lazy loading; the only way
to know for sure would be to view the source code. I know Opera is
switching from their own Presto to the Webkit rendering engine. I
don't recall what they are going to use for Javascript in the future.

>> So, while we could
>> certainly obtain evidence that this parsing is done early, a lack of
>> that evidence will not imply that it is not done early, as far as I
>> can tell.
>
> No, but demonstrating that you can provoke the syntax error report at
> any specific later time by performing a specified actions (such as
> reading a DOM element's pertinent intrinsic event property) can be used
> as evidence that the compiling is being done at that point.  Opera (at
> least in the state it was in when I last tried this) may not be
> providing any positive evidence of how it is behaving in this regard,
> but all of IE, Firefox and Chrome are.

It's of course definitive evidence that it's done no later than that
point, but only circumstantial evidence that it is actually performed
then.


> [ ... ]
>>> And this is the clue to an appropriate test procedure for finding
>>> out when the intrinsic attribute code is used to create function
>>> object; put syntax errors in that code and watch for the moments
>>> when those syntax errors are reported, as it should be at the
>>> moment an attempt is made to compile the code.
>
>> I have a very anemic set of browsers on this machine, but I did run
>> that test on IE8, Chrome 24, and Firefox 10.  IE reports an error on
>> loading the page.
>
> Looking back at what I wrote I notice that I did not remember to mention
> that this is what I was expecting from IE (and it is still the same up
> to at least IE9). In fact it was this extreme that I was alluding to
> when I wrote of "behaviour differs between browsers", and in my opinion
> is a sensible behaviour for a browser as it effetely allows you to
> syntax check all of the intrinsic event attribute code on a page in one
> shot, while the lazy compiling approach needs more hands-on testing to
> achieve the same level of code syntax verification.
>
> This has also been the historic behaviour (including, as I mentioned,
> previous versions of Opera, and in the original versions of
> Mozilla/Firefox). That history possibly gives me a bit of a
> pre-conception prejudice; this is what I see as normal, and the lazy
> compiling is one of those new fangled novelties  ;-)

And interestingly, perhaps because I've done more of my web
development since these new-fangled developments arose (I've done web
development since the late 90's, but it's been the center of my career
only since about 2005; and I've done Javascript-only development only
for the last three years), this lazy-loading seems entirely natural to
me.

>> Chrome and Firefox do not note it on page load.
>> They note it if I try to invoke the event or if I try to assign a
>> variable to the value of that element's event handler.
>
> Which I will maintain is specifically the necessary reading of the
> intrinsic event property rather than the actual assignment operation
> (Implying that it is implemented in the getter for the property).

Yes, I'm sure that's the case.


> And that is pretty much exactly the test I was proposing.
>
>> I don't need
>> to try to invoke the function stored in that variable, simply to
>> make the assignment:
>
> Yes, any implied reading of the property should do. That would be
> necessary to facilitate doing things like - if(typeof p.onclick !=
> 'undefined') - and getting an appropriate result.

Confirmed.

> [ ... ]

-- Scott
0 new messages