A problem a decade in the making
You can refer to a form’s elements in your code by using the element’s name (from the NAME attribute)
— an ancient Javascript spec.
This means myForm.myElement
is a shortcut for myForm.elements['myElement']
. I’m sure this was seen as handy and harmless at the time, but the problem is that references to form elements, simply by using valid name attributes, can overwrite important DOM properties and methods on the form element. Make a text input with name=”submit” and you overwrite the form’s native submit method; no more form submission!
Workaround
Effectively, you have to avoid using name
s that already exist as properties or methods of the form DOM element, from modern specs back to the stone age. To get an idea of how many there are, I created an empty form element with no attributes, fired up the Javascript shell bookmarklet and used its handy props
function:
Methods: addEventListener, addRepetitionBlock, addRepetitionBlockByIndex, appendChild, attachEvent, blur, checkValidity, cloneNode, contains, detachEvent, dispatchEvent, dispatchFormChange, dispatchFormInput, focus, getAttribute, getAttributeNS, getAttributeNode, getAttributeNodeNS, getElementsByTagName, getElementsByTagNameNS, getFeature, hasAttribute, hasAttributeNS, hasAttributes, hasChildNodes, insertAdjacentElement, insertAdjacentHTML, insertAdjacentText, insertBefore, isDefaultNamespace, isSupported, item, lookupNamespaceURI, lookupPrefix, moveRepetitionBlock, namedItem, normalize, removeAttribute, removeAttributeNS, removeAttributeNode, removeChild, removeEventListener, removeNode, removeRepetitionBlock, replaceChild, reset, resetFromData, scrollIntoView, selectNodes, selectSingleNode, setAttribute, setAttributeNS, setAttributeNode, setAttributeNodeNS, submit, toString
Fields: accept, acceptCharset, action, all, attributes, childNodes, children, className, clientHeight, clientLeft, clientTop, clientWidth, contentEditable, currentStyle, data, dir, document, elements, encoding, enctype, firstChild, id, innerHTML, innerText, isContentEditable, lang, lastChild, length, localName, method, name, namespaceURI, nextSibling, nodeName, nodeType, nodeValue, offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth, onblur, onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup, onload, onmousedown, onmousemove, onmouseout, onmouseover, onmouseup, onunload, outerHTML, outerText, ownerDocument, parentElement, parentNode, prefix, previousSibling, repeatMax, repeatMin, repeatStart, repetitionBlocks, repetitionIndex, repetitionTemplate, repetitionType, replace, scrollHeight, scrollLeft, scrollTop, scrollWidth, sourceIndex, style, tagName, target, templateElements, text, textContent, title, unselectable
These are just in Opera; to be really safe you need to add in any extras from all the other modern browsers.
But there’s more
This problem also exists on the document
object: Give your form name="getElementById"
, then try using document.getElementById()
. Even worse, IE/win registers all element id
s onto the global (window
) object.
The real solution
The W3C/WhatWG needs to step up and formally denounce these shortcuts in the HTML DOM specs, and, IMO, also generate warnings in the HTML validator where input names match those in W3C DOM specs, at the very least. Since there’s a sea of legacy code out there using these shortcuts, browser makers desperately need a defined way to handle these collisions.