jQuery delivers inconsistent results with
[name="name"] selectors because of optimization-driven dependence upon un-normalized results from
document.getElementsByName (defined in DOM Level 2), whose behavior in Internet Explorer differs between "quirks" and "standards" modes (in "quirks" mode, the method will only return form controls: elements with tag names like
SELECT/etc.). Specifically, calls to
jQuery with default/document scope will fail to include non-form controls on IE ''if and only if'' there is no DOCTYPE declaration and there are form controls that also match the selector.
Chrome, Firefox, and Safari do not limit the potential set of matching elements for
document.getElementsByName regardless of DOCTYPE, and so do not exhibit this bug.
I've created demonstration pages for both no DOCTYPE and simple DOCTYPE cases. Expected behavior is for the following expressions to always return all elements with a matching
name attribute, but observed behavior is that the simplest one returns only form controls when the browser is IE and there is no DOCTYPE declaration and there is at least one form control that matches the selector.
Note that scoping to
document.body would also avoid this bug because
getElementsByName is only defined on the
document level (see below for relevance), but unfortunately jQuery's
has method is implemented with precisely the kind of unscoped call to jQuery that is problematic.
A possible fix would be something like
jQuery.support.getByName (true if
document.getElementsByName can return elements of any tag name) and corresponding tweaking of
Sizzle.selectors.find.NAME (accessed in Sizzle.find as
Expr.find[ type ] at line 4129 of the uncompressed jQuery-1.7.js) to always return null when getElementsByName is restricted. That is already the return value now when context is not a document, or when context is a document but
getElementsByName returns an empty list, making this a very minor change.
Such a fix would add fewer than 100 bytes.