views:

230

answers:

1

I'm trying to use jQuery to dynamically create an image map, and I ran into a weird behavior:

alert( $('<area />').size() );                         // 1
alert( $('<area shape="circle" />').size() );          // 0
alert( $('<area />').attr("shape", "circle").size() ); // 1

In other words, I can't create an area tag all at once; if I say

$('<area shape="circle" coords="50,25,4" href="#" alt="foo" />')

then nothing is created. However, it works if I do it gradually, e.g.

$('<area />')
    .attr("shape", "circle")
    .attr("coords", "50,25,4")
    .attr("href", "#")
    .attr("alt", "foo");

I have no idea why this is, because I can create all kinds of other elements with attributes and content, e.g.

$('<div id="foo" />')
$('<div id="bar">Hello World!</div>')

so I'm not clear on why this isn't working. This isn't all that important since I can make it wirk by chaining calls to attr, but that's annoying and I'd like to understand this behavior.

+3  A: 

An <area /> element is only defined inside an image map (i.e. <map> element). So essentially the following is failing (as this is what jQuery is doing with your markup):

var div = document.createElement('div');
div.innerHTML = '<area shape="circle" coords="50,25,4" href="#" alt="foo" />';
return div.childNodes; // this is empty, as the browser didn't allow 
                       // the <area /> element inside the <div> element

It's just one of those things obviously the great jQuery has not accounted for (yet). In the meantime try:

var $area = $(
    '<map><area shape="circle" coords="50,25,4" href="#" alt="foo" /></map>'
).contents();

// $area is the jQuery object for the newly created <area /> tag

$area.attr('coords'); // "50,25,4"

// etc
Crescent Fresh
+1 don't expect jQuery to always do the right thing, regardless of what its incessant boosters here at SO say.
bobince
If he tried to append `$area` (since it only has the contents) it won't include the `<map>`, so why not just wrap the `$area` with a map tag before appending?
fudgey
@fudgey: because a `<map>` can contain multiple `<area />` elements.
Crescent Fresh