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.
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