Learning objectives:
Ability to delete nodes using the removeChild() method
Ability to dynamically generate form cases
Ability to register events for elements using traditional and monitoring methods
Ability to say three stages of event flow execution
Ability to get event objects in event handlers
Ability to cancel default behavior using event objects
Ability to use event objects to prevent event bubbles
Ability to use event object to get mouse position
Ability to complete Angel case following mouse
1.1. Node operation
1.1.1 Delete Nodes
The node.removeChild() method deletes a child node from a node and returns the deleted node.
<button>delete</button> <ul> <li>Bear Big</li> <li>Bear Two</li> <li>Light Head Intensity</li> </ul> <script> // 1. Get Elements var ul = document.querySelector('ul'); var btn = document.querySelector('button'); // 2. Delete the element node.removeChild(child) // ul.removeChild(ul.children[0]); // 3. Click the buttons to delete the children in turn btn.onclick = function() { if (ul.children.length == 0) { this.disabled = true; } else { ul.removeChild(ul.children[0]); } } </script>
1.1.2 Cases: Deleting Messages
<textarea name="" id=""></textarea> <button>Release</button> <ul> </ul> <script> // 1. Get Elements var btn = document.querySelector('button'); var text = document.querySelector('textarea'); var ul = document.querySelector('ul'); // 2. Registration Events btn.onclick = function() { if (text.value == '') { alert('You did not enter anything'); return false; } else { // console.log(text.value); // (1) Create elements var li = document.createElement('li'); // Must have li before assignment li.innerHTML = text.value + "<a href='javascript:;'>delete</a>"; // (2) Adding elements // ul.appendChild(li); ul.insertBefore(li, ul.children[0]); // (3) Delete the element Delete the currently linked li its father var as = document.querySelectorAll('a'); for (var i = 0; i < as.length; i++) { as[i].onclick = function() { // Delete the li this.parentNode where li a is currently located; ul.removeChild(this.parentNode); } } } } </script>
1.1.3 Replication (Cloning) Nodes
<ul> <li>1111</li> <li>2</li> <li>3</li> </ul> <script> var ul = document.querySelector('ul'); // 1. node.cloneNode(); Empty parentheses or false shallow copy inside only copy label not copy inside content // 2. node.cloneNode(true); Bracketed true deep copy label copies the contents inside var lili = ul.children[0].cloneNode(true); ul.appendChild(lili); </script>
1.1.4 Cases: Dynamic Table Generation
<script> // 1. Prepare the students'data first var datas = [{ name: 'Wei Er', subject: 'JavaScript', score: 100 }, { name: 'Heritage', subject: 'JavaScript', score: 98 }, { name: 'Fu Heng', subject: 'JavaScript', score: 99 }, { name: 'Mingyu', subject: 'JavaScript', score: 88 }, { name: 'Big Pig's Foot*', subject: 'JavaScript', score: 0 }]; // 2. Create rows inside tbody: we create rows with a few people (by the length of the array) var tbody = document.querySelector('tbody'); // foreach for (var i = 0; i < datas.length; i++) { // 1. Create tr rows var tr = document.createElement('tr'); tbody.appendChild(tr); // 2. The number of td cells created in a row depends on the number of attributes in each object // Traversing student objects using for in for (var k in datas[i]) { // Creating Cells var td = document.createElement('td'); // Give td the attribute value datas[i][k] inside the object td.innerHTML = datas[i][k]; tr.appendChild(td); } // 3. Create cells with 2 words deleted var td = document.createElement('td'); td.innerHTML = '<a href="javascript:;">delete </a>'; tr.appendChild(td); } // 4. Delete operation started var as = document.querySelectorAll('a'); for (var i = 0; i < as.length; i++) { as[i].onclick = function() { // Click a to delete the current row (linked Dad's Dad) node.removeChild(child) tbody.removeChild(this.parentNode.parentNode) } } </script>
1.1.5 Three ways to create elements
<script> // Three ways to create elements // 1. document.write() Creates an element If the page document stream is loaded, calling this sentence again will cause the page to redraw var btn = document.querySelector('button'); btn.onclick = function() { document.write('<div>123</div>'); } // 2. innerHTML creation element var inner = document.querySelector('.inner'); for (var i = 0; i <= 100; i++) { inner.innerHTML += '<a href="#">Baidu</a>' } var arr = []; for (var i = 0; i <= 100; i++) { arr.push('<a href="#">Baidu</a>'"; } inner.innerHTML = arr.join(''); // 3. document.createElement() Create element var create = document.querySelector('.create'); for (var i = 0; i <= 100; i++) { var a = document.createElement('a'); create.appendChild(a); } </script> 1.1.6 innerTHML and createElement Efficiency comparison innerHTML String stitching (inefficient) <script> function fn() { var d1 = +new Date(); var str = ''; for (var i = 0; i < 1000; i++) { document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>'; } var d2 = +new Date(); console.log(d2 - d1); } fn(); </script>
1.1.6 innerTHML versus createElement efficiency
createElement approach (average efficiency)
<script> function fn() { var d1 = +new Date(); for (var i = 0; i < 1000; i++) { var div = document.createElement('div'); div.style.width = '100px'; div.style.height = '2px'; div.style.border = '1px solid red'; document.body.appendChild(div); } var d2 = +new Date(); console.log(d2 - d1); } fn(); </script>
innerHTML array mode (high efficiency)
<script> function fn() { var d1 = +new Date(); var array = []; for (var i = 0; i < 1000; i++) { array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>'); } document.body.innerHTML = array.join(''); var d2 = +new Date(); console.log(d2 - d1); } fn(); </script>
1.2. Core Summary of DOM
With regard to dom operations, we focus on the operations of elements. There are mainly create, add, delete, change, check, attribute operation, event operation.
1.2.1. Creation
1.2.2.Increase
1.2.3. Delete
1.2.4. Change
1.2.5. Check
1.2.6. Attribute operations
1.2.7. Event actions (focus)
1.3. Event Advanced
1.3.1. Register events (2 ways)
1.3.2 Event Monitoring
addEventListener() event monitoring (later supported by IE9)
The eventTarget.addEventListener() method registers the specified listener on the eventTarget, which executes the event handler when it triggers the specified event.
attacheEvent() event monitoring (IE678 support)
The eventTarget.attachEvent() method registers the specified listener on the eventTarget (target object), and when the object triggers the specified event, the specified callback function is executed.
<button>Traditional Registration Events</button> <button>Method listens for registration events</button> <button>ie9 attachEvent</button> <script> var btns = document.querySelectorAll('button'); // 1. Register events in a traditional way btns[0].onclick = function() { alert('hi'); } btns[0].onclick = function() { alert('hao a u'); } // 2. Event Listening Registration Event addEventListener // (1) The event type inside is that the string must be quoted without on // (2) Multiple listeners (event handlers) can be added to the same element and event btns[1].addEventListener('click', function() { alert(22); }) btns[1].addEventListener('click', function() { alert(33); }) // 3. Pre-attachEvent IE9 version support btns[2].attachEvent('onclick', function() { alert(11); }) </script>
Event Listening Compatibility Solution
Encapsulates a function that determines the type of browser:
1.3.3. Delete Events (Unbound Events)
<div>1</div> <div>2</div> <div>3</div> <script> var divs = document.querySelectorAll('div'); divs[0].onclick = function() { alert(11); // 1. Delete events in a traditional way divs[0].onclick = null; } // 2. removeEventListener Delete Event divs[1].addEventListener('click', fn) // fn inside does not need to be called with parentheses function fn() { alert(22); divs[1].removeEventListener('click', fn); } // 3. detachEvent divs[2].attachEvent('onclick', fn1); function fn1() { alert(33); divs[2].detachEvent('onclick', fn1); } </script>
Remove Event Compatibility Solution
1.3.4. DOM Event Flow
Tags in html are nested within each other, so we can imagine elements as boxes, document s being the outermost big boxes. When you click a div, you also click the parent element of the div, or even the entire page. Do you want to execute the parent element's click event first, or div's click event first???
For example, we registered a click event for a div on the page, and when you clicked a div, you clicked body, html, and document.
No one was convinced by the two browser hegemonists at that time! IE suggests starting with the target element, then receiving events one by one and responding, that is, bubble event streams. Netscape proposes to start from the outermost layer, then receive events one by one and respond inward, that is, capture event streams. The disputes between rivers and lakes make the leaders of the Wulin League feel headache!!! Ultimately, the w3c used a compromise approach to calm the war and set a unified standard --- capturing and bubbling first. Modern browsers follow this standard, so when an event occurs, it goes through three stages.
The DOM event flow goes through three phases:
-
Capture Phase
-
Current Target Stage
-
bubbling phase
When we throw a stone into the water, first it will have a descending process, which can be interpreted as a capture process from the top to the most specific element (target point) of the event. Bubbles are then created and float to the surface after the lowest point (the most specific element), which is equivalent to event bubbles.
Event Bubbling
<div class="father"> <div class="son">son Box</div> </div> <script> // onclick and attachEvent(ie) triggered during the bubble phase // Bubble stage if the third parameter of addEventListener is false or omitted // son -> father ->body -> html -> document var son = document.querySelector('.son'); // Register Click Events for son son.addEventListener('click', function() { alert('son'); }, false); // Register click events for father var father = document.querySelector('.father'); father.addEventListener('click', function() { alert('father'); }, false); // Register the click event for the document, omitting the third parameter document.addEventListener('click', function() { alert('document'); }) </script>
Event Capture
<div class="father"> <div class="son">son Box</div> </div> <script> // Triggered during capture if the third argument of addEventListener() is true // document -> html -> body -> father -> son var son = document.querySelector('.son'); // Register the click event for son with the third argument true son.addEventListener('click', function() { alert('son'); }, true); var father = document.querySelector('.father'); // Register the click event for father with the third argument true father.addEventListener('click', function() { alert('father'); }, true); // Register the click event for the document, with the third argument true document.addEventListener('click', function() { alert('document'); }, true) </script>
1.3.5. Event Objects
What is an Event Object
After an event occurs, a collection of information data related to the event is placed inside this object, which is the event object.
For example:
-
Who is bound to this event.
-
When the mouse triggers an event, information about the mouse, such as the mouse position, is obtained.
-
When the keyboard triggers an event, you get information about the keyboard, such as which key was pressed.
Use of event objects
Event objects are generated when an event triggers, and the system passes them to the event handler as arguments.
Therefore, declare a parameter in the event handler to receive the event object.
Compatibility handling of event objects
There are compatibility issues with the acquisition of event objects themselves:
-
The standard browser is the parameter passed by the browser to the method, which can be obtained by simply defining the parameter e.
-
In IE6~8, the browser does not pass parameters to the method, and needs to go to window.event to get the lookup if needed.
As long as'|'is preceded by false, whether true or false after'|', the value after'||' is returned. As long as'|'is preceded by true, whether true or false after'|', the value before'||' is returned.
<div>123</div> <script> var div = document.querySelector('div'); div.onclick = function(e) { // Event Object e = e || window.event; console.log(e); } </script>
Properties and methods of event objects
The difference between e.target and this
-
This is an element of event binding (the element that binds this event handler).
-
e.target is the element triggered by an event.
Typically terget and this are identical, There is a difference, however, when the event bubbles (the parent-child element has the same event, and when the child element is clicked, the parent element's event handler is triggered to execute). this point to the parent element because it is the element object that binds the event. target points to a child element because it is the specific element object that triggers the event.
<div>123</div> <script> var div = document.querySelector('div'); div.addEventListener('click', function(e) { // e.target and this all point to div console.log(e.target); console.log(this); }); </script>
e.target and this under event bubbles
<ul> <li>abc</li> <li>abc</li> <li>abc</li> </ul> <script> var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { // We bind events to ul so this points to ul console.log(this); // ul // The object that triggered the event by e.target We clicked on li e.target and pointed to li console.log(e.target); // li }); </script>
1.3.6 Prevent default behavior
Some tags in html have default behavior, such as page jumps when a tag is clicked.
<a href="http://Www.baidu.com ">Baidu</a> <script> // 2. Prevent default behavior to keep links from jumping var a = document.querySelector('a'); a.addEventListener('click', function(e) { e.preventDefault(); // dom standard writing }); // 3. Traditional registration methods a.onclick = function(e) { // Normal browser e.preventDefault(); method e.preventDefault(); // Low version browser ie678 returnValue property e.returnValue = false; // We can also use return false to prevent default behavior from having compatibility issues return false; } </script>
1.3.7 Prevent Event Bubbles
The characteristics of event bubbles themselves can bring about both harm and benefit.
<div class="father"> <div class="son">son Son</div> </div> <script> var son = document.querySelector('.son'); // Register Click Events for son son.addEventListener('click', function(e) { alert('son'); e.stopPropagation(); // stop Stops Propagation Propagation window.event.cancelBubble = true; // Nonstandard cancel cancel bubble s }, false); var father = document.querySelector('.father'); // Register click events for father father.addEventListener('click', function() { alert('father'); }, false); // Register click events for document document.addEventListener('click', function() { alert('document'); }) </script>
Compatibility handling to prevent event bubbling
1.3.8 Event Delegation
The characteristics of event bubbles themselves can bring about both harm and benefit.
What is an event delegate
Delegate things to others and handle them on their behalf.
Event delegation is also known as event proxy and is called event delegation in jQuery.
To put it plainly, do not register events for child elements, register events for parent elements, and execute processing code in events for parent elements.
Agents in life:
Proxy in js event:
Principle of event delegation
Register events for the parent element, using event bubbling, which bubbles to the parent element when the child element's event is triggered, and then controls the corresponding child element.
Role of event delegation
-
We only operated on the DOM once to improve the performance of the program.
-
Dynamic newly created child elements also have events.
<ul> <li>Do you know if I should have a marquee in my hand?</li> <li>Do you know if I should have a marquee in my hand?</li> <li>Do you know if I should have a marquee in my hand?</li> <li>Do you know if I should have a marquee in my hand?</li> <li>Do you know if I should have a marquee in my hand?</li> </ul> <script> // Core principle of event delegation: add listeners to the parent node and use event bubbles to affect each child node var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { // e.target This object we click on e.target.style.backgroundColor = 'pink'; }) </script>
1.4. Common mouse events
1.4.1 Case: No Selection of Text and No Right-click Menu
<body> I am a piece of text that I don't want to share <script> // 1. contextmenu We can disable the right-click menu document.addEventListener('contextmenu', function(e) { e.preventDefault(); }) // 2. Prohibit selection of text selectstart document.addEventListener('selectstart', function(e) { e.preventDefault(); }) </script> </body>
1.4.2 Mouse Event Object
1.4.3 Get the mouse coordinates on the page
<script> // MouseEvent mouse event object document.addEventListener('click', function(e) { // 1. client mouse x and y coordinates in the viewable area console.log(e.clientX); console.log(e.clientY); console.log('---------------------'); // 2. The x- and y-coordinates of the page mouse in the page document console.log(e.pageX); console.log(e.pageY); console.log('---------------------'); // 3. The x- and y-coordinates of the screen mouse on the computer screen console.log(e.screenX); console.log(e.screenY); }) </script>
1.4.4 Cases: An Angel Following the Mouse
<img src="images/angel.gif" alt=""> <script> var pic = document.querySelector('img'); document.addEventListener('mousemove', function(e) { // 1. Mosemove triggers this event whenever we move the mouse 1px // 2. Core Principle: Every time the mouse moves, we get the latest mouse coordinates. // Use this x and y coordinates as top and left values to move the picture var x = e.pageX; var y = e.pageY; console.log('x Coordinates are' + x, 'y Coordinates are' + y); //3.Don't forget to add px units to left and top pic.style.left = x - 50 + 'px'; pic.style.top = y - 40 + 'px'; }); </script>