Get multivariate by the name attribute--
getElementsByName
Standard
- DOM 1 is defined in
HTMLDocument
Interface, and NodeList getElementsByName(in DOMString elementName)
the method does not throw any exceptions.
- DOM 2 is still defined in, the prototype remains the
HTMLDocument
same, but the new description searches for all elements in the HTML4.0, while the XHTML 1.0 search scope shrinks to form elements
- Dom 3 does not have the standard DOM HTML, Lineage Dom 2 (Dom 3 has
Document
the DOM core standard, but HTMLDocument
belongs to DOM HTML instead of Dom core)
- WHATWG in the DOM HTML standard instead of
Document
another ' HTMLDocument, the prototype is the same
- HTML5 and WHATWG are basically consistent
Watch out.
name
and id
different, can be repeated, so the method name has "S", and the return isNodeList
- This method returns a "Live"
NodeList
, and when the page element changes, the call to get again NodeList
will follow the update.
- When there is no element that meets the requirements, the returned
null
is not an emptyNodeList
name
There are two types of elements, one is already in the IDL of the element, and the other is just the property of the name name
( Attr
)
- Some browsers also provide a
document.name
way to get the name
element name directly, but this feature does not appear in the standard, and some new browsers do not support this approach, so it is best not to use
Compatibility
ie9-only the elements that are allowed with name in HTML4 (in other words, only the elements that are in IDL name
). But they also have a bug: Count the same element with any ID as the name you are searching for.
Check
<!DOCTYPE HTML><HTMLLang= "en"><Head> <MetaCharSet= "UTF-8"> <title>Document</title></Head><Body> <DivID= "Foo"></Div> <aname= "Bar"></a> <Divname= "Baz"></Div></Body></HTML>
IE 9-Next:
document.getElementsByName(‘baz‘).length
Returns 0 (because the div in HTML 4 cannot take name)
document.getElementsByName(‘foo‘).length
Returns 1 (the div that does not have the name but the ID and the name of the query in HTML 4)
document.getElementsByName(‘bar‘).length
Returns 1, which is normal behavior.
FireFox and Chrome return 1,0,1, which allows any element with name and does not confuse the ID with name.
Therefore, in IE 9, the elements obtained using this method may also need to be elem.name == name
filtered.
In addition, some versions of IE return are not, NodeList
HTMLCollection
but because of HTMLCollection
compatibility NodeList
, so there is no major impediment.
Other
In Dom HTML, name
only in the IDL of some element (which IDL has attribute domstring name can be seen in DOM Level 2 and WHATWG, or reference HTML4 DTD), while the other elements is actually a property that is implemented as an ordinary Attr
Node instead of the element IDL itself NamedNodeMap
(see Dom 3 and WHATWG). Therefore, the elements that are not in IDL name
cannot be elem.name
obtained directly name
, but getAttribute
can be obtained by using them. For example:
<!DOCTYPE HTML><HTMLLang= "en"><Head> <MetaCharSet= "UTF-8"> <title>Document</title></Head><Body> <Divname= "Baz"></Div> <aname= "Bar"></a></Body></HTML>
In the console:
var div = document.getelementsbyname (' baz ') [0// undefined// Baz var a = document.getelementsbyname (' bar ') [0// bar// Bar
Webkit Code Analysis
Document
Inheritance ContainerNode
(see Webcore/dom/document.h), which is essentially ContainerNode
used getElementsByName
.
containernode
getelementsbyname
use namenodelist
as Nodelistsnodedata::addcachewithatomicname<> template specialization for
(see webcore/dom/ ContainerNode.cpp). Note the template for nodelistsnodedata::addcachewithatomicname<>
improves code reuse--only the class defined for template specialization Create
, elementmatches
, and so on, you can use Addcachewithatomicname
to implement live nodelist filtering + Cache. WebKit all of these functions in the Cachedlivenodelist
class, so long as the class is inherited and the virtual function it inherits is implemented, it can be used for Addcachewithatomicname Template specialization for
(see WEBCORE/DOM/LIVENODELIST.H), creating a nodelist with cache and specific filtering criteria.
NodeListsNodeData
Use a private NodeListAtomicNameCacheMap
member to m_atomicNameCaches
implement the cache. When addCacheWithAtomicName
called, first check if the corresponding cache already exists, if present, with m_atomicNameCaches.fastAdd
a quick update (see WEBCORE/DOM/NODERAREDATA.H (note NodeListAtomicNameCacheMap
essentially a hash map, see typedef definition). If there is no cache, call the template class's create
function to create a new template class object and return it here NameNodeList
.
NamedNodeList
Inherited CachedLiveNodeList
, CachedLiveNodeList
used by iterators collectionBegin()
, collectionTraverseForward()
etc. (see WEBCORE/DOM/LIVENODELIST.H) will traverse the descendants of root node that need to be filtered, using virtual function elementMatches
filtering (see Webcore/ dom/livenodelist.h). NamedNodeList
implemented elementMatches
as a element.getNameAttribute() == m_name
filtering standard (see WEBCORE/DOM/NAMENODELIST.H).
It is important to note thatCachedLiveNodeList
OfelementMatches
FromLiveNodeList
Inherited, and inLiveNodeList
In the prototypeelementMatches
The prototype isvirtual bool elementMatches(Element&) const = 0
--Just a virtual function that does not require inline (see webcore/dom/livenodelist.h), butNamedNodeList
Implementation of this function is inline. It is well known that the call of a virtual function is expensive to look up a table, which is obviously not possible for a function that is called by a high frequency, which is actually bypassing this overhead through inline. Note that the condition that virtual does not conflict with inline is that the compiler needs to know at compile time what class the virtual function does inline (not as normal virtual calls can be determined at runtime), andCachedLiveNodeList
Usually callelementMatches
Place will have similarauto& nodeList = static_cast<const NodeListType&>(*this)
Statement uses a template to determine its own static type, and then use this to determine a reference to a static type instead ofthis
To invokeelementMatches
, so there is no conflict (this notation is named curiously recurring Template Pattern, which enables the so-called static polymorphism to bypass the overhead of virtual function calls and the purpose of virtual function calls). This way around a big bend (using the template) to add inline for the virtual function is usually for performance reasons, see the StackOverflow on the relevant issues, here just fits the application scenario--elementMatches
are destined to be frequently called. After allgetElementsByName
Will often be directly indocument
, it iterates through all the nodes in the document, each one of which is called once.elementMatches
To filter, which is usually at least hundreds or thousands of calls ... In the same way,ElementDescendantIterator
Almost all of the methods (including constructors) are inline because it is frequently called as a traversal unit, so the inline is required to squeeze dry performance (see Webcore/dom/elementdescendantiterator.h
Other notable points:
- WebKit is to set and determine whether an element has an attribute (for example) by doing a bitwise operation on a well-defined flag
name
, using a 32-bit integer to ElementData
hold the array length and flag (see webcore/dom/ ELEMENTDATA.H, this saves space and time, and is able to treat IDL-defined attributes and custom attributes equally.
Node
is also known by pre-defined flag-bit operations (instead of using C + + expensive rtti), the definition of flag is described in webcore/dom/node.h
- In addition
name
, for the elements contained in IDL, WebKit is actually wrapped one element.getNameAttribute
to return name
, for example, <a>
see Webcore/html/htmlanchorelement.cpp. Therefore NamedNodeList
element.getNameAttribute()
, either name
in IDL or as its own property will be returned, reflected in the upper level is getElementsByName()
also not need to control name
whether in IDL.
Follow the standard and WebKit source to explore DOM--get the getelementsbyname of the element