Re: [DOM4]: Element.create

Hi Charles,

I see some specific problems with both the Element.create and 
JSON.toNode proposals, but in general I think that blessing one JSON 
representation of the DOM over all others is a bad idea.

Also, it is fairly trivial to roll your own solution (or three) so I 
imagine this feature won't ever be a high priority item.

Here's a (non-robust) solution off the top of my head. I'm sure you have 
an alternative approach that works better for you. This merely 
highlights that this sort of syntax sugar shouldn't be in the DOM core.

var $ = { // WARN this API is for demo purposes only
F: function(nodes) { // create a document Fragment and append nodes 
(which is an array)
     var frag = document.createDocumentFragment();
     nodes.forEach(function(node) {
         if (typeof node === "string") node = document.createTextNode(node);
         frag.appendChild(node);
     });
     return frag;
},
E: function(tagName, attrs, nodes) { // create an Element with attrs and 
child nodes (if present)
     var el = document.createElement(tagName);
     if (attrs) for (var name in attrs) el.setAttribute(name, attrs[name]);
     if (nodes) el.appendChild(this.F(nodes));
     return el;
}
}

An example of usage:

To create '<div class="greeting">Hello <b 
class="target">World</b>!</div> ' and retain references to the <div> and 
<b> elements:

var greeting, target, frag = $.F([
     greeting = $.E("div", {"class": "greeting"}, [
         "Hello ",
         target = $.E("b", {"class": "target"}, [
             "World"
         ]),
         "!"
     ])
]);
greeting.onclick = function() { alert("Hi"); }
target.onclick = function() { alert("I am the World"); }


Some inline comments below.


On 2/10/11 7:54 AM, Charles Pritchard wrote:
> On 10/1/11 6:48 AM, Sean Hogan wrote:
>> On 1/10/11 12:15 PM, Charles Pritchard wrote:
>>
>>> var myDiv = JSON.toNode({div: 'Hello World'});
>>> myDiv.outerHTML == '<div>Hello World</div>';
>>>
>>
>> what would the following result in?
>>
>>     var myFrag1 = JSON.toNode({b: "Hello", i: "World"});
>>
>>     var myFrag2 = JSON.toNode({b: "Hello", b: "World"});
>>
> myFrag1.outerHTML == '<b>Hello</b><i>World</i>'; // could be <i> then 
> <b> as well.

JSON.toNode() can't return two nodes. Are you implying that it would 
return a DocumentFragment in this instance?

> myFrag2.outerHTML == '<b>World</b>';
>

Would myFrag2 be a DocumentFragment or Element?

>
>>
>> how would I create equivalents of the following?
>>
>> <div>Hello <b>World</b>!</div>
>
> {div: ['Hello', {b: 'World'}, '!']};
>
>>
>> <div class="greeting">Hello <b class="target">World</b>!</div>
>>
>
> JSON.toNode({div: ['Hello', {b: 'World'}, '!']}).className = 'greeting';

Okay, I see that the object syntax {b: 'Hello', i: 'World'} wouldn't be 
the preferred way to insert multiple sibling elements. In that case it 
shouldn't be supported at all.

>
> No quick route to b class = "target".
>
> This is just the usual DOM work:
>
> var greeting = JSON.toNode({div: ['Hello', '!']});
> greeting.className = 'greeting';
> var target = JSON.toNode({b: 'World'});
> target.className = 'target';
> greeting.firstChild.nextSibling.appendChild(target);
>
> ...
>
>
> The purpose of this work is to do less string manipulation in JS.
>
> Consider these two methods:
> JSON.toNode({div: [start, {b: middle}, end]}).className = myGreeting;
> parent.innerHTML = ['<div class="',myGreeting, '">', start, 
> '<b>',middle,'</b>',end].join('');
>
> Node is a bit of a misnomer if attributes and class names are involved,
> as those are part of Element.
>
> This is just an alternative idea for attaching the Element.create 
> method we've been discussing.
>
> http://www.w3.org/TR/dom/#element
> http://dev.w3.org/2006/webapi/WebIDL/#idl-object
>
> -Charles
>

Received on Sunday, 2 October 2011 12:01:23 UTC