DOM basic + domReady + element node type judgment

DOM node type

Element 1 node.element node

attr 2 node.attribute node

Text 3 node. Text > node text node (the blank area between labels also belongs to the text node)

Comment 8 node.comment node

Document 9 node.document [node] document node (on all documents, i.e. the front most position in a page, in front of the document definition)

documentType 10 node.document type node (DOCTYPE)

documentFragment 11 node.document [fragment] document fragment node (it does not belong to the document tree, but is the smallest fragment. It can be used as a temporary placeholder. When inserting it into a document, only its descendant elements will be inserted, not itself)

Note: there are no nodes in IE8 and below. Using constant to judge nodeType will report an error: "node" is not defined

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>

</head>
<body>
    <div id="container"></div>
    <script>
        window.onload=function(){

            var container=document.getElementById("container");
            if(container.nodeType==Node.ELEMENT_NODE){
                alert("Is element node");
            }
        }    
    </script>
</body>
</html>

 

Therefore, it is not recommended to use constant to judge, and it is recommended to use numerical value

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>

</head>
<body>
    <div id="container"></div>
    <script>
        window.onload=function(){

            var container=document.getElementById("container");
            // if(container.nodeType==Node.ELEMENT_NODE){
            //     alert("Is element node");
            // }
            if(container.nodeType==1){
                alert("Is element node");
            }
        }    
    </script>
</body>
</html>

 

nodeName node name

nodeValue node value

. attributes saves all the attributes of an element. You can use array subscripts to access a specific attribute

. chilsNodes gets all the child nodes of an element. You can use array subscripts to access a specific attribute

document.doctype get document type node

Document. Createdocumentfragment() create document fragment

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>

</head>
<body>
    <!-- This is a comment -->
    <div id="container">This is the text duck inside</div>
    <script>
        window.onload=function(){

            var container=document.getElementById("container");
            console.log("Element node:"+container.nodeName+"/"+container.nodeValue);//Element node: DIV/null
            var attr=container.attributes[0];//Get the first attribute of an element
            console.log("Attribute node:"+attr.nodeName+"/"+attr.nodeValue);//Attribute node: id/container
            var text=container.childNodes[0];//Get the first child element node of an element
            console.log("Text node:"+text.nodeName+"/"+text.nodeValue);//Text node:#Text / this is the text duck inside
            var comment=document.body.childNodes[1];//Obtain body The second child element node of the element (the first child element node is a blank text node)
            console.log("Comment node:"+comment.nodeName+"/"+comment.nodeValue);//Comment node:#Comment / this is a comment 
            var doctype=document.doctype;//Obtain body The second child element node of the element (the first child element node is a blank text node)
            console.log("Document type node:"+doctype.nodeName+"/"+doctype.nodeValue);//Document type node: html/null
            var docFragment=document.createDocumentFragment();//Obtain body The second child element node of the element (the first child element node is a blank text node)
            console.log("Document fragment node:"+docFragment.nodeName+"/"+docFragment.nodeValue);//Document fragment node:#document-fragment/null
        }    
    </script>
</body>
</html>

 

When the script is before the DOM element, it cannot get the DOM element

Because the js code is placed in the head, and the code is executed in sequence. When the page is opened in the browser, the js code will be executed first, and then the dom structure in the body will be executed. If js wants to get the elements in the body when executing, an error will be reported, because the structure of the page has not been loaded yet.

You can use window.onload to solve

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>
    <script>
        window.onload=function(){

            var container=document.getElementById("container");
            console.log(container);
        }    
    </script>
</head>
<body>
    <!-- This is a comment -->
    <div id="container">This is the text duck inside</div>

</body>
</html>

Disadvantages of window.onload: waiting for DOM tree loading and external resources loading to complete

If the page references many external resources, it will lead to slow loading and affect the user experience

 

Best solution, jquery's $(document).ready()

Use native js to copy this method here

 

DOMContentLoaded loads the dom tree, but does not start loading external resources

IE does not support this method, use: document.documentElement.doScroll("left")

 

Listen for document loading status document.onreadystatechange

Document loading completed document.readyState=="complete"

Arguments.call calls the function itself

DomReady.js written by myself

function myReady(fn){

    /*
    Modern browser operation
    */
    if(document.addEventListener){
        //Modern browser operation
        document.addEventListener("DOMContentLoaded",fn,false);//false Indicates capture during bubbling
    }else{
        //IE Environmental operation
        IEContentLoaded(fn);
    }

    /*
    IE Environmental operation
    */
    function IEContentLoaded(fn){

        // init()--ensure fn Call only once
        var loaded=false;
        var init=function(){
            if(!loaded){
                loaded=true;
                fn();
            }
        }

        // If DOM Before the tree load is completed, try again and again
        (function(){
            try{
                // If DOM Tree loading is not completed, an exception will be thrown
                document.documentElement.doScroll("left");
            }catch(e){
                // If the attempt fails, try again
                setTimeout(arguments.callee,50);
                return;//Implementation recursion
            }
            //If no exception is thrown, execute immediately init()
            init();
            
        })();

        // DOM After the tree is loaded, call init()Method
        document.onreadystatechange=function(){
            if(document.readyState=="complete"){
                document.onreadystatechange=null;//Clear listening events
                init();
            }
        }
    }
}

Call the js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>
    <script src="DomReady.js"></script>
    <script>
        myReady(function(){
            var container=document.getElementById("container");
            console.log(container);
        });
    </script>
</head>
<body>
    <!-- This is a comment -->
    <div id="container">This is the text duck inside</div>

</body>
</html>

Achieve successful access to all browsers~

Let's really feel the difference between window.onload and domReady!!!

Use multiple large pictures to simulate the loading time

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>
    <script src="DomReady.js"></script>

</head>
<body>
    <!-- This is a comment -->
    <div id="container">This is the text duck inside</div>
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">
    <img src="source/cat.jpg">

    <script>

        myReady(function(){
            alert("domReady!");
            domready=new Date().getTime();
        });

        window.onload=function(){
            alert("windowLoaded!");
            windowload=new Date().getTime();
        }

    </script>
</body>
</html>

Found pop domReady first

Wait until the image is loaded, and then pop up windowsloaded

It takes a long time to confirm windows loaded

 

Type judgment of element node

isElement() determines whether it is an element node

isHTML() determines whether it is the element node of html document

isXML() determines whether it is an element node of an xml document

contains() to determine whether the element nodes are contained

. nextSibling get sibling of element

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>
    <script src="DomReady.js"></script>

</head>
<body>
    
    <div id="container">This is the text duck inside</div><!-- This is a comment -->

    <script>

        myReady(function(){
            
            function isElement(el){
                return !!el && el.nodeType===1;
            }

            console.log(isElement(container));
            console.log(isElement(container.nextSibling));
        });

    </script>
</body>
</html>

This method has a Bug, that is, if an object has the nodeType attribute set, it will lead to misjudgment

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>
    <script src="DomReady.js"></script>

</head>
<body>
    
    <div id="container">This is the text duck inside</div><!-- This is a comment -->

    <script>
        
        myReady(function(){
            
            function isElement(el){
                return !!el && el.nodeType===1;
            }

            var obj={
                nodeType:1
            }
            console.log(isElement(obj));//true
        });

    </script>
</body>
</html>

The strictest way to write isXML()

. createElement() create element

If it is not case sensitive, it is the element node of the html document;

Element node of xml document if case sensitive

. ownerDocument returns the document object of the element itself

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>
    <script src="DomReady.js"></script>

</head>
<body>
    
    <div id="container">This is the text duck inside</div><!-- This is a comment -->

    <script>
        
        myReady(function(){
            // Determine whether it is an element node
            function isElement(el){
                return !!el && el.nodeType==1;
            }
            // Judge whether it is xml File
            function isXML(el){
                return el.createElement("p").nodeName!==el.createElement("P").nodeName;
            }
            // Judge whether it is html File
            function isHTML(el){
                return el.createElement("p").nodeName===el.createElement("P").nodeName;
            }
            // Judge whether it is html Element node of the document
            function isHTMLNode(el){
                if(isElement(el)){
                    return isHTML(el.ownerDocument);
                }
                return false;
            }
            console.log(isXML(document));//false
            console.log(isHTML(document));//true
            console.log(isHTMLNode(container));//true
        });

    </script>
</body>
</html>

. containers determine whether a node contains another node

Google browser works normally, while IE requires that both nodes must be element nodes

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>
    <script src="DomReady.js"></script>

</head>
<body>
    
    <div class="parent" id="parent">
        <div class="child" id="child">This is a text node</div>
    </div>

    <script>
        
        myReady(function(){
            var parent=document.getElementById("parent");
            var child=document.getElementById("child");
            console.log(parent.contains(child));//true

            var text=child.childNodes[0];
            console.log(parent.contains(text));//Google browser true,IE Browser for false
        });

    </script>
</body>
</html>

Next, the compatibility method is given

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            width:100%;
            height:100%;
        }
    </style>
    <script src="DomReady.js"></script>

</head>
<body>
    
    <div class="parent" id="parent">
        <div class="child" id="child">This is a text node</div>
    </div>

    <script>
        
        myReady(function(){
            var parent=document.getElementById("parent");
            var child=document.getElementById("child");
            console.log(parent.contains(child));//true

            var text=child.childNodes[0];
            console.log(parent.contains(text));//Google browser true,IE Browser for false

            function fixContains(pNode,cNode){
                try{
                    while(cNode=cNode.parentNode){
                        if(pNode===cNode) return true;
                    }
                    return false;
                }catch(e){
                    return false;
                }
            }
            console.log(fixContains(parent,text));//Google browser true,IE Browser for true
        });

    </script>
</body>
</html>

true can be returned in all browsers, even if it is not an element node

Tags: Javascript Attribute Fragment IE Google

Posted on Thu, 06 Feb 2020 02:42:28 -0800 by damo87