Follow the standard and WebKit source to explore DOM--get the getelementsbyname of the element

Source: Internet
Author: User

Get multivariate by the name attribute-- getElementsByNameStandard
    • 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.
    • nameand 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
    • nameThere 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‘).lengthReturns 0 (because the div in HTML 4 cannot take name)
    • document.getElementsByName(‘foo‘).lengthReturns 1 (the div that does not have the name but the ID and the name of the query in HTML 4)
    • document.getElementsByName(‘bar‘).lengthReturns 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

DocumentInheritance 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.

NodeListsNodeDataUse 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 .

NamedNodeListInherited 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). NamedNodeListimplemented elementMatches as a element.getNameAttribute() == m_name filtering standard (see WEBCORE/DOM/NAMENODELIST.H).

It is important to note thatCachedLiveNodeListOfelementMatchesFromLiveNodeListInherited, and inLiveNodeListIn the prototypeelementMatchesThe prototype isvirtual bool elementMatches(Element&) const = 0--Just a virtual function that does not require inline (see webcore/dom/livenodelist.h), butNamedNodeListImplementation 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), andCachedLiveNodeListUsually callelementMatchesPlace 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 ofthisTo 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--elementMatchesare destined to be frequently called. After allgetElementsByNameWill often be directly indocument, it iterates through all the nodes in the document, each one of which is called once.elementMatchesTo filter, which is usually at least hundreds or thousands of calls ... In the same way,ElementDescendantIteratorAlmost 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.
    • Nodeis 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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.