Note source: Still silicon Valley latest version of the full set of JavaScript basic tutorial complete version (140 sets of actual combat teaching,JS from entry to master)_ bilibili _bilibili

[TOC]

DOM

1. Introduction to DOM

DOM, Document Object Model.

JS through THE DOM to the HTML document operation. As long as you understand the DOM, you can manipulate WEB pages in any way you want.

The document

A document represents the entire HTML web page document

object

Object means to convert every part of a web page into an object

model

Using models to represent relationships between objects makes it easy to get objects

The DOM tree represents the relationship between nodes

2, node,

A Node is the most basic component of a web page. Each part of a web page can be called a Node

For example, HTML tags, attributes, text, comments, entire documents, and so on are all nodes

Although both are nodes, their specific types are actually different. Such as:

  • Tags are called element nodes
  • Properties are called property nodes
  • Text is called a text node
  • Documents are called document nodes

Different types of nodes have different attributes and methods

The node type

Node: Node – The most basic unit of an HTML document

Common nodes fall into four categories

  • Document node: The entire HTML document
  • Element nodes: HTL tags in HTML documents
  • Attribute node: Attributes of an element
  • Text node: Text content in AN HTML tag

Node properties

Document node (Document)

The document node, document, represents the entire HTML document, and all nodes in the web page are its children

The Document object exists as a property of the Window object, so we can use it without getting it

This object allows us to look for node objects throughout the document access and to create various node objects from this object

Element node

The various tags in HTML are element nodes, and this is the one we use most often

The browser converts all the tags in the page to an element node, which we can retrieve using the Document method

For example: document.getelementById () gets an element node object based on the id attribute value.

Text node (Text)

Text nodes represent text content other than HTML tags. Any non-HTML text is a text node

It includes plain text content that can be interpreted literally

Text nodes generally exist as children of element nodes

When obtaining a text node, the element node is usually obtained first, and then the text node is obtained through the element node. For example: element node.firstChild;

Gets the first child of an element node, typically a text node

Attribute Node (Attr)

Attribute nodes represent attributes one by one in the tag. It is important to note that the attribute node is not a child of the element node, but a part of the element node

The specified attribute node can be obtained from the element node. For example, element node. GetAttributeNode (” attribute name “);

Note: We generally do not use attribute nodes

The browser already provides us with a document node object, which is a Window

Properties can be used directly within a page, and document nodes represent the entire web page

// Get the button object
var btn = document.getElementById("btn");
console.log(btn); 
// Modify the text node content of the BTN
btn.innerHTML = "I'm a button.";
Copy the code

3, events,

Events are specific moments of interaction that occur in a document or browser window

The interaction between JavaScript and HTML is achieved through events

For Web applications, there are typical events: clicking on an element, moving the mouse over an element, pressing a key on the keyboard, and so on

We can set some JS code in the properties of the event so that it will be executed when the event is fired

<button type="button" id="btn" onclick="alert('Fuck');"> I am a button </button>Copy the code

This approach, which we call structure-behavior coupling, is not recommended because it is not easy to maintain

You can respond to an event by binding a handler function to the button’s corresponding event, so that when the event is fired, its corresponding function will be called

// Bind a click event
btn.onclick = function(){
    alert("Don't touch me.");
}
Copy the code

Functions such as these that bind to click events are called click response functions

4. Document loading

UncaughtTypeError: Cannot set property ‘innerHTML’ of NULL

When the browser loads a page, it loads the page from top to bottom. When it reads a line, it runs a line. If the script tag is written to the top of the page, the page is not loaded and the DOM object is not loaded when the code is executed, it will cause that the DOM object cannot be obtained

If we have to do this, we can do it

The onLoad event is triggered after the entire page is loaded. You can bind an onload event to the window object

window.onload = function(){
    // Get the button object
    var btn = document.getElementById("btn");
    // Bind a click event
    btn.onclick = function(){
        alert("Don't touch me."); }}Copy the code

The response function for this event will be executed after the page is loaded, ensuring that all DOM objects have been loaded by the time our code executes

DOM query

Get element node

Through the Document object

For convenience, define a generic function that binds the click response function to the specified element

/ / parameters:
// idstr Specifies the id attribute value of the object to which the click response function is bound
// The callback function for the fun event, which is fired when the element is clicked
function myClick(idStr, fun){
    var btn = document.getElementById(idStr);
    btn.onclick = fun;
}
Copy the code
  • GetElementById () gets an element node object via the ID attribute

    myClick("btn01".function () {
        // innerHTML This property is used to get the HTML code inside the element
        alert(document.getElementById("bj").innerHTML); / / Beijing
    });
    Copy the code
  • GetElementsByTagName () gets a set of element node objects by tag names

    myClick("btn02".function () {
        // getElementsByTagName() gets a list of element node objects based on tag names
        // This method returns an array-like object in which all queried elements are encapsulated
        // Even if only one element is queried, it is wrapped in an array and returned
        var li_list = document.getElementsByTagName("li");
        alert(li_list.length); / / 14
        
        var arr = [];
        for(var i=0; i<li_list.length; i++){ arr.push(li_list[i].innerHTML); } alert(arr);/ / Beijing, Shanghai, Tokyo, Seoul, alert, and gourmet coaster, warcraft, IOS, Android, Windows Phone, IOS, Android, Windows Phone
    });
    Copy the code
  • GetElementsByName () gets a set of element node objects through the name attribute

    myClick("btn03".function () {
        var inputs = document.getElementsByName("gender");
        alert(inputs.length); / / 2
        
        var arr = [];
        for(var i=0; i<inputs.length; i++){// innerHTML Gets the HTML code of the element's civil war
            // If you need to read element node attributes, use the 'element directly. The property name `
            // Example: 'element. id' element. name 'element. value'
            arr.push(inputs[i].value); 
            // Note that the class attribute cannot be read in this way. The class attribute needs to be read using the element. ClassName
            arr.push(inputs[i].className);
        }
        alert(arr); // male,hello,female,hello
    });
    Copy the code

Practice: Switching pictures

The HTML code

<div class="outer">
    <p id="info">There are 5 pictures, so the first one</p>
    <img src="img/1.jpg" alt="Freeze"/>
    <button type="button" id="prev">On one piece</button>
    <button type="button" id="next">The next</button>
</div>
Copy the code

CSS code

* {margin:0;
    padding:0;
}

.outer{
    width: 500px;
    margin: 50px auto;
    padding: 10px;
    background-color: greenyellow;
    /* Text centered: Inline styles are treated as text */
    text-align: center;
}
Copy the code

JS code

/ / a
var prev = document.getElementById("prev");
/ / the next
var next = document.getElementById("next");
/ / picture
var img = document.getElementsByTagName("img") [0];
/ / information
var info = document.getElementById("info");
// Create a collection of images
var imgArr = ["img/1.jpg"."img/2.jpg"."img/3.jpg"."img/4.jpg"."img/5.jpg"];
// Record the number of entries
var index = 0;
// Click the corresponding event for the previous binding
prev.onclick = function(){
    // Loop switch
    index = (index < 0)? imgArr.length -1 : index;
    // Change the img SRC property to switch images
    img.src = imgArr[index];
    // Modify the text prompt
    info.innerHTML = "Total" + imgArr.length + "A picture, current number" + (index + 1) + "Zhang";
    // Switch to the previous one
    index--;
};
// Next bind click the corresponding event
next.onclick = function(){
    // Loop switch
    index = (index > imgArr.length - 1)?0 :index;
    // Change the img SRC property to switch images
    img.src = imgArr[index];
    // Modify the text prompt
    info.innerHTML = "Total" + imgArr.length + "A picture, current number" + (index + 1) + "Zhang";
    // Switch to the next slide
    index++;
};
Copy the code

The effect

Gets the children of the element node

Called by a specific element node

  • The getElementsByTagName() method returns the descendant node of the specified tag name for the current node

    myClick("btn04".function () {
        var city = document.getElementById("city");
        // Get the 1i node under city
        var list = city.getElementsByTagName("li");
        alert(list.length); / / 4
        
        var arr = [];
        for(var i=0; i<list.length; i++){ arr.push(list[i].innerHTML); } alert(arr);// Beijing, Shanghai, Tokyo, Seoul
    });
    Copy the code
  • The childNodes property represents all children of the current node

    myClick("btn05".function () {
        var city = document.getElementById("city");
        // The childNodes property retrieves all nodes, including text nodes
        // According to DOM tags, the space between tags is also treated as text nodes
        Note: In IE8 and below, blank text is not treated as a child node
        // So this property returns 4 child elements in IE8 and 9 in other browsers
        var list = city.childNodes;
        alert(list.length); / / 9
        
        var arr = [];
        for(var i=0; i<list.length; i++){ arr.push(list[i]); } alert(arr);// [object Text],[object HTMLLIElement],[object Text],[object HTMLLIElement],[object Text],[object HTMLLIElement],[object Text],[object HTMLLIElement],[object Text]
    });
    myClick("btn05".function () {
        var city = document.getElementById("city");
        // The children attribute gets all the children of the current element
        var list = city.children;
        alert(list.length); / / 4
        
        var arr = [];
        for(var i=0; i<list.length; i++){ arr.push(list[i].innerHTML); } alert(arr);// Beijing, Shanghai, Tokyo, Seoul
    });
    Copy the code
  • FirstChild property representing the firstChild of the current node

    myClick("btn06".function () {
        var phone = document.getElementById("phone");
        // firstChild retrieves the firstChild of the current element (including the blank text node)
        var firstChild = phone.firstChild;				
        alert(firstChild); // [object HTMLLIElement]
        alert(firstChild.innerHTML); // IOS
    });
    myClick("btn06".function () {
        var phone2 = document.getElementById("phone2");
        // firstChild retrieves the firstChild of the current element (including the blank text node)
        var firstChild = phone2.firstChild;				
        alert(firstChild); // [object Text]
        alert(firstChild.innerHTML); // undefined
    });
    myClick("btn06".function () {
        var phone2 = document.getElementById("phone2");
        FirstElementchild does not support IE8 and below. Do not use firstElementchild if you need to
        var firstElementChild = phone2.firstElementChild;				
        alert(firstElementChild); // [object HTMLLIElement]
        alert(firstElementChild.innerHTML); // IOS
    });
    Copy the code
  • The lastChild property represents the lastChild of the current node

    document.getElementById("btn062").onclick = function () {
        var phone = document.getElementById("phone");
        // The children attribute gets all the children of the current element
        var lastChild = phone.lastChild;				
        alert(lastChild); // [object HTMLLIElement]
        alert(lastChild.innerHTML); // Windows Phone
    });
    Copy the code

Gets the parent and sibling nodes

Called by a specific node

  • The parentNode property represents the parentNode of the current node

    myClick("btn07".function () {
        var bj = document.getElementById("bj");
        var parentNode = bj.parentNode;				
        alert(parentNode); // [object HTMLUListElement]
        alert(parentNode.innerHTML);
        // 
  • //
  • //
  • //
  • // innerText // - This property can get the text content inside the element // - It is similar to innerHTML, except that it automatically removes htM1 alert(parentNode.innerText); / / Beijing / / Shanghai / / Tokyo / / Seoul }); Copy the code
  • The previousSibling property represents the previousSibling of the current node

    myClick("btn08".function () {
        var android = document.getElementById("android");
        // Return the previous sibling of #android (possibly empty text)
        var previousSibling = android.previousSibling;				
        alert(previousSibling); // [object HTMLLIElement]
        alert(previousSibling.innerHTML); // IOS
    });
    myClick("btn08".function () {
        var android2 = document.getElementById("android2");
        // Return the previous sibling of #android (possibly empty text)
        var previousSibling = android2.previousSibling;				
        alert(previousSibling); // [object Text]
        alert(previousSibling.innerHTML); // undefined
    });
    myClick("btn08".function () {
        var android2 = document.getElementById("android2");
        // previousElementSibling gets the previous sibling, not supported by IE8 and below
        var previousElementSibling = android2.previousElementSibling;				
        alert(previousElementSibling); // [object HTMLLIElement]
        alert(previousElementSibling.innerHTML); // IOS
    });
    Copy the code
  • The nextSibling property represents the nextSibling of the current node

    myClick("btn082".function () {
        var android = document.getElementById("android");
        // Return the previous sibling of #android (possibly empty text)
        var nextSibling = android.nextSibling;				
        alert(nextSibling); // [object HTMLLIElement]
        alert(nextSibling.innerHTML); // Windows Phone
    });
    Copy the code

6, choose all exercises

The HTML code

<form method="post" action="">What's your favorite sport?<input type="checkbox" id="checkedAllBox" />All/none<br />
    <input type="checkbox" name="items" value="Football" />football<input type="checkbox" name="items" value="Basketball" />basketball<input type="checkbox" name="items" value="Badminton" />badminton<input type="checkbox" name="items" value="Table tennis" />Table tennis<br />
    <input type="button" id="checkedAllBtn" value="Future generations" />
    <input type="button" id="checkedNoBtn" value="None at all" />
    <input type="button" id="checkedRevBtn" value="The choice" />
    <input type="button" id="sendBtn" value="Submit" />
</form>
Copy the code

select all

document.getElementById("checkedAllBtn").onclick = function(){
    var items = document.getElementsByName("items");
    for(var i=0; i<items.length; i++){// The checked status of the checkboxes can be obtained or set using the checked property of the checkboxes
        items[i].checked = true;
    }
    // The all button should also be selected synchronously
    document.getElementById("checkedAllBox").checked = true;
}
Copy the code

All don’t choose

document.getElementById("checkedNoBtn").onclick = function(){
    var items = document.getElementsByName("items");
    for(var i=0; i<items.length; i++){ items[i].checked =false;
    }
    // The all button should also be synchronized unselected
    document.getElementById("checkedAllBox").checked = false;
}
Copy the code

The selected

document.getElementById("checkedRevBtn").onclick = function(){
    var items = document.getElementsByName("items");
    var flag = true;
    for(var i=0; i<items.length; i++){ items[i].checked = ! items[i].checked;if(! items[i].checked){ flag =false; }}// The all button should also be selected or unselected synchronously
    document.getElementById("checkedAllBox").checked = flag;
}
Copy the code

submit

document.getElementById("sendBtn").onclick = function(){
    var items = document.getElementsByName("items");
    var arr = [];
    for(var i=0; i<items.length; i++){if(items[i].checked){
            arr.push(items[i].value);
        }
    }
    alert(arr);
}
Copy the code

All/none

document.getElementById("checkedAllBox").onclick = function(){
    var items = document.getElementsByName("items");
    for(var i=0; i<items.length; i++){// In the event's response function, this is the object to which the response function is bound
        items[i].checked = this.checked; }}Copy the code

items

var flag;
var items = document.getElementsByName("items");
for(var i=0; i<items.length; i++){ items[i].onclick =function(){
        flag = true;
        for(var j=0; j<items.length; j++){if(! items[j].checked){ flag =false;
                break; }}document.getElementById("checkedAllBox").checked = flag; }}Copy the code

The effect

7. Remaining methods for DOM queries

document.body

There is an attribute body in the document, which holds a reference to the body

// Note: if the script tag is defined in the head, then window.onload = function(){} is required, otherwise null will occur
var body = document.getElementsByTagName("body");
console.log(body); // HTMLCollection [body]
body = document.body;
console.log(body); // <body></body>
console.log(typeof body); // object
Copy the code

document.documentElement

Document.documentelement holds the HTML root tag

var html = document.documentElement;
console.log(html);
Copy the code

document.all

Document. all represents all elements in the page

var all = document.all;
console.log(all); // HTMLAllCollection(11) [html, head, meta, title, script, script, script, body, script, script, script]
console.log(all.length); / / 11
console.log(typeof all); // undefined
for(var i=0; i<all.length; i++){console.log(all[i]);
}

var el = document.getElementsByTagName("*");
console.log(el); // HTMLCollection(11) [html, head, meta, title, script, script, script, body, script, script, script]
console.log(all.length); / / 11
console.log(typeof all); // undefined
for(var i=0; i<el.length; i++){console.log(el[i]);
}
Copy the code

document.getElementsByClassName()

Queries a set of element node objects based on their class attribute value

GetElementsByClassName () can get a set of element node objects based on the class attribute value, but this method is not supported in IE8 and below

var boxs = document.getElementsByClassName("box");
console.log(boxs); // HTMLCollection(3) [div.box, div.box, div.box]
console.log(boxs.length); / / 3
console.log(typeof boxs); // object
Copy the code

document.querySelector()

Requiring a selector string as an argument, you can query an element node object against a CSS selector

Although THERE is no getElementsByClassName() in IE8, you can use querySelector() instead

This method always returns a unique element, and if there are more than one, it only returns the first one

var div = document.querySelector(".box div");
console.log(div.innerHTML); // I'm first div.
boxs = document.querySelector(".box");
console.log(boxs); 
// <div class="box">
// 
      
I'm first div.
// </div> Copy the code

document.querySelectorAll()

This method is similar to querySelector(), except that it returns the matched elements wrapped in an array

It returns an array even if only one element is eligible

boxs = document.querySelectorAll(".box");
console.log(boxs); // NodeList(3) [div.box, div.box, div.box]
console.log(boxs.length); / / 3
Copy the code

8. DOM addition, deletion and modification

document.createElement()

Can be used to create an element node object, which takes a label name as an argument, creates the element node object based on that label name, and returns the created object as a return value

document.createTextNode()

Can be used to create a text node object, which takes a text content as an argument, from which the text node will be created, and the new node will be returned

appendChild()

Add a new child node to a parent node using: parent node. AppendChild (child node);

insertBefore()

InsertBefore (new node, old node); insertBefore(new node, old node);

replaceChild()

ReplaceChild (new, old); replaceChild(new, old);

removeChild()

RemoveChild removeChild removes a child node. Parentnode. removeChild(child node);

// Create a "Guangzhou" node and add it to #city
var city = document.getElementById("city");
myClick("btn01".function(){
    // Create the element node
    var li = document.createElement("li");
    // Create a text node
    var gz = document.createTextNode("Guangzhou");
    // Add the text node to the element node
    li.appendChild(gz);
    // Add the element node under #city
    city.appendChild(li);
});
// Insert the "guangzhou" node before #bj
var bj = document.getElementById("bj");
myClick("btn02".function(){
    var li = document.createElement("li");
    var gz = document.createTextNode("Guangzhou");
    li.appendChild(gz);
    // Insert the element node before #bj
    city.insertBefore(li,bj);
});
// replace the #bj node with the "guangzhou" node
myClick("btn03".function(){
    var li = document.createElement("li");
    var gz = document.createTextNode("Guangzhou");
    li.appendChild(gz);
    // Replace the element node with the #bj node
    city.replaceChild(li,bj);
});
// Delete the #bj node
myClick("btn04".function(){
    // Replace the element node with the #bj node
    // city.removeChild(bj);
    // What is the parent node
    bj.parentNode.removeChild(bj);
});
// Add the "Guangzhou" node under #city with innerHTML
myClick("btn07".function(){
    You can also add, delete, or modify the DOM using innerHTML
    // city. InnerHTML += "
  • Guangzhou
  • ";
    // However, this method will delete and then replace, which costs performance, so generally we use both methods together var li = document.createElement("li"); li.innerHTML = "Guangzhou"; city.appendChild(li); }); Copy the code

    9. Add and delete exercises

    To prepare

    The HTML code

    <table id="employeeTable">
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Salary</th>
            <th>&nbsp;</th>
        </tr>
        <tr>
            <td>Tom</td>
            <td>[email protected]</td>
            <td>5000</td>
            <td><a href="deleteEmp? id=001">Delete</a></td>
        </tr>
        <tr>
            <td>Jerry</td>
            <td>[email protected]</td>
            <td>8000</td>
            <td><a href="deleteEmp? id=002">Delete</a></td>
        </tr>
        <tr>
            <td>Bob</td>
            <td>[email protected]</td>
            <td>10000</td>
            <td><a href="deleteEmp? id=003">Delete</a></td>
        </tr>
    </table>
    
    <div id="formDiv">
        <h4>Add new employees</h4>
        <table>
            <tr>
                <td class="word">name: </td>
                <td class="inp">
                    <input type="text" name="empName" id="empName" />
                </td>
            </tr>
            <tr>
                <td class="word">email: </td>
                <td class="inp">
                    <input type="text" name="email" id="email" />
                </td>
            </tr>
            <tr>
                <td class="word">salary: </td>
                <td class="inp">
                    <input type="text" name="salary" id="salary" />
                </td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <button id="addEmpButton" value="abc">
                        Submit
                    </button>
                </td>
            </tr>
        </table>
    </div>
    Copy the code

    JS code

    // a clicks the corresponding function
    function delRow() {
        // Add a prompt
        grandPrentNode = this.parentNode.parentNode;
        var name = grandPrentNode.children[0].innerHTML;
        if (confirm("Confirm deletion" + name + "?")) {
            // Delete the ancestor node
            grandPrentNode.parentNode.removeChild(grandPrentNode);
        }
        // When a hyperlink is clicked, it redirects to the page. This is the default behavior of hyperlinks.
        // But we don't want the default behavior at this point. We can cancel the default behavior by returning false at the end of the response function
        return false;
    }
    
    window.onload = function() {
        // 1
        // Click the corresponding function for the delete binding
        var a;
        var grandPrentNode;
        var aList = document.getElementsByTagName("a");
        for (var i = 0; i < aList.length; i++) {
            aList[i].onclick = delRow;
        }
    
        // 2
        document.getElementById("addEmpButton").onclick = function() {
            / / get the name/email/salary
            var empName = document.getElementById("empName").value;
            var email = document.getElementById("email").value;
            var salary = document.getElementById("salary").value;
    
            // Check whether the data is null
            if(! empName || ! email || ! salary) { alert("Empty data cannot be added!");
                return;
            }
    
            // Create a text node
            var empName_text = document.createTextNode(empName);
            var email_text = document.createTextNode(email);
            var salary_text = document.createTextNode(salary);
            var delete_text = document.createTextNode("Delete");
    
            // Create the element node
            var tr = document.createElement("tr");
            var empName_td = document.createElement("td");
            var email_td = document.createElement("td");
            var salary_td = document.createElement("td");
            var a_td = document.createElement("td");
            var a = document.createElement("a");
    
            // Add content
            a.href = "javascript:;";
            a.onclick = delRow;
    
            // Add child nodes
            empName_td.appendChild(empName_text);
            email_td.appendChild(email_text);
            salary_td.appendChild(salary_text);
            a.appendChild(delete_text);
            a_td.appendChild(a);
            tr.appendChild(empName_td);
            tr.appendChild(email_td);
            tr.appendChild(salary_td);
            tr.appendChild(a_td);
    
            // Add tr to table
            // document.getElementById("employeeTable").appendChild(tr);
            // Note: The browser-generated table structure has an internal tbody layer, which should be added to tBody just in case, for structural and style consistency
            var employeeTable = document.getElementById("employeeTable");
            var tbody = employeeTable.getElementsByTagName("tbody") [0];
            tbody.appendChild(tr);
        }
    Copy the code

    Add the optimization

    Use createElement and innerHTML to optimize and modify the add code logic above

    document.getElementById("addEmpButton").onclick = function() {
        / / get the name/email/salary
        var empName = document.getElementById("empName").value;
        var email = document.getElementById("email").value;
        var salary = document.getElementById("salary").value;
    
        // Check whether the data is null
        if(! empName || ! email || ! salary) { alert("Empty data cannot be added!");
            return;
        }
    
        // Create the element node
        var tr = document.createElement("tr");
    
        // Add child nodes
        var empNameTd = "<td>" + empName + "</td>";
        var emailTd = "<td>" + email + "</td>";
        var salaryTd = "<td>" + salary + "</td>";
        var aTd = "Delete";
        tr.innerHTML = empNameTd + emailTd + salaryTd + aTd;
    
        // To bind a, click the corresponding function
        tr.getElementsByTagName("a") [0].onclick = delRow;
    
        // Add tr to table
        // document.getElementById("employeeTable").appendChild(tr);
        // Note: The browser-generated table structure has an internal tbody layer, which should be added to tBody just in case, for structural and style consistency
        var employeeTable = document.getElementById("employeeTable");
        var tbody = employeeTable.getElementsByTagName("tbody") [0];
        tbody.appendChild(tr);
    }
    Copy the code

    Index problem of A

    The above, we add for each a click the response function, use this traversal of a element, through this. ParentNode. ParentNode gained the tr element, if here to aList [I] parentNode. ParentNode, Can I get tr?

    It looks like there’s no suspense, but you can’t actually get it. Why is that?

    We can modify the click function for the element a in the for loop to print out the I we get every time

    for (var i = 0; i < aList.length; i++) {
        aList[i].onclick = function(){
            alert(i);
            return false;
        };
    }
    Copy the code

    You will find that each time you print the result is 3, and the length of a aList is 3 and the maximum index is 2

    The reason is simple, because the click function executes later than the for loop. In other words, the for loop is completed before we hit Delete. So when the loop of I =2 is being executed, it’s going to be I ++, so I =3, so that’s the loop condition so I being 9:2, so if the loop condition is not met, the for loop exits. Therefore, every time I is obtained after the execution of the for loop, so it is impossible to obtain the corresponding a element through the aList[I] mode

    Summary: The for loop executes immediately after the page loads, while the response function executes when the hyperlink is clicked. By the time the response function executes, the for loop has already completed its execution

    10. Operate inline styles

    Modify the inline style of elements

    Change the inline style of an element with JS syntax: element.style.style name = style value

    box1.style.height = "200px";
    box1.style.width = "200px";
    Copy the code

    Note: CSS style names with a one in them are not valid in JS, such as background-color

    You need to change the style name to camel nomenclature, remove the -, and then capitalize the letter after –

    // box1.style.background-color = "red"; // Uncaught SyntaxError: Invalid left-hand side in assignment
    box1.style.backgroundColor = "red";
    Copy the code

    In the W3School manual, you can see the JS code corresponding to each style

    The styles we set with the style property are all inline, and inline styles have higher priority, so styles modified with JS tend to show up immediately

    But if you write it in style! Important, then the style will have the highest priority, even through JS also cannot override the style, this will result in JS modification style invalid, so try not to add style! important

    Let’s set background-color! Important, through box1. Style. BackgroundColor = “red”; The set style is “invalid”

    background-color: yellow ! important;
    Copy the code

    Read the inline style of the element

    Read the inline style of an element with JS syntax: element. Style. Style name

    All styles set and read through the style property are inline styles and cannot be read from the style sheet

    alert(box1.style.height); // 
    box1.style.height = "200px";
    alert(box1.style.height); // 200px
    Copy the code

    Don’t worry, look down patiently

    Reading element Styles

    Gets the current display style of the element, syntax: element.currentStyle. Style name

    It can be used to read the style being displayed for the current element and get its default value if the style is not set for the current element

    alert(box1.currentStyle.height); // 100px
    box1.style.height = "200px";
    alert(box1.currentStyle.height); // 200px
    Copy the code

    Currentstyle is only supported by Internet Explorer, not other browsers. UncaughtTypeError: Cannot read property ‘height’ of undefined

    However, in other browsers you can use getComputedStyle(), which gets the current style of the element

    This method is the window method and can be used directly. It takes two arguments

    • First: The element to get the style
    • Second: can pass a false element, generally passnull

    This method returns an object that encapsulates the style of the current element

    The style can be read by the object. Style name, and if the style is not set, it will get the true value, not the default value

    For example, if width is not set, it does not get auto, but a length

    However, this method does not support Internet Explorer 8 and below

    var obj = getComputedStyle(box1, null);
    alert(obj); // [object CSSStyleDeclaration]
    alert(obj.width); // 200px
    alert(obj.height); // 200px
    alert(obj.backgroundColor); // rgb(255, 0, 0)
    Copy the code

    So, if you want to be compatible with IE8 and below, you will be in a dilemma, what to do?

    The styles read through currentStyle and getComputedStyle() are read-only and cannot be modified, except through the Style attribute

    I’ll have to write my own function that works with all browsers

    // Custom methods that are compatible with all browsers to get element styles
    function getStyle(obj, name) {
        // Determine if there is a getComputedStyle method
        if (getComputedStyle) {
            // Normal browser mode
            return getComputedStyle(obj, null)[name];
        } else {
            // IE
            returnobj.currentStyle[name]; }}Copy the code

    The test results

    Hbuilder built-in browser

    Chrome

    Edge

    IE11

    IE8

    “GetComputedStyle” is not defined.

    If (function) = function (getComputedStyle); if (function) = function (getComputedStyle)

    So how to solve this problem?

    Let’s change the function code and change getComputedStyle to window.getComputedStyle

    function getStyle(obj, name) {
        // Determine if there is a getComputedStyle method
        if (window.getComputedStyle) {
            // Normal browser mode
            return getComputedStyle(obj, null)[name];
        } else {
            // IE
            returnobj.currentStyle[name]; }}Copy the code

    The effect

    Why is that?

    Because the variable can not find the error, and attribute can not find the return is undefined and not error, so we can use undefined! = true, executes code in else

    In the same way, the following code can be used, except that the currentStyle method will take precedence over the getComputedStyle method, so it is not recommended

    function getStyle(obj, name) {
        // Check if there is a currentStyle attribute
        if (obj.currentStyle) {
            // IE
            return obj.currentStyle[name];
        } else {
            // Normal browser mode
            return getComputedStyle(obj, null)[name]; }}Copy the code

    Is there any room for optimization or simplification? Of course, we can simplify this by using the ternary operator

    function getStyle(obj, name) {
        return window.getComputedStyle ? getComputedStyle(obj, null)[name] : obj.currentStyle[name];
    }
    Copy the code

    Ternary operators are a little bit cleaner, and if-else is a little bit clearer, so IF-else is recommended, but it’s essentially the same, depending on your personal habits

    11. Other style related properties

    Clientwidth, clientHeight

    These two attributes get the visible width and height of the element

    These attributes do not contain px and return a number that can be computed directly

    Gets the element width and height, including the content area and inner margins

    These attributes are read-only and cannot be changed (there is only one way to change them, via the element.style. Style = style value)

    // #box1 {
    // width: 100px;
    // height: 100px;
    // background-color: red;
    // padding: 10px;
    // border: 10px solid yellow;
    // }
    alert(box1.clientHeight); / / 120
    alert(box1.clientWidth); / / 120
    Copy the code

    Offsetwidth, offsetHeight

    Gets the entire width and height of the element, including the content area, padding, and border

    // #box1 {
    // width: 100px;
    // height: 100px;
    // background-color: red;
    // padding: 10px;
    // border: 10px solid yellow;
    // }
    alert(box1.offsetHeight); / / 140
    alert(box1.offsetWidth); / / 140
    Copy the code

    offsetParent

    Can be used to get the location parent of the current element

    The nearest ancestor element with sticky enabled (as long as position is not sticky) is retrieved

    If positioning is not enabled for all ancestor elements, the body is returned

    // <div id="box1"></div>
    alert(box1.offsetParent); // [object HTMLBodyElement]
    
    // <div id="box2">
    // 
          
    // </div> alert(box1.offsetParent); // [object HTMLBodyElement] //<div id="box3"> // <div id="box2"> //
    // </div> //</div> alert(box1.offsetParent); // [object HTMLBodyElement] //
    //
    //
    // </div> //</div> alert(box1.offsetParent); // [object HTMLDivElement] alert(box1.offsetParent.id); // box2 //
    // <div id="box2"> //
    // </div> //</div> alert(box1.offsetParent); // [object HTMLDivElement] alert(box1.offsetParent.id); // box3 Copy the code

    The offsetLeft and offsetTop

    The horizontal or vertical offset of the current element with respect to its positioned parent

    //<div id="box3">
    //	<div id="box2">
    // 
          
    // </div> //</div> alert(box1.offsetLeft); // 8 Default browser style alert(box1.offsetTop); / / 54 //<div id="box3"> //
    //
    // </div> //</div> alert(box1.offsetLeft); / / 0 alert(box1.offsetTop); / / 0 Copy the code

    ScrollHeight, scrollWidth

    Gets the width and height of the element’s entire scroll area

    // #box4 {
    // width: 200px;
    // height: 300px;
    // background-color: yellow;
    // overflow: auto;
    // }
    // #box5 {
    // width: 400px;
    // height: 600px;
    // background-color: #bfa;
    // }
    alert(box4.scrollHeight); / / 600
    alert(box4.scrollWidth); / / 400
    Copy the code

    ScrollLeft, scrollTop

    Gets how far the horizontal or vertical scroll bar scrolls

    // #box4 {
    // width: 200px;
    // height: 300px;
    // background-color: yellow;
    // overflow: auto;
    // }
    // #box5 {
    // width: 400px;
    // height: 600px;
    // background-color: #bfa;
    // }
    alert(box4.scrollLeft); / / / 92/0/71.19999694824219... Changes as the horizontal scroll bar rolls
    alert(box4.scrollTop); / / / 116/0/163.1999969482422... Changes as the vertical scroll bar scrolls
    Copy the code

    To look at a problem, print the following values and scroll through the horizontal and vertical bars

    alert(box4.clientHeight + "," + (box4.scrollHeight - box4.scrollTop)); / / 283, 283.20001220703125
    alert(box4.clientWidth + "," + (box4.scrollWidth - box4.scrollLeft)); / / 183, 183.1999969482422
    Copy the code

    PS: The result I printed here has a decimal point, I wonder why

    • When meetscrollHeight - scrollTop == clientHeight“Indicates that the vertical scroll bar has been rolled to the end
    • When meetscrollWidth - scrollLeft == clientwidth, indicating that the horizontal scroll bar is rolled to the end

    So what does this principle do?

    Some sites have an overlord user agreement when they sign up. Make sure you read the agreement before you can sign up. So how do you make sure the user reads the agreement? Is the use of the above principle, when the scroll bar drag to the bottom, you can register.

    So next, let’s do a bully clause user agreement

    practice

    The HTML code

    <div id="outer">
        <h3>Dear users, welcome to register this website</h3>
        <p id="info">Dear users, please read the following agreement carefully. If you do not read it carefully, you should not register.</p>
        <div id="checkDiv">
            <input type="checkbox" name="checkInput" value="1" id="checkInput" disabled="disabled" />I have read the agreement carefully and will abide by it</div>
        <div id="submitDiv">
            <input type="submit" id="submitInput" disabled="disabled" value="Registered"/>
        </div>
    </div>
    Copy the code

    CSS code

    #outer {
        width: 500px;
    }
    
    #outer.h3.#checkDiv.#submitDiv.#submitInput {
        margin: 10px auto;
    }
    
    #checkDiv {
        width: 250px;
    }
    
    #submitInput {
        display: block;
    }
    
    #info {
        height: 600px;
        overflow: auto;
    }
    Copy the code

    JS code

    // Bind events to scrollbars, which bind events to elements with scrollbars
    var info = document.getElementById("info");
    var checkInput = document.getElementById("checkInput");
    var submitInput = document.getElementById("submitInput");
    info.onscroll = function() {
        // When the scrollbar scrolls to the bottom, enable and automatically check the protocol and enable the registration button
        if (parseInt(info.scrollHeight - info.scrollTop) == parseInt(info.clientHeight)) {
            // Automatically check the protocol
            checkInput.disabled = false;
            checkInput.checked = true;
            // Enable the register button
            submitInput.disabled = false; }}// Check response events for the checkInput binding
    checkInput.onclick = function(ret) {
        // If protocol is selected, the registration button is enabled, otherwise it is disabled
        if(! checkInput.checked) { submitInput.disabled =true;
        }
        else{
            submitInput.disabled = false; }}// Click the response function for the Submit binding
    submitInput.onclick = function(){
        if(confirm("Are you sure to register?")){
            alert("Registration successful"); }}Copy the code

    The effect