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

Re: onclick=function(){obj.meth()}

5 views
Skip to first unread message
Message has been deleted

Tom de Neef

unread,
Feb 20, 2012, 2:20:37 PM2/20/12
to
"Puzzled" <scratch...@example.com> schreef in bericht
news:jp45k75qbcjbb5v8t...@4ax.com...
>
> function row( i )
> {
> var rec_s = '<tr><td><a href="javascript:void(0);" '+
> 'id="foo'+i+'" '+
> 'onclick=function(){alert('+i+')}>'+i+'</a>'+
> '</td></tr>';
> return rec_s ;
> }
>

This function compiles in FF and JSlint doesn't complain either.
Tom


Jake Jarvis

unread,
Feb 20, 2012, 2:39:07 PM2/20/12
to
It's not about just compiling/passing as syntactically valid js program
on the first level, the real problem manifests itself "later", when
actually clicking the resulting anchor.

--
Jake Jarvis

Stefan Weiss

unread,
Feb 20, 2012, 3:09:05 PM2/20/12
to
On 2012-02-20 20:02, Puzzled wrote:
> Now I'm trying to convert the code to javascript's version of oo
> style
...
> function row( i )
> {
> var rec_s = '<tr><td><a href="javascript:void(0);" '+
> 'id="foo'+i+'" '+
> 'onclick=function(){alert('+i+')}>'+i+'</a>'+
> '</td></tr>';
> return rec_s ;
> }

Why are you wrapping "function(){ ... }" around your event handler code?
That's not what "javascript's version of oo style" is. Anonymous
functions have their place, but they need to be part of an expression,
or it's syntax error. Drop the "function(){ ... }" bit (and put the
remaining onclick value in quotes, while you're at it).

There are some other weak spots in your code, but this should resolve
the syntax error.


- stefan

Evertjan.

unread,
Feb 20, 2012, 3:29:51 PM2/20/12
to
This kind of works:

<div onclick=alert('a')>click</div>

but this not:

<div onclick=alert('a b')>click</div>

[so if your string i contains whitespace you are in trouble]

You should have the onclick js in quotes:

<div onclick="alert('a b')">click</div>

even then

<div onclick="function(){alert('a b')}">click</div>

will not work, because this

<script type='text/javascript'>
function(){alert('a b')}
</script>

does not,
methinks because an anonimous function has to be compiled to be called.

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

Jake Jarvis

unread,
Feb 20, 2012, 4:38:22 PM2/20/12
to
On 20.02.2012 21:47, Puzzled wrote:
> What I supplied was the simplest form that gives the error. What
> I'm actually trying to do is use a method as the event service
> routine, so a somewhat more accurate version of the code would
> be:
>
> // row is called as x.rec_row,
> // where x is the obj instance identifier
>
> // esr is the event service routine declared in x
>
> // i is the integer id of the record that can be selected
> // for further processing by clicking the link
>
> function row( i )
> {
> var proxy = this ; // create a closure-alias for 'this'
> var rec_s = '<tr><td><a href="javascript:void(0);" '+
> 'id="foo'+i+'" '+
> 'onclick=function(){proxy.esr(i)}>'+i+'</a>'+
> '</td></tr>';
> return rec_s ;
> }
>
> It's my understanding that to use a method as an esr, I've to
> create and use a proxy for 'this' in the event binding as here,
> and use an anon function so as to be able to pass arguments. Is
> that not so?

When you use HTML "intrinsic event attributes" you write as attribute
content the statements you want executed

<a onclick="p.esr(2);">2</a>

(note the delimiting with " (details in the HTML specs))


When you script the HTML document by manipulating the higher level DOM
representation you assign an anonymous function

anchorRef.onclick = function () { p.esr(2); };

--
Jake Jarvis
Message has been deleted

Gene Wirchenko

unread,
Feb 20, 2012, 5:04:16 PM2/20/12
to
On Mon, 20 Feb 2012 15:47:45 -0500, Puzzled
<scratch...@example.com> wrote:

[snip]

>It's my understanding that to use a method as an esr, I've to
>create and use a proxy for 'this' in the event binding as here,
>and use an anon function so as to be able to pass arguments. Is
>that not so?

No. (Please read this understanding that I think I know what you
want to do, but that I do not understand your bit about a proxy. I am
still weak on exactly how to use the this object. From my
perspective, JavaScript is a bit weird with how the this object
works.)

I am fairly new to the deep end of the JavaScript pool, so the
following might not be the best way, but it does work reliably.

Somewhere, I create the function that is what you call an "event
service routine". That is *separate* from the on clause. (Unless the
on action is trivial as in the onfocus clause below, I create a
separate function.)

For the on clause, I have a call to the function with whatever
parameters I need. Here is one control from my experimental page:
<input name="CliCode" id="Text" onfocus="this.select();"
onblur="return FieldData['CliCode'].FIValidation(this);" size="3"
maxlength="3">

In the code above, FieldData is an array of FieldItem objects.
FieldItem contains data about data fields, and its method
.FIValidation() handles the validation for the field/control. Because
the control may be accessed, I pass the this object to the validation.
There is absolutely no problem passing parameters.


Advanced readers: "the this object" is awkward. "this" with or
without the quotes is confusing. Is there a better way to refer to
the this object in English text?

Sincerely,

Gene "Dogpaddle" Wirchenko
Message has been deleted

Scott Sauyet

unread,
Feb 20, 2012, 4:43:05 PM2/20/12
to
Puzzled wrote:
>  function row( i )
>  {
>      var proxy = this ;   // create a closure-alias for 'this'
>      var rec_s  = '<tr><td><a href="javascript:void(0);" '+
> 'id="foo'+i+'" '+
>          'onclick=function(){proxy.esr(i)}>'+i+'</a>'+
>         '</td></tr>';
>      return rec_s ;
>  }
>
> It's my understanding that to use a method as an esr, I've to
> create and use a proxy for 'this' in the event binding as here,
> and use an anon function so as to be able to pass arguments.  Is
> that not so?

I think you need to re-read Stefan's response.

An event handler stored as a DOM attribute like this:

<element onclick='xyz' ... >

should contain only the body of the function, and not the function
declaration itself. Thus, don't do

<element onclick='function(){doSomething();}' ...>

but instead simply

<element onclick='doSomething();' ...>

If you're attaching an event handler directly in JS code (not running
through the attribute, then you would assign an actual function
reference:

var myElement = ...
myElement.onclick = function() {doSomething();}

although there are many alternative ways of attaching such a handler.

-- Scott

Stefan Weiss

unread,
Feb 20, 2012, 5:17:42 PM2/20/12
to
On 2012-02-20 21:47, Puzzled wrote:
> What I supplied was the simplest form that gives the error.

Actually, Evertjan posted a very nice and short explanation of why the
error occurred.

> function row( i )
> {
> var proxy = this ; // create a closure-alias for 'this'
> var rec_s = '<tr><td><a href="javascript:void(0);" '+
> 'id="foo'+i+'" '+
> 'onclick=function(){proxy.esr(i)}>'+i+'</a>'+
> '</td></tr>';
> return rec_s ;
> }

1) This will still trigger the same syntax error
2) The onclick attribute value still isn't quoted
3) This time, the variable i will not get interpolated

To remove the syntax error, you should have used

... + 'onclick="proxy.esr(' + i + ')">' + i + '</a>' + ...

> It's my understanding that to use a method as an esr, I've to
> create and use a proxy for 'this' in the event binding as here,
> and use an anon function so as to be able to pass arguments. Is
> that not so?

Ah, now I see where this is coming from.

It doesn't work the way you wrote it. The words are all there, but I
don't think you know _why_ you're supposed to "create a proxy for this"
and "use an anon function".

When your inline onclick handler is activated, it will evaluate whatever
is written in - onclick="..." from a different scope than your row()
function*. This means that the |this| value from row() is no longer
available. And neither is your proxy variable, which goes out of scope
as soon as the row() function returns. There are no references to it
left, so it will just be garbage collected. Putting its name in a string
doesn't count as a reference.

(* the details of the scoping and context of inline event handlers are a
little tricky; I'll skip those for now)

If you want to stick with inline (HTML) event handlers, you need a way
to refer to your x object from the outside. If x is visible globally,
this may be as simple as

... + 'onclick="x.esr(' + i + ')">' + i + '</a>' + ...

The cleaner way would be to create the your table rows with DOM methods
instead of HTML, and use event handler properties:

---------------------------------------------------------------------------
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>

<table id="argl"></table>

<script>

function MyObj () {

this.table = document.getElementById("argl");

this.esr = function (i) {
alert("Row " + i + " was clicked.");
}

this.row = function (i) {
var tr = document.createElement("tr"),
td = document.createElement("td"),
that = this; // <---- here's your proxy for |this|

td.appendChild(document.createTextNode("Row nr: " + i));
td.onclick = function () {
that.esr(i); // <---- and here's where you use it
};
tr.id = "foo" + i;
tr.appendChild(td);
this.table.appendChild(tr);
}

}

var x = new MyObj();
x.row(3);
x.row(5);

</script>

</body>
</html>

---------------------------------------------------------------------------

It will even work without a proxy for |this|, if bind() is available:

this.row = function (i) {
var tr = document.createElement("tr"),
td = document.createElement("td");

td.appendChild(document.createTextNode("Row nr: " + i));
td.onclick = function () {
this.esr(i); // <--- no more proxy needed, |this| is bound
}.bind(this);

....

Hope this gets you on the right track.

- stefan
Message has been deleted

Stefan Weiss

unread,
Feb 20, 2012, 6:57:20 PM2/20/12
to
On 2012-02-20 23:48, Puzzled wrote:
> This is what I'm trying to do:
>
> onclick = "this.some_method_identifier( arg, arg )"
>
> where 'this' is the instance's self-reference.
>
> It shouldn't be hard to do

You think so? I'd say it is impossible in your case. Inline event
handlers are not executed in the scope of your x object. When they get
activated, they set |this| to the element node they're attached to. You
would need some other way to get the proper context for the row() method
from the _outside_. The only way to do that is to make your x object
globally available.

This is (IMHO) the biggest drawback of inline event handlers. Another is
that you're mixing code and markup. That's why I suggested using DOM
methods.

(What I would actually do in your case is different again: I would set
_one_ handler for the table, and use it to delegate events to the right
methods. But before you attempt that, you should be a little more
comfortable with the DOM and its methods.)

> -- the terp certainly knows that
> 'this' is a special case, and should be able to grasp that when I
> use it in a binding, I want its current value bound. That's the
> whole point of oo after all -- to give a "free" reference to an
> instance such that the same code can be used for all instances.

If you want to pass a reference, then you should do that. What you're
actually doing is placing an identifier (or keyword) inside a string for
later evaluation in a different scope. Unless that identifier is global,
this won't work.

(BTW, I'm assuming that "terp" is the interpreter?)

> But apparently the terp doesn't dereference 'this' at that moment
> or do any trickery to create the expected binding. Instead it
> evaluates 'this' at the time the esr is called, which doesn't
> work.

The |this| value is indeed special. Its value always depends on how a
function is called, and it will not be inherited by nested functions
(hence the need for a proxy if you want to preserve it).

> Yet people do make it work, I suppose, in some way. I thought
> the proxy and the anon function were the required magic, be
> evidently not so, so now I'm back where I started, neck deep in
> confusion and ignorance.

I've shown you one way to make it work, and it doesn't require any
magic. The example I've posted is self-contained, it will run as-is and
do what you describe. We're willing to help you with the confusion and
ignorance, but you need to be open for advice. The way you want to write
it cannot work. Read the example again and try to understand what's
going on. The DOM methods may seem overly verbose at first, but there
are lots of wrappers and libraries out there to make your life easier.
(Or more confusing, in the case of some libraries ;-)


- stefan

Richard Cornford

unread,
Feb 20, 2012, 7:34:43 PM2/20/12
to
Jake Jarvis wrote:
> On 20.02.2012 20:20, Tom de Neef wrote:
>> Puzzled schreef:
>>>
>>> function row( i )
>>> {
>>> var rec_s = '<tr><td><a href="javascript:void(0);" '+
>>> 'id="foo'+i+'" '+
>>> 'onclick=function(){alert('+i+')}>'+i+'</a>'+
>>> '</td></tr>';
>>> return rec_s ;
>>> }
>>>
>>
>> This function compiles in FF and JSlint doesn't complain either.
>>
>
> It's not about just compiling/passing as syntactically valid js
> program on the first level, the real problem manifests itself
> "later", when actually clicking the resulting anchor.

As you say, the real problem will manifest itself later, but that later
will not be when anchor is clicked. The issue here is a syntax error;
an Expression statement is forbidden from commencing with the -
function - keyword by the language's syntax rules, because that would be
ambiguous with a function declaration. And the point when that syntax
error will manifest itself will be when the javascript string defined in
the function above is processed through an HTML parser (probably via the
use of innerHTML, but maybe - document.write -). At that point the
browser must use the text of the - ONCLICK - attribute in the HTML to
create a javascript function object to assign to the DOM element
representation's - onclick - property, which is will not be able to do
because the HTML attribute value contains a javascript syntax error.

Richard.

Stefan Weiss

unread,
Feb 20, 2012, 7:37:14 PM2/20/12
to
On 2012-02-20 23:04, Gene Wirchenko wrote:
> Advanced readers: "the this object" is awkward. "this" with or
> without the quotes is confusing. Is there a better way to refer to
> the this object in English text?

It is awkward. I still haven't found a good way to reduce the
awkwardness in plain text. It's easier when you can use markup (<code>)
or italics or a different color, but on Usenet? *shrugs* I use what
seems appropriate at the moment. Some use "this", or |this|, or `this'.
I think that as long as it's clear what we're talking about, we're okay.
It's not our fault that it has °this° silly name...

BTW, the specs always used to refer to it as "the this value", not "the
this object". IIRC, that's because in ES3 it is possible to set |this|
to a type other than object. In ES5 (strict mode only?), |this| always
has to be of type object. I could be mistaken about the details, but I'm
too lazy to look it up now (it's late, and the wine was good).


- stefan

Richard Cornford

unread,
Feb 20, 2012, 7:45:39 PM2/20/12
to
<snip>

No, not at that point. The syntax error will manifest itself when the
string value defined in the function above is used to create DOM
elements (when it is parsed). If there was no syntax error in the
ONCLICK attribute in the HTML it would be possible, after the string of
HTML text has been parsed to create part of the DOM, to find that
element in the DOM, examine its - onclick - property and see that its
value is a function object and, by converting that object to a string,
examine the code it contains, prior to any user interaction. This would
only be possible if the onclick property's function were created prior
to any possible user interaction with the element in the DOM.

Richard.

Richard Cornford

unread,
Feb 20, 2012, 8:03:52 PM2/20/12
to
Puzzled wrote:> On Mon, 20 Feb 2012 23:17:42 +0100,
<snip>
>
> I do appreciate your responses, and believe that there's still
> a fair bit of confusion here (for which I'm sure I'm responsible).

Yes, saying things is as many words (as it takes) often avoids
confusion.

> This is what I'm trying to do:
>
> onclick = "this.some_method_identifier( arg, arg )"

That is meaningless in javascript terms precisely because the value of
the - this - keyword is not decided at this point.

> where 'this' is the instance's self-reference.
>
> It shouldn't be hard to do -- the terp certainly knows that
> 'this' is a special case,

Presumably you are using "terp" as an abbreviation for interpreter.

In javascript the value of the - this - keyword is (always and only)
decided at runtime, so the interpreter cannot know what the value will
be at the time of tokenising/parsing/compiling the code. Javascript's -
this - values are determined by _how_ any particular function is called,
and the javascript engine cannot tell how a function has been called
until it has been called.

> and should be able to grasp that when I
> use it in a binding,

Presumably you are using "terp" as an abbreviation for interpreter.

In javascript the value of the - this - keyword is (always and only)
decided at runtime, so the interpreter cannot know what the value will
be at the time of tokenising/parsing/compiling the code. Javascript's -
this - values are determined by _how_ any particular function is called,
and the javascript engine cannot tell how a function has been called
until it has been called.

> I want its current value bound. That's the
> whole point of oo after all -- to give a "free" reference to an
> instance such that the same code can be used for all instances.
>
> But apparently the terp doesn't dereference 'this' at that moment
> or do any trickery to create the expected binding. Instead it
> evaluates 'this' at the time the esr is called, which doesn't
> work.

Yes, that is how it works, and you use - this - to refer to any
individual instance from code defined once for a 'Class definition' by
calling the instance's methods in a way that provides the 'correct' -
this - value.

> Yet people do make it work, I suppose, in some way.

Yes, and the two techniques that work have been covered in other posts
in this thread (though not necessarily in their only/optimum forms).

> I thought
> the proxy and the anon function were the required magic, be
> evidently not so, so now I'm back where I started, neck deep in
> confusion and ignorance.

Computer programming is about understand enough to take control, which
is the antithesis of 'magic'.

Richard.

Stefan Weiss

unread,
Feb 20, 2012, 8:13:50 PM2/20/12
to
On 2012-02-21 01:34, Richard Cornford wrote:
> Jake Jarvis wrote:
>> It's not about just compiling/passing as syntactically valid js
>> program on the first level, the real problem manifests itself
>> "later", when actually clicking the resulting anchor.
>
> As you say, the real problem will manifest itself later, but that later
> will not be when anchor is clicked. The issue here is a syntax error;
> an Expression statement is forbidden from commencing with the -
> function - keyword by the language's syntax rules, because that would be
> ambiguous with a function declaration. And the point when that syntax
> error will manifest itself will be when the javascript string defined in
> the function above is processed through an HTML parser (probably via the
> use of innerHTML, but maybe - document.write -). At that point the
> browser must use the text of the - ONCLICK - attribute in the HTML to
> create a javascript function object to assign to the DOM element
> representation's - onclick - property, which is will not be able to do
> because the HTML attribute value contains a javascript syntax error.

You're right about the cause of the syntax error, of course, but I beg
to differ about the rest. What the HTML parser does when it encounters
invalid JS in an event handler attribute is completely up to the
implementation. All it is required to do (if scripting is available and
enabled) is register the presence of the onclick attribute, and leave
the rest for the JS engine. After all, the contents of that attribute
could change at any time, so why bother pre-parsing it.

<a href="#" onclick="|-">.</a>
<!-- in the main document HTML -->

Firefox, Chrome, Opera, Safari don't blink an eye about this, until the
user clicks the link. Imagine my surprise when I found out that IE8
handles it differently, and does throw a syntax error (I didn't have an
IE9 for testing available).


- stefan

Gene Wirchenko

unread,
Feb 20, 2012, 8:20:01 PM2/20/12
to
On Tue, 21 Feb 2012 01:37:14 +0100, Stefan Weiss
<krewe...@gmail.com> wrote:

>On 2012-02-20 23:04, Gene Wirchenko wrote:
>> Advanced readers: "the this object" is awkward. "this" with or
>> without the quotes is confusing. Is there a better way to refer to
>> the this object in English text?
>
>It is awkward. I still haven't found a good way to reduce the
>awkwardness in plain text. It's easier when you can use markup (<code>)
>or italics or a different color, but on Usenet? *shrugs* I use what
>seems appropriate at the moment. Some use "this", or |this|, or `this'.
>I think that as long as it's clear what we're talking about, we're okay.
>It's not our fault that it has °this° silly name...

But we can get stung by it. I was about to say "this" at one
point in my post, and realised that if it were taken as being the
usual English meaning for "this", it would distort what I intended to
state.

>BTW, the specs always used to refer to it as "the this value", not "the
>this object". IIRC, that's because in ES3 it is possible to set |this|
>to a type other than object. In ES5 (strict mode only?), |this| always
>has to be of type object. I could be mistaken about the details, but I'm
>too lazy to look it up now (it's late, and the wine was good).

Thank you for that bit about what the spec stated. I can see
that "the this value" is more accurate as The Awkward-To-Name Entity
is a reference to an object, not an object.

Hmm, maybe, I should call it "TATNE".

Hey! Put down that baseball bat.

Sincerely,

Gene Wirchenko

Stefan Weiss

unread,
Feb 20, 2012, 8:22:34 PM2/20/12
to
On 2012-02-21 01:45, Richard Cornford wrote:
> Stefan Weiss wrote:
>> When your inline onclick handler is activated, it will evaluate
>> whatever is written in - onclick="..."
> <snip>
>
> No, not at that point. The syntax error will manifest itself when the
> string value defined in the function above is used to create DOM
> elements (when it is parsed).

Our posts overlapped, please see my other reply in this thread. This
seems to be particular to Internet Explorer.

> If there was no syntax error in the
> ONCLICK attribute in the HTML it would be possible, after the string of
> HTML text has been parsed to create part of the DOM, to find that
> element in the DOM, examine its - onclick - property and see that its
> value is a function object and, by converting that object to a string,
> examine the code it contains, prior to any user interaction. This would
> only be possible if the onclick property's function were created prior
> to any possible user interaction with the element in the DOM.

In browsers other than IE(8?), no syntax error will be triggered until
the user clicks - OR until a script tries to access the value of
ele.onclick. This last part was news for me, too. Thanks.


- stefan

Richard Cornford

unread,
Feb 20, 2012, 8:30:44 PM2/20/12
to
Gene Wirchenko wrote:
> On Mon, 20 Feb 2012 15:47:45 -0500, Puzzled
<snip>
> For the on clause, I have a call to the function with whatever
> parameters I need. Here is one control from my experimental page:
> <input name="CliCode" id="Text" onfocus="this.select();"
> onblur="return FieldData['CliCode'].FIValidation(this);" size="3"
> maxlength="3">
<snip>

You may be interested to know (possibly even pleased) that this is the
technique that I have always considered best to associate javascript
object instances when dealing with defining intrinsic event attributes
inside javascript string values that are later parsed into DOM elements.
Not quite the way I would do it, but the same principle.

In the end mine tended to be along the lines of:-

function Constructor(){
this.index = Constructor.instances.length;
Constructor.instances[this.index] = this;
}

Constructor.instances = [];

Constructor.prototype.forOnclick = function(){
...
return false;
};

Constructor.prototype.insertElement = function(div){
div.innerHTML = '<a href"#" ' +
'onclick="return Constructor.instances[' +
this.index +
'].forOnclick()'">XXXX<\/a>';
};

The constructor function would be expected to be global available so
hanging the array of instances off the constructor function object makes
the individual instances globally available (and so available to the
intrinsic event hander code) without introducing any new names into the
global namespace.

But that was mostly in the day of Netscape 4 when messing about with
strings of HTML code was necessary to solve some types otherwise
insurmountable limitations in the browsers (in a cross browser way).
These days I would tend to use the DOM creation/manipulation methods as
they are (sufficiently) universally supported and their use makes for
more easily understood code.

> Advanced readers: "the this object" is awkward.

And ambiguous. In javascript - this - is a keyword, and has a value that
is determined at runtime by how any particular function is called. In ES
3 that value is always an object, but not necessarily in ES5 'strict
mode'.

> "this" with or
> without the quotes is confusing. Is there a better way to
> refer to
> the this object in English text?

The optimum approach is disputed, but putting quotes round it is likely
to be taken either as a quote or as a reference to a string literal
value.

Richard.

Gene Wirchenko

unread,
Feb 20, 2012, 10:05:01 PM2/20/12
to
On Tue, 21 Feb 2012 01:03:52 -0000, "Richard Cornford"
<Ric...@litotes.demon.co.uk> wrote:

>Puzzled wrote:> On Mon, 20 Feb 2012 23:17:42 +0100,

[snip]

>> This is what I'm trying to do:
>>
>> onclick = "this.some_method_identifier( arg, arg )"
>
>That is meaningless in javascript terms precisely because the value of
>the - this - keyword is not decided at this point.

Huh? Is it not going to be the control that the onclick is for?

[snip]

>Computer programming is about understand enough to take control, which
>is the antithesis of 'magic'.

Plenty of magic deals with taking control.
"One ring to rule them all..."

Sincerely,

Gene Wirchenko

Evertjan.

unread,
Feb 21, 2012, 6:33:57 AM2/21/12
to
Puzzled wrote on 20 feb 2012 in comp.lang.javascript:

> On 20 Feb 2012 20:29:51 GMT,
> "Evertjan." <exjxw.ha...@interxnl.net> wrote:
>
>>You should have the onclick js in quotes:
>>
>><div onclick="alert('a b')">click</div>
>
> I agree, though it didn't really make any difference to the
> problem.

Yes it does, because on a NGT we are not concerned with your specific
probelem that includes untold info, like "the string in x never has any
whitespace, but I did not say so".

The responses are to the group and are used by others, so quoting of
unknown strings should always be quoted in html, and even then the same
quote is not allowed to be in such string.

>>even then
>>
>><div onclick="function(){alert('a b')}">click</div>
>>
>>will not work, because this
>>
>><script type='text/javascript'>
>> function(){alert('a b')}
>></script>
>>
>>does not,
>>methinks because an anonimous function has to be compiled to be called.
>
> Could it be that your example doesn't work because it's only the
> declaration? It seems to work if there's a call as well:
>
> <script type='text/javascript'>
> var foo = function(){alert('hello')} // COMPILED
> foo() ; // CALLED
> </script>
>

Quite. That's why I set it as an example.

As I said the "anonimous function has to be compiled to be called"

Thomas 'PointedEars' Lahn

unread,
Feb 21, 2012, 6:47:19 AM2/21/12
to
Richard Cornford wrote:

> Jake Jarvis wrote:
>> On 20.02.2012 20:20, Tom de Neef wrote:
>>> Puzzled schreef:
>>>> function row( i )
>>>> {
>>>> var rec_s = '<tr><td><a href="javascript:void(0);" '+
>>>> 'id="foo'+i+'" '+
>>>> 'onclick=function(){alert('+i+')}>'+i+'</a>'+
>>>> '</td></tr>';
>>>> return rec_s ;
>>>> }
>>>
>>> This function compiles in FF and JSlint doesn't complain either.
>>
>> It's not about just compiling/passing as syntactically valid js

There is no "js".

>> program on the first level, the real problem manifests itself
>> "later", when actually clicking the resulting anchor.
>
> As you say, the real problem will manifest itself later, but that later
> will not be when anchor is clicked. […]

That depends on the host environment. Internet Explorer/MSHTML is known to
compile event-handler attribute values (and IIRC also `href' attribute
values with `javascript:' URI) when parsing the document; other layout
engines handle this differently. So the real problem may manifest itself
only if the anchor is clicked.

How a layout engine's markup parser handles invalid attribute specifications
depends on that parser as well.

Further, the current HTML5 working draft at the W3C makes delimiting quotes
or apostrophes optional with the used attribute value (in general with any
string of non-whitespace characters) [1]. So this also depends on the
markup language in which this code is used, in particular it also depends on
the version of HTML.

Of course, none of this makes the above code in any way correct or even
recommended/-able. See also <http://jibbering.com/faq/#javascriptURI>.


PointedEars
___________
[1] <http://www.w3.org/TR/html5/tokenization.html#before-attribute-value-
state>
--
When all you know is jQuery, every problem looks $(olvable).

Thomas 'PointedEars' Lahn

unread,
Feb 21, 2012, 6:58:41 AM2/21/12
to
Richard Cornford wrote:

> Puzzled wrote:> On Mon, 20 Feb 2012 23:17:42 +0100,
>> This is what I'm trying to do:
>>
>> onclick = "this.some_method_identifier( arg, arg )"
>
> That is meaningless in javascript terms precisely because the value of
> the - this - keyword is not decided at this point.

Incorrect. `this' in an event-handler *attribute* value is and always has
been a reference to the DOM object representing the element having that
attribute value.

However, issues arise if `some_method_identifier' is not a stand-in for a
built-in method of that DOM object or an object in its prototype chain. A
DOM object is a host object, and per the ECMAScript Language Specification
the algorithms of the Specification, including the `[[Put]]' and `[[Get]]'
algorithms to set and retrieve property values, respectively, do not need to
be implemented as specified. IOW:

With host objects, all bets are off.
-- (attributed to) Lasse Reichstein Nielsen

>> and should be able to grasp that when I use it in a binding,
>
> Presumably you are using "terp" as an abbreviation for interpreter.
>
> In javascript the value of the - this - keyword is (always and only)
> decided at runtime,

Which is precisely why the followed approach may work, given the right
method call.

> so the interpreter cannot know what the value will be at the time of
> tokenising/parsing/compiling the code.

It does not have to in this case.

>> I thought the proxy and the anon function were the required magic, be
>> evidently not so, so now I'm back where I started, neck deep in
>> confusion and ignorance.
>
> Computer programming is about understand enough to take control, which
> is the antithesis of 'magic'.

ACK.


PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

Richard Cornford

unread,
Feb 21, 2012, 7:14:39 AM2/21/12
to
On Feb 21, 3:05 am, Gene Wirchenko wrote:
> On Tue, 21 Feb 2012 01:03:52 -0000, Richard Cornford wrote:
>> Puzzled wrote:
> [snip]
>
>>> This is what I'm trying to do:
>
>>> onclick = "this.some_method_identifier( arg, arg )"
>
>>That is meaningless in javascript terms precisely because the
>> value of the - this - keyword is not decided at this point.
>
> Huh? Is it not going to be the control that the onclick is for?

Not necessarily, it depends on how the function is call. In response
to user interaction the browsers will reliably call the function as a
method of the DOM element with which it is associated (thus arranging
that the value of the - this - keyword is that DOM element), but it is
possible (indeed trivial) to call that function in a way that will
give the - this - keyword any value you choose. In Javascript the
value of the - this - keyword is decided (always and only) by how a
function is called.

> [snip]
>
>> Computer programming is about understand enough to take control, which
>> is the antithesis of 'magic'.
>
> Plenty of magic deals with taking control.
> "One ring to rule them all..."

Citing fiction in order to make a point about magic actually makes my
point. Fiction is as relevant to reality (which is where computer
programming goes on) as poetry or religion.

Richard.

Richard Cornford

unread,
Feb 21, 2012, 7:05:27 AM2/21/12
to
On Feb 21, 1:13 am, Stefan Weiss wrote:
> On 2012-02-21 01:34, Richard Cornford wrote:
<snip>
> You're right about the cause of the syntax error, of course,
> but I beg to differ about the rest. What the HTML parser does
> when it encounters invalid JS in an event handler attribute is
> completely up to the implementation. All it is required to do
> (if scripting is available and enabled) is register the presence
> of the onclick attribute, and leave the rest for the JS engine.
> After all, the contents of that attribute could change at any
> time, so why bother pre-parsing it.
>
> <a href="#" onclick="|-">.</a>
> <!-- in the main document HTML -->
>
> Firefox, Chrome, Opera, Safari don't blink an eye about this,
> until the user clicks the link.

Not blinking an eye is not quite the same as evidence of the creation
of the function object at the point of user interaction. The versions
of Opera and Safari that I tried (which are definitely not the latest,
so things may have changed) failed to create the event handler
function silently, in the sense of generating no syntax error reports
(which is not good). Chrome and Firefox seemed to create the function
object at the point of first access to the element's - onclick -
property, which may be before any user interaction. And that is not
such a good design either as instead of being warned about syntax
errors when the elements are created you are only going to find out
about the ones that will not work by interacting (programmatically or
by user interaction) with the handlers, which complicates testing.

I tested your proposition with:-

<html>
<head>
<title></title>

<script type="text/javascript">
window.onload = function(){
var t;
document.body.innerHTML =
'<div id="x" onclick="||alert(\'here\');"></div>';
var div = document.getElementById('x');
alert('1');
t = (typeof div.onclick);
alert('2 '+t);
div.innerHTML = t +'<br>'+ div.onclick+'<br>';
};
</script>

</head>
<body>
</body>
</html>
- where Chrome and Firefox show the error after the first alert, IE
shows the syntax error before the first alert and the Safari and Opera
versions that I tired where silent on the syntax error but reported -
typeof div.onclick - as null and undefined respectively (with clicking
on the field not resulting in any action or error, showing that they
had attempted and failed to create the function, but not making
pinning down the exact moment of attempted creation).


> Imagine my surprise when I found out that IE8
> handles it differently, and does throw a syntax error (I didn't
> have an IE9 for testing available).

Yes, it is unusual for IE to have the better design (and IE 9 is the
same as 8 in this regard), but then all they have done is left things
as they were, while at least Chrome and Firefox have tried to get
clever about it and done something stupid along the way.

Richard.

Thomas 'PointedEars' Lahn

unread,
Feb 21, 2012, 7:44:33 AM2/21/12
to
Stefan Weiss wrote:

> On 2012-02-20 23:04, Gene Wirchenko wrote:
>> Advanced readers: "the this object" is awkward. "this" with or
>> without the quotes is confusing. Is there a better way to refer to
>> the this object in English text?
>
> It is awkward. I still haven't found a good way to reduce the
> awkwardness in plain text. It's easier when you can use markup (<code>)
> or italics or a different color, but on Usenet? *shrugs* I use what
> seems appropriate at the moment. Some use "this", or |this|, or `this'.
> I think that as long as it's clear what we're talking about, we're okay.
> It's not our fault that it has °this° silly name...

One must also differentiate between the "`this' value" (in the
specification) and the "value of `this'" (in program code).

> BTW, the specs always used to refer to it as "the this value", not "the
> this object".

Correct.

> IIRC, that's because in ES3 it is possible to set |this| to a type other
> than object.

I do not see how that could be possible. While it is true that you can
specify the `this' value as not being an object reference, the value of
`this' in ECMAScript Ed. 3-conforming program code will *always* be a
reference to an object [1].

> In ES5 (strict mode only?), |this| always has to be of type object.

Incorrect; rather the reverse is true.

In ECMAScript Edition 5 strict mode function calls or execution contexts,
`this' only refers to an object (and therefore could be said to be of
Type(…) "Object") if the function is called *explicitly* as the method or
constructor of an object [2]. IOW, in any String prototype method `bar',
for "foo".bar(), `this' is the primitive String value "foo", not a reference
to the String object referred by new String("foo") that needed to be created
to call the method in the first place. [This affects primarily the result
of the `typeof' operation, as if a primitive string value is used with a
property accessor, it is being converted internally to a String instance
anyway (so you still can use `this.trim()', but it is easier to tell string
values apart, or so perhaps was the intention of Ecma TC39.]

Further, with strict mode calls, the `this' value /is/ the `undefined' value
if the base value of the Reference of the call was `undefined' or `null'
[3]. IOW, in the strict mode call bar() or strict mode function context of
`bar' ("use strict" at the start of the function body), where `bar' is a
property of the Global Object and `globalRef' is a reference to the Global
Object, `this' will only refer to the Global Object if bar is called as
globalRef.bar(). While `bar()' being resolved to `globalRef.bar()' will
cause the `this' value /to be/ the `undefined' value.

Google V8 in Chromium 16.0.912.77 (Developer Build 118311 Linux) and V8 in
18.0.1025.33 beta (Linux) are (apparently; tested only in the Script Console
as yet) not conforming regarding the latter.

> I could be mistaken about the details, but I'm too lazy to look it up now
> (it's late, and the wine was good).

It would appear to be prudent if one, in good scientific tradition,
refrained from making claims that one is unable or unwilling to
substantiate.


PointedEars
___________
[1] ECMA-262 Edition 3 Final, section 10.2
[2] ECMA-262 5.1 Edition, sections 11.2.3, 13.2.1 and 10.4.3
[3] ibid.
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f806at$ail$1$8300...@news.demon.co.uk>

Thomas 'PointedEars' Lahn

unread,
Feb 21, 2012, 7:54:33 AM2/21/12
to
Richard Cornford wrote:

> On Feb 21, 3:05 am, Gene Wirchenko wrote:
>> On Tue, 21 Feb 2012 01:03:52 -0000, Richard Cornford wrote:
>>> Puzzled wrote:
>> [snip]
>>>> This is what I'm trying to do:
>>>> onclick = "this.some_method_identifier( arg, arg )"
>>>That is meaningless in javascript terms precisely because the
>>> value of the - this - keyword is not decided at this point.
>>
>> Huh? Is it not going to be the control that the onclick is for?

It is.

> Not necessarily, it depends on how the function is call. In response
> to user interaction the browsers will reliably call the function as a
> method of the DOM element with which it is associated (thus arranging
> that the value of the - this - keyword is that DOM element), but it is
> possible (indeed trivial) to call that function in a way that will
> give the - this - keyword any value you choose. In Javascript the
> value of the - this - keyword is decided (always and only) by how a
> function is called.

I do not see your point, and it appears you are preaching to the choir. If
that is an event-handler attribute value, then the OP is correct. The way
the function named `some_method_identifier' is called is *there*, in the
attribute value. There is no ambiguity (host object issues aside) about the
*initial* `this' value in the context of that method (if it is callable).

>> [snip]
>>
>>> Computer programming is about understand enough to take control, which
>>> is the antithesis of 'magic'.
>>
>> Plenty of magic deals with taking control.
>> "One ring to rule them all..."
>
> Citing fiction in order to make a point about magic actually makes my
> point. Fiction is as relevant to reality (which is where computer
> programming goes on) as poetry or religion.

That depends on whether that fiction is pure fantasy or based on scientific
thought. Consider Star Trek (not the reboot), for example. (It is not by
pure coincidence that I have a smartphone powered by an operating system
named *Android*.)


PointedEars
--
Sometimes, what you learn is wrong. If those wrong ideas are close to the
root of the knowledge tree you build on a particular subject, pruning the
bad branches can sometimes cause the whole tree to collapse.
-- Mike Duffy in cljs, <news:Xns9FB6521286...@94.75.214.39>
Message has been deleted

John G Harris

unread,
Feb 21, 2012, 10:59:24 AM2/21/12
to
On Tue, 21 Feb 2012 at 12:47:19, in comp.lang.javascript, Thomas
'PointedEars' Lahn wrote:
>Richard Cornford wrote:
>
>> Jake Jarvis wrote:
>>> On 20.02.2012 20:20, Tom de Neef wrote:
>>>> Puzzled schreef:
>>>>> function row( i )
>>>>> {
>>>>> var rec_s = '<tr><td><a href="javascript:void(0);" '+
>>>>> 'id="foo'+i+'" '+
>>>>> 'onclick=function(){alert('+i+')}>'+i+'</a>'+
>>>>> '</td></tr>';
>>>>> return rec_s ;
>>>>> }
>>>>
>>>> This function compiles in FF and JSlint doesn't complain either.
>>>
>>> It's not about just compiling/passing as syntactically valid js
>
>There is no "js".
<snip>

It isn't ECMA 262 that says the value of an intrinsic event attribute
must be a statement. Richard has invented the generic name "js" for the
sub-languages that do say.

Therefore there *is* now a "js".

John
--
John Harris

Gene Wirchenko

unread,
Feb 21, 2012, 1:17:48 PM2/21/12
to
On Tue, 21 Feb 2012 04:14:39 -0800 (PST), Richard Cornford
<Ric...@litotes.demon.co.uk> wrote:

>On Feb 21, 3:05 am, Gene Wirchenko wrote:
>> On Tue, 21 Feb 2012 01:03:52 -0000, Richard Cornford wrote:
>>> Puzzled wrote:
>> [snip]
>>
>>>> This is what I'm trying to do:
>>
>>>> onclick = "this.some_method_identifier( arg, arg )"
>>
>>>That is meaningless in javascript terms precisely because the
>>> value of the - this - keyword is not decided at this point.
>>
>> Huh? Is it not going to be the control that the onclick is for?
>
>Not necessarily, it depends on how the function is call. In response

Which was specified in the example above. Is there any case in
JavaScript where the value for this used in an onclick is other than
the control of the onclick?

>to user interaction the browsers will reliably call the function as a
>method of the DOM element with which it is associated (thus arranging
>that the value of the - this - keyword is that DOM element), but it is
>possible (indeed trivial) to call that function in a way that will
>give the - this - keyword any value you choose. In Javascript the
>value of the - this - keyword is decided (always and only) by how a
>function is called.
>
>> [snip]
>>
>>> Computer programming is about understand enough to take control, which
>>> is the antithesis of 'magic'.
>>
>> Plenty of magic deals with taking control.
>> "One ring to rule them all..."
>
>Citing fiction in order to make a point about magic actually makes my
>point. Fiction is as relevant to reality (which is where computer
>programming goes on) as poetry or religion.

*You* brought up magic.

Sincerely,

Gene Wirchenko

Scott Sauyet

unread,
Feb 21, 2012, 2:14:17 PM2/21/12
to
Puzzled wrote:
> Stefan Weiss wrote:
>> Hope this gets you on the right track.
>
> It did, and *many* thanks for that.
>
> At first I resisted accepting what you were obliquely telling me
> because I found it too hideous to contemplate.  But after downing
> a pint of whisky (no, not really) I relaxed enough to think about
> it.  It's still eye-wateringly hideous, but I've always been able
> to accept reality when I've no other choice.

I still say that this is the only good time to accept reality! Don't
do so if you have any choice.

> To me, the key concepts here are
>
> a) js is at best pseudo-oo because it doesn't maintain under all
> circumstances the defining oo relationship:  that of the object
> instance to its properties.

Javascript can certainly be used as an OO language. The fact that it
uses prototypal rather than classical inheritance is the main
difference between it and more mainstream OO languages.

But it is not an OO-only language in the way that, say, Java or C# are
OO languages. I often use it more as a functional language.

I think what you're reacting to is the fact that functions are first-
class objects. Although they can be used as object methods, they are
not simply object methods. I'm afraid you won't get much support here
that this is horrible. I imagine many other regulars would agree with
me that this is one of the best features of the language.


> b) a within-element event "binding" remains, at least in effect,
> nothing but a string until source-interpreted ...

When you say "within-element", you are confusing two different
languages. Javascript can be embedded within HTML, and that is in
essence what you're doing with code like this. There are various ways
to bind event handlers to document nodes. When you do it in markup
like this, you have to live with the restriction that markup is just
text to be interpreted. There are many alternatives. One is
demonstrated at

<http://jsfiddle.net/CrossEye/wxQ2K/>

(I didn't understand your requirements well enough to try to use your
terminology, but this should show the ideas.)

>(eeeuw, shades of lisp and apl)

Yahoo, shades of SCHEME and LISP! :-)

> ... during the lookup process that determines who
> should service the current event.  It's that choice --to delay
> the binding until the object relationship has been lost-- that
> makes js a pseudo-oo language.

Again, this seems to be a confusion between the JS and the HTML. You
are creating some HTML representing elements to be added to the
document. Your Javascript has been left behind at this point.


> So, the solution (in my case at least) is to maintain within each
> instance the name of the instance and substitute it as the
> self-ref for within-element bindings, e.g.
>
> var foo = constr('foo'...
> function constr( selfid,...)
> { this.InstName = selfid ; this.click_esr = cesr ; }
> function cesr( j ) {...}
>
> <a .... onclick="'+this.InstName+'.click_esr('+i+...');">'+...

That's one way, but there are so many alternatives. If you're
generating the elements within code (rather than generating markup
that the HTML engine must interpret to make elements) then there are
much more elegant techniques.


> Thanks to everyone who tried to explain to me the full
> horribleness of what's going on.

You may find that Javascript is not to your liking, but you're not
likely to get too much sympathy in comp.lang.javascript for the notion
that the language is horrible. ;-)

-- Scott

Scott Sauyet

unread,
Feb 21, 2012, 2:57:25 PM2/21/12
to
Gene Wirchenko wrote:
> Is there any case in JavaScript where the value for this used in
> an onclick is other than the control of the onclick?

Yes:

<a id="droid" onclick="alert(this); return false;">Obi-Wan</a>

document.getElementById("droid").onclick.call({
toString: function() {
return "This is not the link you are looking for";
}
});

-- Scott

Stefan Weiss

unread,
Feb 21, 2012, 4:31:44 PM2/21/12
to
On 2012-02-21 13:44, Thomas 'PointedEars' Lahn wrote:
> Stefan Weiss wrote:
>> IIRC, that's because in ES3 it is possible to set |this| to a type other
>> than object.
>
> I do not see how that could be possible. While it is true that you can
> specify the `this' value as not being an object reference, the value of
> `this' in ECMAScript Ed. 3-conforming program code will *always* be a
> reference to an object [1].

You're right, I got that switched around.

>> I could be mistaken about the details, but I'm too lazy to look it up now
>> (it's late, and the wine was good).
>
> It would appear to be prudent if one, in good scientific tradition,
> refrained from making claims that one is unable or unwilling to
> substantiate.

Where do you think you are, the Royal Society? A simple correction would
have been enough, but you chose to ignore four hints at uncertainty
("IIRC"; "could be mistaken"; didn't look it up; had wine) to
pontificate about scientific tradition. Get a life.

- stefan

Gene Wirchenko

unread,
Feb 21, 2012, 4:39:57 PM2/21/12
to
I do not understand how that answers my question. The only this
reference that I see is in the onclick, and would that not refer to
the anchor?

If I understand the second bit correctly, you are changing the
behaviour of the onclick (I am not sure of this), but I do not see
that you are changing the this value.

Sincerely,

Gene Wirchenko

Thomas 'PointedEars' Lahn

unread,
Feb 22, 2012, 4:55:36 AM2/22/12
to
I daresay you would not have corrected yourself later. If I had not taken
the time for a correction, and nobody else would have tested or corrected
you, the false claim would still be there. Making such claims is ultimately
harmful, in particular for beginners, and should be avoided.

It is particularly illogical of you to make such a claim on the grounds of
unwillingness ("lazy") or an unfit condition ("the wine was good"). For you
can make *and* substantiate the claim *later* when you are willing and fit
for an answer (no matter if the reasoning for the claim turns out to be
correct or not).


PointedEars

Scott Sauyet

unread,
Feb 22, 2012, 8:07:32 AM2/22/12
to
Gene Wirchenko wrote:
> Scott Sauyet wrote:
>> Gene Wirchenko wrote:
>>> Is there any case in JavaScript where the value for this used in
>>> an onclick is other than the control of the onclick?
>>
>>  <a id="droid" onclick="alert(this); return false;">Obi-Wan</a>
>
>>  document.getElementById("droid").onclick.call({
>>    toString: function() {
>>      return "This is not the link you are looking for";
>>    }
>>  });
>
>      I do not understand how that answers my question.  The only this
> reference that I see is in the onclick, and would that not refer to
> the anchor?

It would when you click the anchor. The Javascript engine creates a
DOM click event and fires it in the context of the anchor element.
But that same function can be called in another manner as I was
attempting to demonstrate.

>      If I understand the second bit correctly, you are changing the
> behaviour of the onclick (I am not sure of this), but I do not see
> that you are changing the this value.

Breaking it down a little, we might do

  var anchor = document.getElementById("droid");

which I assume you recognize as selecting the element in the document
with the ID of "droid", and assigning the `anchor` reference that
value.

Then we fetch the onclick property of that element:

var onclickFunction = anchor.onclick;

This property is a function, created at some point by the Javascript
engine out of the text "alert(this); return false;". We now have a
free-standing reference to that function.

We construct an object with only a single property, `toString`, a
simple function:

var myObj = {toString: function() {return "This is not ...";}};

Finally, we invoke the function using `call`, which accepts as the
first parameter the object to be used as `this`:

onClickFunction.call(myObj);

(If you haven't seen `call` or its sibling, `apply`, you should
probably look them up [1, 2] as they are part of what gives Javascript
its expressive power.)

Stringing these all together without the intermediate variables, we
get back to the code above. You can see this in action at

<http://jsfiddle.net/CrossEye/AthGj/>

When you click the link, the system will alert the toString
representation of the link, which in most (all?) browsers is the link
target. When you click the button, you run the code we've been
discussing, and it runs the same function, but with the object in
question being our little object, and alerts "This is not the link
you're looking for".

Javascript is a multi-paradigm language, but some of its best
features, IMHO, are its functional-programming ones. The onclick
function that is a property of that link element is not simply a
method of that element. It is a function that can be reused in many
contexts.

-- Scott

[1] https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call
[2] https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

John G Harris

unread,
Feb 22, 2012, 10:58:53 AM2/22/12
to
On Wed, 22 Feb 2012 at 10:55:36, in comp.lang.javascript, Thomas
'PointedEars' Lahn wrote:

<snip>
>I daresay you would not have corrected yourself later. If I had not taken
>the time for a correction, and nobody else would have tested or corrected
>you, the false claim would still be there. Making such claims is ultimately
>harmful, in particular for beginners, and should be avoided.
<snip>

Here, here! That's why I so often correct unjustified statements.

John
--
John Harris
0 new messages