Re: Element.create(): a proposal for more convenient element creation

On 8/4/11, Jonas Sicking <jonas@sicking.cc> wrote:
> On Wed, Aug 3, 2011 at 8:10 AM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>> On Wed, Aug 3, 2011 at 12:34 AM, Anne van Kesteren <annevk@opera.com>
>> wrote:
>>> On Tue, 02 Aug 2011 20:31:04 +0200, Tab Atkins Jr. <jackalmage@gmail.com>
>>> wrote:
>>>> On Tue, Aug 2, 2011 at 11:26 AM, Glenn Maynard <glenn@zewt.org> wrote:
>>>>> On Tue, Aug 2, 2011 at 2:18 PM, Tab Atkins Jr. <jackalmage@gmail.com>
>>>>> wrote:
>>>>>> MooTools is basically identical to Prototype, except that you can
>>>>>> additionally set listeners on the element during creation by using a
>>>>>> magical "events" property in the attribute bag, which takes an object
>>>>>> of event names and functions.  This would be nice to look into adding.
>>>>>
>>>>> Is this much better than just saying eg. Element.create("a", {href:
>>>>> "http://link", onclick: function(e) { ... } }, "link"}?
>>>>
>>>> Hmm, is everything exposed as on* attributes now?  If so, then yeah,
>>>> just do that; no need to mess around with a magic property in the
>>>> attributes bag.
>>>
>>> This would still be magical as it is setting an IDL attribute rather than
>>> a
>>> content attribute.
>>
>> Hmm.  onclick is a content attribute, no?  Or do you just mean that
>> assigning a function directly (rather than a string of code) is
>> something that can only be done via an IDL attribute?
>>
There is an event handler attribute named onclick. There is an event
handler property named onclick. Setting the property does not set the
attribute. Setting the attribute results in the creation of a function
with the value of that attribute as its FunctionBody and an augmented
scope chain. When the attribute is set, the property gets that
browser-generated function function.

The scope of handler attributes is explained in HTML 5, though incompletely:
http://dev.w3.org/html5/spec/Overview.html#event-handler-content-attributes
That's incomplete.

The scope chain of an event handler attribute for a form control would
function as so:

| <input type="text" onclick="alert([form, type]);" value="test">

function anonymous() {
  with(document) {
    with(this.form) {
      with(this) {
       alert([form, type]);
      }
    }
  }
};

Or alternatively:
  document.forms[0].elements[0].setAttribute("onclick", "alert(form, type])");

Result:
  "[object HTMLFormElement],text"

Setting the property does not change the attribute. They're two
different things.

>> If so, then good point, but I also expect that this wouldn't be very
>> confusing.
>
I can see why you'd say that, but the fact is that attributes and
properties are different things.

If you take good care not to assign ID and NAME like "form" or "body"
(yeah, Google doesn't really heed that rule very well), you might not
see too many problems. And if you never ever use event handler
attributes, you won't get stung by scope augmentation bugs.

I wrote an article on this but Jim's server is perpetually down (as is
my site now). "Unsafe Names for Form Controls". Google cache:
http://webcache.googleusercontent.com/search?q=cache:VLOWitVtytgJ:www.jibbering.com/faq/names/event_handler.html+%22Event+Handler+Scope%22+jibbering&cd=1&hl=en&ct=clnk&gl=us&client=safari&source=www.google.com

See also:
http://code.google.com/p/chromium/issues/detail?id=80911&q=bzbarsky&colspec=ID%20Stars%20Pri%20Area%20Feature%20Type%20Status%20Summary%20Modified%20Owner%20Mstone%20OS

Though also explained many many years ago by Cornford on c.l.js.

> It would seem very inconsistent if some attributes are set using
> elem.setAttribute and others using elem.foo=bar.

Yeah, inconsistent. Sounds like jQuery.

Would you make the
> distinction based on that the attribute name starts with "on"?
>
I'm pretty sure Jonas would not do that.

> One possible solution would be to be able to specify event handler
> attributes in a second object, so something like:
>
> Element.create("a", { href: "..." }, { onclick: function(e) { ... } },
> "link", anotherChild);
>

The scope augmentation that goes along with the event handler
attribute is undesirable here.
-- 
Garrett

Received on Friday, 5 August 2011 05:46:08 UTC