Cross-Browser JavaScript: Creating DOM Nodes That Set The name Property
Creating and appending DOM nodes to a form can be tricky. Internet Explorer needs special care when you create a DOM node and then set the name property. This handy JavaScript gets around these cross browser issues efficiently, and without browser detection.
Web browsers have come a long way. We can create Document Object Model nodes at will using the universally supported document.createElement
function, then you try creating form fields in Internet Explorer and
you hit a snag.
Form fields, in order to be useful, need a name
attribute in HTML. In JavaScript, you set the name
property. It's two simple lines of code. Nothing special. No hoops to
jump through:
// Create a new form input to hold a first name:
var el = document.createElement("input");
el.name = "fname";
You append this new input
to your form
and then try to access it using the form.elements.field_name
syntax and you can't find the "fname"
field. Turns out, Internet Explorer requires a
little fudging:
// Create a new form input for Internet Explorer:
var el = document.createElement("<input name=fname>");
In one fell swoop, you must create the new element AND assign
the name
property before Internet Explorer
will append this element to the form's document object model, making it available through the form.elements.field_name
syntax. The
problem is, standards compliant browsers, i.e. "every other browser
developed within the last 8 years," will throw a JavaScript error if
they try executing that code.
You could try browser detection, which usually involves
parsing the user agent string of the browser. Most browsers allow you
to change the user agent string, so this is no longer a viable method.
Plus, what do you do when a new browser or browser version comes out?
You'd have to change your function. Turns out, a simple try-catch
block is the answer.
Creating a named DOM node the coss browser way
We can create our own createElement
function to account for the difference in Internet Explorer's
implementation of document.createElement
:
It works fine and dandy. Every time you call the function, it
tries doing it Internet Explorer's way, but you take a performance hit
because of the try-catch
block that executes
every time the createElement
function
executes. With a little runtime retooling, we can get around this using
three functions instead of one:
When the page first loads, you've got three functions. The createElement
function, which is what you will always
use, has a try-catch
block that calls two
other functions. The createElementMsie
function attempts to create the new DOM node using Internet Explorer's
implementation. If the function call succeeds, the createElement
function is reassigned to be the createElementMsie
function. All subsequent calls to createElement
will run the code in createElementMsie
.
In the catch
clause, the browser has
failed to execute createElementMsie
, and
therefore doesn't support Internet Explorer's implementation of document.createElement
.
Here we assume it is a standards compliant browser and doesn't need any
hand holding. It calls createElementStandard
,
and when that succeeds it reassigns the createElement
function to be the createElementStandard
function. All subsequent calls to createElement
run the code in createElementStandard
.
You still take a performance hit with these three functions
because the try-catch
block is executed, but
only for the first time you call createElement. From the
second time you call createElement
onwards,
it directly executes the code the browser supports. The try-catch
block doesn't exist anymore, and you've gotten around Internet
Explorer's faulty implementation of the document.createElement
function. You can now create form fields at will and feel safe in
knowing Internet Explorer will actually send those field values to the
server when the form is submitted.
Using createElement:
var el = createElement("input", "fname");
// append the new INPUT to the form.