Basic concept
- When the browser reads the file content, it does not immediately parse and draw the interface. Instead, it first parses the label into an object and constructs a DOM tree, and then renders the tree according to the DOM tree + CSS to draw the interface. (The page is redrawn as soon as the element object in the DOM tree changes).
- Dom objects are created from tags in HTML code, and each tag creates a Dom object, which together form a Dom tree.
- WebAIP: BOM and DOM, a set of browser-provided apis that modify and manipulate objects in the DOM tree to control page interaction. (A series of methods that browsers give us to use)
- Event three elements: event source, event type, and event handler
DOM
Access to elements
// Return null if no element is found
document.querySelector('.box');/ / class
document.querySelector('#nav');// id
document.querySelector('li');// The first li
document.querySelectorAll('li');/ / all li
document.querySelector('.box').querySelectorAll('li');
// Get the body tag
document.body;
// Get the HTML tag
document.documentElement;
Copy the code
Operating elements
Changing element content
// It can be modified or read
div.innerText='Returns the content inside the tag (does not contain HTML tags) does not recognize HTML tags';
div.innerHTML='Recognize HTML tags (recommended)';
<div><p>What's inside</p></div>
div.innerText; // The contents
div.innerHTML;
Copy the code
Common property operations
// It can be modified or read
src/href
id/alt/title
img.src='/images/zxy.jpg';
Copy the code
Form property operations
// It can be modified or read
#input/textarea/select
type/value/checked/selected/disabled
<input type="checkbox" checked>
input.checked;// True if checked, false if unchecked
Copy the code
Style property operations
You can only get inline style sheets
// Can only be modified
#1.Div. Style Inline style manipulation// Take the hump nomenclature
- div.style.backgroundColor='blue';
- div.style.color='blue';
- div.style.display='none';
#2.Div. ClassName className style operation// Changes its class name directly, overwriting the original class name
- div.className='first change';
- div.className=' ';
Copy the code
Exclusive ideas
// Optimization of exclusivity
let lis = document.querySelectorAll('li');
for (let i = 0; i < lis.length; i++) {
// All buttons. Onclick share a method!!
lis[i].onclick = click;
}
// Exclusive function (public)
function click() {
// Kill everyone
for (let i = 0; i < lis.length; i++) {
lis[i].style.backgroundColor = 'lightcoral';
}
Leave me alone
this.style.backgroundColor = 'lightblue';
}
Copy the code
Classlist properties
The classList attribute is a new HTML5 attribute that returns the class name of an element. But IE10 and later support it.
Add the class:
Element.classlist.add (‘ class name ‘);
focus.classList.add('current');
Copy the code
Remove the class:
Element.classlist. remove (‘ class name ‘);
focus.classList.remove('current');
Copy the code
Switch:
Element.classlist. toggle (‘ class name ‘);
focus.classList.toggle('current');
Copy the code
Note: in the above method, all class names are not marked
Attribute operation
Dom element attributes
- Standard properties
- Browsers create DOM objects based on HTML tags, and the attributes in the objects are standard attributes
- For example, id, name, style, type….
Note: To get the style. property, you can only get inline styles.
- Operation mode: Directly through the object. Property name
- Get the property value:
dom.name
- Set the property value:
dom.checked=true
- The standard properties of the DOM cannot be deleted
Delete dom.name// Cannot be deleted
- Get the property value:
let o={a:'123'.b:'456'};
delete o.a;
console.log(o);//{b:'456'};
Copy the code
-
Custom attributes
-
Because custom attributes are not added to the DOM object, but are placed in attributes within the DOM object, they cannot be used directly through the DOM. Custom property to get
-
Attributes that programmers add to the DOM through HTML tag syntax or DOM syntax
-
Such as < a href = “1. HTML” mydog = “Ricky” > < / a >
-
How it works: you must use dom.getarrtribute () and dom.setarrtribute ()
- Get the property value:
dom.getArrtribute('mydog'); // ricky
- Set the property value:
dom.setArrtribute('mydog','motty')
- Add custom attribute values:
dom.setAttribute('mycat','miao')
- Delete a custom attribute:
dom.removeAttribute('mydog');
- Get the property value:
-
-
H5 Custom Attributes (data-)
- Operation mode:
- Get the property value:
Dom. GetArrtribute (' property ')
orThe dom. The dataset. Properties
- Set/Add attributes:
dom.setArrtribute('mydog','motty')
; ordom.dataset.mycat='miao';
- Delete a custom attribute:
dom.removeAttribute('mydog');
ordelete dom.dataset.mycat;
- Get the property value:
- Operation mode:
Note:
- GetAttribute and setAttribute are versatile, and various attributes can be obtained or manipulated
- Add your own custom attributes and try to start with data-
added
-
Set custom properties by dot
① The attribute can be set successfully, but it is not set in the tag. It will not be displayed in the tag.
(2) The dot call can get the attribute value, but the getAttribute method cannot
-
Set attributes using the setAttribute method
(1) You can set the attribute successfully and set it in the label
② You must use the getAttribute method to obtain the attribute value
Node operation
Everything node
- The browser parses the HTML page and creates the contents of the page as node objects
- Node objects have many types and all have the same three properties: nodeType, nodeName, and nodeValue
- Common node types:
- Element nodes: Generated from HTML tags
- Text node: The text inside or outside the tag
- Comment node
Gets the label name of the node
e.target.nodeName=='A';// Label names should be capitalized
e.target.tagName=='A'
ol.addEventListener('click'.function(e) {
if (e.target.nodeName == 'A') {
letli = e.target.parentNode; ol.removeChild(li); count--; todocount.innerHTML = count; }})Copy the code
parent-child
-
The parent node
-
Dom. parentNode will find all nodes of the parent (including text nodes, etc.)
-
Dom.parentelement will only find the parentElement node
-
They differ only when the parent HTML tag is removed, but otherwise the parent element is removed and the effect is the same.
// Document. documentElement is an HTML tag, and its parent element is document, not a tag - document.documentElement.parentNode;// #document - document.documentElement.parentElement;// null Copy the code
-
-
Child nodes
ul.childNodes
, find all child nodes (element nodes text nodes, etc.)ul.children
It is also us to get all child element nodesThe actual developmentThe commonly usedol.children[0] / ol.children[ol.children.length - 1]
.The actual developmentIs written without compatibility problems and returns the first childol.firstChild / ol.lastChild
, the first/last child node whether text node or element nodeol.firstElementChild / ol.lastElementChild
, returns the first child element node supported only by IE9
Brother nodes
-
The nextSibling contains element nodes or text nodes and so on
- div.nextSibling
- div.previousSibling
-
NextElementSibling Gets the next sibling node, recommended (incompatible before IE9)
- div.nextElementSibling
- div.previousElementSibling
-
Get all sibling nodes
for(let li of lis){ li.onclick= liClick; } function liClick(){ let arrNext=[]; let nextE=this.nextElementSibling; // When the next sibling of the element can still be found while(nextE){ arrNext.push(nextE); nextE=nextE.nextElementSibling; } console.log(arrNext); } Copy the code
Create/Add/remove element nodes
A dynamically created/added element node. Note that the node cannot be obtained externally
// 1. Create node element node (existing in content)
var li = document.createElement('li');
Node. appendChild(child) Node's parent child is an append element similar to the push element in an array
ul.appendChild(li);
InsertBefore (create dom, specify element);
var lili = document.createElement('li');
ul.insertBefore(lili, ul.children[0]);
RemoveChild (child element);
ul.removeChild(ul.children[0]);
Copy the code
Copy the node
// Make a copy of the node. All properties of the node are copied.
1.Shallow copy ()/(false) copies only the current element itself, not the child node node.clonNode();2.Deep copy (true) copies the contents of the current element, including its children node.clonNode(true);
Copy the code
Get focusinput.focus()
// 1. Autofocus, the page is automatically focused when loaded
<textarea name="" id="" autofocus></textarea>
<button disabled>release</button>
// 2. Text.focus (), click button to make the textbox focus;
button.onclick=function(){
text.focus();
}
// 3.
<label for="male">Male</label>
<input type="radio" name="sex" id="male" />
Copy the code
Message Posting Cases
<body>
<textarea name="" id="" autofocus></textarea>
<button disabled>release</button>
<ul>
</ul>
<script></script>
</body>
Copy the code
Dynamically generate cell cases
<body>
<table cellspacing="0">
<thead>
<tr>
<th>The name</th>
<th>subjects</th>
<th>results</th>
<th>operation</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 1. Prepare students' data first
var datas = [{
name: 'Wei Yingluo'.subject: 'JavaScript'.score: 100
}, {
name: 'hong li'.subject: 'JavaScript'.score: 98
}, {
name: 'Fu Heng'.subject: 'JavaScript'.score: 99
}, {
name: 'MingYu'.subject: 'JavaScript'.score: 88
}, {
name: 'Big pig trotter'.subject: 'JavaScript'.score: 0
}];
let tbody = document.querySelector('tbody')
// Iterate over the number group to generate data rows
for (let stu of datas) {
let tr = document.createElement('tr');
tbody.appendChild(tr);
// Iterate over the student object to generate cells
for (let k in stu) {
let td = document.createElement('td');
td.innerHTML = stu[k];
tr.appendChild(td);
}
// Generate delete cells
let del = document.createElement('td');
del.innerHTML = ' delete < / a > ';
tr.appendChild(del);
// Add click event to delete button
del.onclick = delClick;
}
function delClick() {
let isOk = confirm('Are you sure you want to delete it? ');
if (isOk) {
tbody.removeChild(this.parentNode);
} else {
return; }}</script>
</body>
Copy the code
Three dynamically created element differences
-
Document.write () creates the element if the page document flow has been loaded, calling this statement will cause the page to be redrawn
123var btn = document.querySelector('button'); btn.onclick = function() { document.write('<div>123</div>'); } Copy the code -
InnerHTML creates the element
var inner = document.querySelector('.inner'); // Method 1: string concatenation (slowest) // The reason for the slow: // 1. Each time the HTML code is parsed, the DOM object is generated, the DOM tree is added, and the page is redrawn (most time-consuming). // 2. Each loop resets the innerHTML of the body, causing the page to be redrawn 1000 times console.time();// Start the timer for (var i = 0; i <= 1000; i++) { inner.innerHTML += ' } console.timeEnd();// End the timer // Array concatenation (fastest) // Fast reason: 4ms // Create 1000 DOM objects by setting the innerHTML of all generated tags at once // You only need to parse the code once and redraw the page once var arr = []; for (var i = 0; i <= 1000; i++) { arr.push('); } inner.innerHTML = arr.join(' '); Copy the code
-
Document.createelement () creates the element
for (var i = 0; i <= 1000; i++) { var a = document.createElement('a'); document.body.appendChild(a); } // Speed is in the middle // Slow cause: 17ms // 1. Create objects 1000 times // 2. Redraw the page 1000 times Copy the code
-
document.createDocumentFragment()
// Create code snippets (to temporarily store newly created DOM objects) var frag = document.createDocumentFragment(); for (var i = 0; i <= 1000; i++) { var a = document.createElement('a'); frag.appendChild(a); } // Add code snippets to body (add 1000 internal divs to body at once) document.body.appendChild(frag); // Slow cause: 7ms // 1. Create objects 1000 times // 2. Add 1000 objects to the page once and redraw the page once Copy the code
The event, a senior
An event is essentially a property of an object, and the added function is its property value.
Register events (2 ways)
-
Traditional registration (starting with ON)
- Uniqueness of registered events
- Only one handler can be set for an element and an event. If there are more than one, subsequent registrations will override the previous one
- Level 0 DOM events
- Properties are added directly to dom objects
-
Listener registration (addEventListener())
-
W3c standard recommendation (not supported before IE9, can use attachEvent()- not recommended instead)
-
Multiple listeners can be registered for the same element and event
-
By default, they are executed in the order of registration
-
Level 2 DOM events
-
Properties are not added to DOM objects, but to the in-memory dom event table at level 2 (virtual)
-
<script>
var btns = document.querySelectorAll('button');
// 1. Register events the traditional way
// hao a u
btns[0].onclick = function() {
alert('hi');
}
btns[0].onclick = function() {
alert('hao a u');
}
// 2. Register event addEventListener
// The event type inside (1) is the string must be quoted without on
// (2) Add more listeners to the same element and event
// 22 33
btns[1].addEventListener('click'.function() {
alert(22);
})
btns[1].addEventListener('click'.function() {
alert(33);
})
</script>
Copy the code
Delete event (unbind event)
-
Traditional Registration
- eventTarget.onclick=null;
-
Method listens for the registration mode
- eventTarget.removeEventListener(type, listener[, useCapture ]);
- eventTarget.detachEvent( eventNameWithOn , callback ); (Not recommended)
<script>
var divs = document.querySelectorAll('div');
divs[0].onclick = function() {
alert(11);
// 1. Delete events in the traditional way
divs[0].onclick = null;
}
// 2. RemoveEventListener Deletes the 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>
Copy the code
The DOM event flow
The event stream is the order in which events are received from the page
When events occur, they are propagated in a specific order before element nodes, which is called the DOM event stream
The DOM event flow goes through three stages:
-
Capture phase
-
Current target stage
-
Bubbling phase
If we throw a stone into the water, it will first have a descent process, which can be understood as the capture process from the topmost layer to the most specific element of the event (the target point); Bubbles are then created and float to the surface of the water after the lowest point (the most specific element), a process equivalent to event bubbling.
Note:
-
Js can only capture or bubble one of the phases.
-
Onclick and attachEvent only get the bubbling phase
-
The third parameter to add is useCapture
- True, the capture phase
- False (do not write default values), bubble phase
-
Pay more attention to events bubbling up
-
Some events are not bubbling, such as onblur, unfocus, onMouseEnter, onmouseleave
The event bubbling
// Click son to execute son's click event first... And finally document
<div class="father">
<div class="son">Son box</div>
</div>
<script>
// Onclick and attachEvent (ie) fire in the bubbling phase
If the third addEventListener parameter is false or omitted
// son -> father ->body -> html -> document
var son = document.querySelector('.son');
// Register the son click event
son.addEventListener('click'.function() {
alert('son');
}, false);
// Register the father click event
var father = document.querySelector('.father');
father.addEventListener('click'.function() {
alert('father');
}, false);
// Register the document click event, omitting the third argument
document.addEventListener('click'.function() {
alert('document');
})
</script>
Copy the code
Event capture
// Click son to execute document first... And finally son
<div class="father">
<div class="son">Son box</div>
</div>
<script>
// If the third addEventListener() argument is true then it is emitted during the capture phase
// document -> html -> body -> father -> son
var son = document.querySelector('.son');
// Register the son click event with the third parameter true
son.addEventListener('click'.function() {
alert('son');
}, true);
var father = document.querySelector('.father');
// Register the click event for father with the third parameter true
father.addEventListener('click'.function() {
alert('father');
}, true);
// Register the document click event with the third parameter true
document.addEventListener('click'.function() {
alert('document');
}, true)
</script>
Copy the code
The event object
After an event occurs, the collection of information data related to the event is put into this object, which is the event object.
Who bound the event, mouse position, which key was pressed, etc
Event objects are generated when an event firing occurs and are passed by the system as arguments to the event handler.
Event object compatibility handling
In IE6~8, the browser does not pass parameters to methods. If necessary, you need to go to window.event to look for them.
<div>123</div>
<script>
var div = document.querySelector('div');
div.onclick = function(e) {
// Event object
e = e || window.event;
console.log(e);
}
</script>
Copy the code
Properties and methods of the event object
The difference between e.target and this
-
This is the element of the event binding (the element that binds the event handler).
-
E.target is the element that triggers the event.
Usually terget and this are the same, but when the event bubbles (the parent element has the same event, and clicking on the child element triggers the parent element’s event handler), this refers to the parent element because it is the element object to which the event is bound. Target refers to the child element because it is the specific element object that triggered the event.
# event bubbling under e.target andthis
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
var ul = document.querySelector('ul');
// Click the li tag, the event will bubble to ul
ul.addEventListener('click'.function(e) {
// we bind the event to ul so this points to ul
console.log(this); // ul
// e.target is the object that triggered the event. We clicked on Li
console.log(e.target); // li
});
Copy the code
Blocking default behavior
Some tags in the HTML have default behaviors. For example, after a tag is clicked, the page is redirected by default.
# e.preventDefault();
<a href="http://www.baidu.com">baidu</a>
<script>
// 2. Prevent the default behavior from skipping links
var a = document.querySelector('a');
a.addEventListener('click'.function(e) {
e.preventDefault(); // dom standard
});
// 3. Traditional registration method
a.onclick = function(e) {
// common browser e.preventdefault (); Method ## recommend ##
e.preventDefault();
// Lower version Browser IE678 returnValue property
e.returnValue = false;
// We can also use return false to prevent the default behavior from being incompatible
// Note that the code after return does not execute and is limited to traditional registration
return false;
}
</script>
Copy the code
// When the form is clicked submit, the form's data is submitted by default.
// Can be added to the form to block the submit event, or to the submit button## It is recommended to submit events through the form, since forms can have multiple submit buttons and all submit the form, so it should be uniformly blocked in form submission eventslet fNode=document.querySelector('form');
fNode.addEventListener('submit'.function(e){
e.preventDefault();
});
Copy the code
// Prevents the default event from selecting text at the beginning of the page
document.addEventListener('selectstart'.function(e){
e.preventDefault();
})
Copy the code
Prevents events from bubbling
-
The standard of writing
e.stopPropagation(); // stop Stops Propagation Copy the code
-
Non-standard notation IE678
window.event.cancelBubble = true; // Nonstandard Cancel Cancels bubble Copy the code
<div class="father">
<div class="son">Son son</div>
</div>
<script>
var son = document.querySelector('.son');
// Register the son click event
son.addEventListener('click'.function(e) {
alert('son');
e.stopPropagation(); // stop Stops Propagation
window.event.cancelBubble = true; // Nonstandard Cancel Cancels bubble
}, false);
var father = document.querySelector('.father');
// Register the father click event
father.addEventListener('click'.function() {
alert('father');
}, false);
// Register the document click event
document.addEventListener('click'.function() {
alert('document');
})
</script>
Copy the code
Event delegation
Event delegates are also called event proxies, or event delegates in jQuery.
In plain English, you do not register events for child elements, register events for parent elements, and execute the processing code in the event of the parent element.
The principle of event delegation
-
Register events for the parent element and use event bubbling. When the child element’s event is triggered, it will bubble to the parent element and then control the corresponding child element.
-
That is, delegating the child element's events to the parent element via bubbling
-
Delegate to an existing element
The role of event delegation
- We only manipulated the DOM once, improving the performance of the program.
- Dynamically newly created child elements also have events.
- Application: By registering click events for UL, click events can be added to newly created Li in the future through event delegation
< button > new < / button ><ul>
<li>You know what? I should have a frame in hand!</li>
<li>You know what? I should have a frame in hand!</li>
<li>You know what? I should have a frame in hand!</li>
<li>You know what? I should have a frame in hand!</li>
<li>You know what? I should have a frame in hand!</li>
</ul>
<script>
let btnAdd = document..querySelector('button');
var ul = document.querySelector('ul');
// Dynamically add li
btnAdd.addEventListener('click'.function(e) {
let newLi = document.createElement('li');
newLi.innerHTML = '我是新加的li'+Math.radom();
ul.appendChild(li);
})
// The core principle of event delegation is to add listeners to the parent node and use event bubbling to affect each child node
// You can add click events to future li's
ul.addEventListener('click'.function(e) {
// e.target this will get the object we clicked on
e.target.style.backgroundColor = 'pink';
})
</script>
Copy the code
Common Mouse events
Example: Disable text selection and right-click menus
// Disable is usually to prevent the browser from displaying the default right-click menu, because you need to write the style function of the right-click menu, etc<body> I'm a text I don't want to share <script>// contextMenu we can disable the right menu
document.addEventListener('contextmenu'.function(e) {
e.preventDefault();
})
// 2. Disable selectStart
document.addEventListener('selectstart'.function(e) {
e.preventDefault();
})
</script>
</body>
Copy the code
mouseout
Note: Mouseout is triggered only when the mouse removes the edge of the target element, not when it “steps” over other elements
Pay attention to the point
- Mouseover and mouseout can fire in both parent and child elements, depending on the number of children when the mouse passes over an element.
- Mouseenter and mouseleave fire only on the parent element, and only once when the mouse moves over an element;
- When all four functions are used in parent elements, mouseover and mouseout fire before mouseEnter and mouseleave;
- In general:
- Mouseover is used with mouseout and mouseEnter is used with mouseleave
- Use mouseover and mouseout if there are no children inside the element.
- If the element has child elements, use mouseEnter and mouseleave to prevent events from bubbling.
Mouse event object
Get the coordinates of the mouse on the page (pageX)
// the MouseEvent object MouseEvent
document.addEventListener('click'.function(e) {
// 1. The client mouse is in view of the x and Y coordinates
console.log(e.clientX);
console.log(e.clientY);
console.log('-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -');
// 2. Page mouse over page document x and Y coordinates!! Focus!!!!!
console.log(e.pageX);
console.log(e.pageY);
console.log('-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -');
// 3. The mouse is in the x and Y coordinates of the computer screen
console.log(e.screenX);
console.log(e.screenY);
})
Copy the code
Case study: An angel with a mouse
<img src="images/angel.gif" alt="">
<script>
var pic = document.querySelector('img');
document.addEventListener('mousemove'.function(e) {
// 1. Mousemove will trigger this event whenever the mouse moves 1px
// 2. Core principle: Every time the mouse moves, we will get the latest mouse coordinates,
// Use the x and y coordinates as the top and left values to move the image
// Note that top left is the coordinate relative to the document
var x = e.pageX;
var y = e.pageY;
console.log(The x-coordinate is zero. + x, 'The y-coordinate is'. + 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>
Copy the code
Common keyboard events
Keyboard events
Execution order of three events: keyDown — keypress — keyup
Difference between keyUp and KeyDown
Text box content input and keyDown and keyUp order
-
The keyDown event is emitted before the text box has entered the content of the pressed button
-
Adds a key to a text box
-
When the key is lifted, the KeyUp event is triggered
In a text box, the keyUp event is usually used
Keyboard event object
KeyCode — returns the ASCII value of the value e.keycode===65 // determines whether to press the A key
Note:
- Onkeydown and onKeyUp are case insensitive, onKeyPress is
- In practice, onKeyDown and onKeyUp are used more often
Case: simulated jingdong key input content
// Add the event to keyDown
// 1. Trigger the document's keyDown event, which determines that if the s key is pressed, the text box gets focus
// 2. The text box gets focus
// 3. The browser will then type the pressed S key into the element currently in focus
// Add the event to keyUP
Trigger a keyDown event for the document, but in this case no keyDown event is added to the document, so nothing happens
// 2. The browser then presses the s key into the current focus element, but there is no focus element on the page, so nothing happens
// 3. Trigger the keyUp event of the document so that the text box gets focus
<input type="text">
<script>
// Get the input box
var search = document.querySelector('input');
// Register the keyUp event for document
document.addEventListener('keyup'.function(e) {
// Determine the value of keyCode
if (e.keyCode === 83) {
// Triggers a focus event for the input box
search.focus();
search.
}
})
</script>
Copy the code
Case: Simulate jingdong express tracking number query
Check whether the text box is empty: this.value.trim().length === 0
// Requirement: When we enter content in the text box, the text box automatically displays the content in large size.
<div class="search">
<div class="con">123</div>
<input type="text" placeholder="Please enter your tracking number" class="jd">
</div>
<script>
// Get the element to operate on
var con = document.querySelector('.con');
var jd_input = document.querySelector('.jd');
// Register the keyUp event for the input field
jd_input.addEventListener('keyup'.function() // Check whether the input box is emptyif (this.value.trim().length === 0) {
// If empty, hide the zoom prompt box
con.style.display = 'none';
} else {
// Not empty, display the enlargement prompt box, set the box content
con.style.display = 'block';
con.innerText = this.value; }})// Register the out-of-focus event for the input box, and hide the zoom prompt box
jd_input.addEventListener('blur'.function() {
con.style.display = 'none';
})
// Register the input field to get focus events
jd_input.addEventListener('focus'.function() {
// Check whether the input box is empty
if (this.value ! = =' ') {
// display the prompt box if it is not empty
con.style.display = 'block'; }})</script>
Copy the code
BOM
Summary of BOM
The Browser Object Model (BOM) is the Browser Object Model. It provides objects that interact with the Browser window independently of content. The core Object is window. Operating the browser
A BOM is made up of a series of related objects, each of which provides a number of methods and attributes.
BOM lacks standards. The standardization body for JavaScript syntax is ECMA, the standardization body for DOM is W3C, and BOM was originally part of the Netscape browser standard.
The BOM is larger than the DOM, and it contains the DOM.
Top-level object Window
-
Is an interface for JS to access the browser
-
Is a global object. Variables and functions defined in the global scope become properties and methods of the Window object
- The window can be omitted when called. Alert () and prompt() are window object methods
-
The next special property of window is window.name, so do not declare name in the global scope
Common events for window objects
Page (window) loading event (2 kinds)
Keep JS from having to be written at the bottom of an HTML file
1. The first one
- Window. onload is a window (page) load event,When the document content is fully loadedTriggers the event (
This includes images, scripts, and CSS files
) to call the handler function. - Cons: If the connection is slow, the user sees the button first, but it doesn’t work when clicked
// Traditional registration can only be written once ## normal code uses ##
window.onload = function(){}
// There is no limit
window.addEventListener("load".function(){})
Copy the code
2. The second
-
The DOMContentLoaded event is triggered only when the DOM is loaded, excluding stylesheets, images, Flash, etc.
-
IE9 support only above!!
-
Only level 2 registration can be used
-
If there are many pictures on the page, it may take a long time from user access to onload trigger, and the interactive effect will not be realized, which will inevitably affect the user experience. In this case, DOMContentLoaded event is appropriate.
document.addEventListener('DOMContentLoaded'.function(){})
Copy the code
Resize window events
window.addEventListener('resize'.function(){})
Copy the code
Window. onresize is a handler that adjusts the window size to load the event and is called when triggered.
Note:
-
This event is triggered whenever the window size changes by pixels.
-
We often use this event for reactive layout. Window. innerWidth Width of the current screen
<script>
// Register page loading event
window.addEventListener('load'.function() {
var div = document.querySelector('div');
// Register the resize window event
window.addEventListener('resize'.function() {
// window.innerWidth Gets the window size
console.log('Changed');
if (window.innerWidth <= 800) {
div.style.display = 'none';
} else {
div.style.display = 'block';
}
})
})
</script>
<div></div>
Copy the code
The timer
Bomb timer
SetTimeout () Bomb start timer
window.setTimeout(call function, [number of milliseconds delayed]);// setTimeout This calling function is called callback
// Window can be omitted
// The number of milliseconds omitted defaults to 0
// Calling a function can write the function directly, or write the function name, or 'function name ()' is not recommended
<script>
The callback function is an anonymous function
setTimeout(function() {
console.log('Time is up');
}, 2000);
function callback() {
console.log('Exploded');
}
Since there can be many timers, we often assign an identifier ## to timers
// The callback function is a named function
var timer1 = setTimeout(callback, 3000);// Return a single id
var timer2 = setTimeout(callback, 5000);
</script>
Copy the code
Stop timer
window.clearTimeout(timeoutID);// timeoutID is the timer identifier
Copy the code
Move the div box case
<style>
* {
padding: 0;
margin: 0;
}
div {
position: absolute;
width: 100px;
height: 100px;
background-color: lightcoral;
}
</style>
<script>
window.onload = function() {
let div = document.querySelector('div');
let start = document.querySelector('.start');
let stop = document.querySelector('.stop');
let timeId = null;
start.addEventListener('click'.function() {
if (timeId) return;
timeId = setInterval(function() {
let windowW = window.innerWidth - 100;
let xNum = parseInt(div.style.left);
console.log(xNum);
if (xNum >= windowW) {
clearInterval(timeId);
// timeId = null;
// return;
}
div.style.left = xNum + 10 + 'px';
}, 20);
stop.onclick = function() {
clearInterval(timeId);
timeId = null; }})}</script>
<button class="start">mobile</button>
<button class="stop">stop</button>
<div style="left: 100px"></div>
Copy the code
Alarm clock timer
SetInterval () Indicates that the alarm starts the timer
// Call the callback function at intervals
window.setInterval(call function, [number of milliseconds between calls]);Copy the code
Stop timer
window.clearInterval(intervalID);// timeoutID is the timer identifier
Copy the code
Countdown case
// 1. Get the element
var hour = document.querySelector('.hour'); // Hour black box
var minute = document.querySelector('.minute'); // Minute black box
var second = document.querySelector('.second'); // The number of seconds of the black box
var inputTime = +new Date('the 2019-10-25 18:00:00'); // Returns the total number of milliseconds the user entered
// call it once so that the page has content as soon as it loads
countDown();
// 2. Start the timer
setInterval(countDown, 1000);
function countDown() {
var nowTime = +new Date(a);// Returns the total number of milliseconds in the current time
var times = (inputTime - nowTime) / 1000; // times is the total number of seconds left
var h = parseInt(times / 60 / 60 % 24); / /
h = h < 10 ? '0' + h : h;
hour.innerHTML = h; // Give the remaining hours to the hour black box
var m = parseInt(times / 60 % 60); / / points
m = m < 10 ? '0' + m : m;
minute.innerHTML = m;
var s = parseInt(times % 60); // The current second
s = s < 10 ? '0' + s : s;
second.innerHTML = s;
}
Copy the code
This points to the problem
-
In a global scope or normal function, this refers to the global object Window.
-
Whoever calls this points to in a method call
-
Constructor this refers to an instance of the constructor
// 1. In the global scope or normal function, this refers to the global object Window.
function a(){
console.log(this);//window
}
a();// window.a();
window.setTimeout(function() {
console.log(this);// window
}, 1000); }// 2. Who calls this in the method call refers to who
var o = {
sayHi: function() {
console.log(this); // This refers to the object o
}
}
o.sayHi();
// 3. Constructor this refers to an instance of the constructor
function Fun() {
console.log(this); // This points to the fun instance
}
var fun = new Fun();
Copy the code
Location object
The location concept
URL
Location The property of the object
Key points: href and search
Href case
// The page is automatically displayed after 5 secondsClick < button > < / button ><div></div>
<script>
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.addEventListener('click'.function() {
// console.log(location.href);
location.href = 'http://www.itcast.cn';
})
var timer = 5;
setInterval(function() {
if (timer == 0) {
location.href = 'http://www.itcast.cn';
} else {
div.innerHTML = 'You will be in' + timer + 'Jump to home page in seconds'; timer--; }},1000);
</script>
Copy the code
The search case
# login.html
<form action="index.html">User name:<input type="text" name="uname">Password:<input type="password" name="password" id="">
<input type="submit" value="Login">
</form>
# index.html
<div></div>
<script>
let div = document.querySelector('div');
let data = UrlToObj(location.search);
// decodeURIComponent(data.uname) decodes Chinese
div.innerHTML = `The ${decodeURIComponent(data.uname)}Welcome, your password is:${data.password}`;
// Convert location.search to an object
function UrlToObj(urlParams) {
let strParams = urlParams.substr(1); // uname=jean&password=1234
let obj = {};
let arrParams = strParams.split('&') // ["uname=jean","password=1234"]
for (let p of arrParams) {
let key = p.split('='); // ['uname','jean']
obj[key[0]] = key[1]; // { uname: 'jean'}
}
return obj;
}
</script>
Copy the code
Common methods for location objects
Click < button > < / button ><script>
var btn = document.querySelector('button');
btn.addEventListener('click'.function() {
// Record the browsing history, so you can implement the backward function
// location.assign('http://www.itcast.cn');
// The browser history is not recorded, so you cannot implement the backward function
// location.replace('http://www.itcast.cn');
location.reload(true);
})
</script>
Copy the code
The navigator object
The Navigator object contains information about the browser and has a number of properties, the most common being the userAgent, which returns the value of the User-Agent header of the server sent by the client.
The following front-end code can determine which terminal users open the page, to achieve the jump
if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS |Symbian|Windows Phone)/i))) {
window.location.href = ""; / / cell phone
} else {
window.location.href = ""; / / computer
}
Copy the code
The history object
The Window object gives us a History object that interacts with the browser history. This object contains the URL that the user has visited (in the browser window).
The history object is rarely used in real development, but is found in some OA office systems.
The local store
Only strings can be stored; you can encode the object json.stringify () for storage
window.sessionStorage
1. The lifecycle is to close the browser window
2. Data can be shared in the same window (page)
3. Store and use in the form of key-value pairs
Storing data:
sessionStorage.setItem(key, value)
Copy the code
Get data:
sessionStorage.getItem(key)
Copy the code
Delete data:
sessionStorage.removeItem(key)
Copy the code
Clear data :(all cleared)
sessionStorage.clear()
Copy the code
window.localStorage
1, declare that the cycle is permanent, unless manually deleted or closed page will exist
2. Multiple Windows (pages) can be shared (the same browser can be shared)
3. Store them as key-value pairs
Storing data:
localStorage.setItem(key, value)
Copy the code
Get data:
localStorage.getItem(key)
Copy the code
Delete data:
localStorage.removeItem(key)
Copy the code
Clear data :(all cleared)
localStorage.clear()
Copy the code
JS execution mechanism
JS is single threaded
Single threading means that all tasks need to be queued until the first one is finished before the next one can be executed. If the first task takes a long time, the second task has to wait forever. The problem with this is that if the JS execution takes too long, the rendering of the page will be incoherent, causing the page rendering load to feel blocked.Copy the code
Synchronous and asynchronous tasks
All tasks in JS can be categorized into two types, synchronous and asynchronous. A synchronization task refers to a task that is queued to be executed on the main thread. The next task can be executed only after the first task is completed. Asynchronous tasks refer to tasks that do not enter the main thread but enter the "task queue". When the tasks in the main thread are finished, the asynchronous tasks are removed from the "task queue" and put into the main thread for execution.Copy the code
Callback function: the function is passed in as an argument
Event loop
Link and script tags
<! -- Link tag loads files asynchronously -->
<! When the browser encounters an external file with the link tag, it will make a separate request and continue executing the code itself.
<! -- Purpose: first display the page structure to the user, and then add style, beautify the interface -->
<link rel="stylesheet" href="01.css">
<! -- the script tag loads files synchronously -->
<! When the browser encounters an external file with a script tag, it will wait until the external JS file is loaded and continue to execute the following code.
<! * * * * * * * * * * * * * * * * * * * * *
<script src="01.js"></script>
<! Onload =function(){} -->
Copy the code
PC side web effects
Element offset series
Summary of offset
- Gets the element distance with the location of the parent element
- Directly gets the result of the last style position operation (composite style sheet = inline style + inline style + outer chain style)
- Get the size (width and height) of the element itself
- Note: The values returned do not have units
<div class="father">
<div class="son"></div>
</div>
<div class="w"></div>
<script>
/ / offset series
var father = document.querySelector('.father');
var son = document.querySelector('.son');
// 1. We can get the ununitless value returned by the offset position of the element
console.log(father.offsetTop);
console.log(father.offsetLeft);
// It takes the parent with the location. If there is no parent or the father has no location, the body will take the place
console.log(son.offsetLeft);
var w = document.querySelector('.w');
// 2. You can get the size, width and height of the element, including padding + border + width
console.log(w.offsetWidth);
console.log(w.offsetHeight);
// 3. Return the parent with the location otherwise return the body
console.log(son.offsetParent); // Return the parent with the location otherwise return the body
console.log(son.parentNode); // Return father is the closest level of father to father regardless of father location
Copy the code
Offset is different from style
offset
-
Offset can get the style value in any stylesheet
-
The values obtained by the offset series are ununitless
-
OffsetWidth contain padding + border + width
-
Properties such as offsetWidth are read-only and can only be obtained but cannot be assigned
-
So, we want to get the size of the element, offset is more appropriate
style
-
Style can only get style values from inline style sheets
-
Style.width returns a string with units
-
Style.width gets a value that does not contain the padding and border
-
Style. width is a read-write property that can be obtained or assigned
-
So, if we want to change the value of an element, we need to use a style change
Because we normally register touch events for elements, keep targetTocuhes in mind
Modal box drag and drop
// 1. Get the element
var login = document.querySelector('.login');
var mask = document.querySelector('.login-bg');
var link = document.querySelector('#link');
var closeBtn = document.querySelector('#closeBtn');
var title = document.querySelector('#title');
// Prevents the default event from selecting text at the beginning of the page
document.addEventListener('selectstart'.function(e){
e.preventDefault();
})
// 2. Click the pop-up link to make mask and login appear
link.addEventListener('click'.function() {
mask.style.display = 'block';
login.style.display = 'block';
})
Click closeBtn to hide mask and login
closeBtn.addEventListener('click'.function() {
mask.style.display = 'none';
login.style.display = 'none';
})
// 4. Start dragging
// (1) When we mouse down, we get the coordinates of the mouse inside the box
title.addEventListener('mousedown'.function(e) {
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
// (2) When the mouse moves, subtract the mouse's position in the page from the position in the box to create the left and top values of the modal box
// ### Since the mouse movement event can only be triggered when the mouse is pressed down, the main mouse can be moved in any position, so the event source is document
document.addEventListener('mousemove', move)
function move(e) {
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
}
// (3) Remove the mouse movement event
document.addEventListener('mouseup'.function() {
document.removeEventListener('mousemove', move); })})Copy the code
Magnifier effect
window.onload = function() {
/ / the preview
let preview_img = document.querySelector('.preview_img');
/ / mask layer
let mask = document.querySelector('.mask');
// Big box
let big = document.querySelector('.big');
/ / a larger version
let bigImg = document.querySelector('.bigImg');
// Mouse over, mask and large image display
preview_img.addEventListener('mouseover'.function(e) {
mask.style.display = 'block';
big.style.display = 'block';
})
// Mouse over, mask and large image hide
/ /!!!!! Mouseout must be triggered when the mouse moves the edge of the target element, not when it "steps" over other elements
preview_img.addEventListener('mouseout'.function(e) {
mask.style.display = 'none';
big.style.display = 'none';
})
// Mouse movement
preview_img.addEventListener('mousemove'.function(e) {
// Coordinates of the mouse inside the box
let x = e.pageX - this.offsetLeft;
let y = e.pageY - this.offsetTop;
// Coordinates of the mask layer = the coordinates of the mouse inside the box - half the size of the mask layer
let maskX = x - mask.offsetWidth / 2;
let maskY = y - mask.offsetHeight / 2;
// The maximum distance the mask layer can move inside the box = the width of the box - the width of the mask layer
let maskMax = this.offsetWidth - mask.offsetWidth;
// Limit the distance the mask can move
if (maskX < 0) {
maskX = 0;
} else if (maskX > maskMax) {
maskX = maskMax;
}
if (maskY < 0) {
maskY = 0;
} else if (maskY > maskMax) {
maskY = maskMax;
}
// The moving distance of the occlusion layer
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
// 3. Moving distance of large picture = moving distance of occlusion layer * maximum moving distance of large picture/Maximum moving distance of occlusion layer
// The maximum moving distance of a large image
bigMax = bigImg.offsetWidth - big.offsetWidth;
let bigX = maskX * bigMax / maskMax;
let bigY = maskY * bigMax / maskMax;
// The distance of the large image is X and Y
bigImg.style.left = -bigX + 'px';
bigImg.style.top = -bigY + 'px'; })}Copy the code
Element viewable client family
Taobao flexible. Js source code analysis
// flexible.js
(function flexible(window.document) {
// Get the root element of the HTML
var docEl = document.documentElement
// DPR physical pixel ratio
var dpr = window.devicePixelRatio || 1
// Adjust Body font size Sets the font size for our body
function setBodyFontSize() {
// If the page has the body element set the body font size
if (document.body) {
document.body.style.fontSize = (12 * dpr) + 'px'
} else {
// If the page does not have the body element, wait until the main DOM element of the page is loaded before setting the body element
// The font size
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10 Sets the text size of our HTML element
function setRemUnit() {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset REM unit on page resize When the page size changes, we need to reset the REM size
window.addEventListener('resize', setRemUnit)
// PagesHow is the event triggered when we reload the page
window.addEventListener('pageshow'.function(e) {
// e.persisted returns true, which means that if the page is cached, the rem size should also be recalculated
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports Some mobile browsers do not support 0.5 pixels
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window.document))
Copy the code
Execute function immediately
Main effect: Creates a separate scope. Naming conflicts are avoided
Problem solved: When importing multiple files, the same variable or function name is used in different files, resulting in variable contamination
Solution: Use self-executing functions to generate separate scopes in each j file to avoid variable contamination
(function(){}) () or (function(){} ())Copy the code
pageshow
The load event is triggered in each of the following three cases where the page is refreshed.
1. Hyperlink of a label
2.F5 or refresh button (forced refresh)
3. Forward and back buttons
But firefox features a “round-trip cache” that not only stores page data, but also the DOM and JavaScript state; In effect, the entire page is stored in memory.
So the back button cannot refresh the page at this point.
This can be triggered using the PagesHow event. This event is triggered when the page is displayed, whether the page is from the cache or not. In the reload page, pagesHow fires after the load event fires; The pagesHow event that is emitted from the page in the cache will be checked from the persisted event object in the event object. Notice that this event is added to the window.
Element scroll series
Scroll Outlines
Scroll translates to scroll, and we can use the related properties of scroll series to dynamically obtain the size and scrolling distance of the element.
The head of the page that is rolled out
Scroll bars appear automatically if the browser is not tall (or wide) enough to display the entire page. When the scroll bar scrolls down, the height of the page is hidden, we call the page rolled out of the head. The onScroll event is triggered when the scroll bar scrolls.
Fixed right sidebar (window.pageyoffset)
- The original sidebar was absolutely positioned
- When the page scrolls to a certain location, the sidebar changes to a fixed location
- If the page continues to scroll, the return to the top will appear
Note:
- The rolled out header for an element is element.scrollTop, or for a page
window.pageYOffset
.- PageYOffset can be obtained from window.pageYOffset on the left if it is window.pageXOffset
- If the value is greater than or equal to this value, the box can be fixed (note:
OffsetTop is relative to body
(the top of the entire page), the smaller the page scrolls.) Fixed positioning is relative to the window (browser viewable area)
In terms of,Absolute positioning
Is relative to the location of the parent box, if there is no parent box, relative tobody
(Top of the entire page)
let sliderbar = document.querySelector('.slider-bar');
let goBack = document.querySelector('.goBack');
let banner = document.querySelector('.banner');
let main = document.querySelector('.main');
// banner. OffestTop is the size of the page with the head rolled off. This value does not change as the page scrolls
let bannerTop = banner.offsetTop;
// The top value when the sidebar is absolutely positioned at the beginning
let sliderbarTop = sliderbar.offsetTop;
// The value that should change when our sidebar is fixed
let sliderbarTop1 = sliderbarTop - bannerTop;
// Record the initial top value of main
let mainTop = main.offsetTop;
document.addEventListener('scroll'.function() {
// The sidebar should be fixed when the page is rolled to a head greater than or equal to bannerTop
if (window.pageYOffset >= bannerTop) {
sliderbar.style.position = 'fixed';
// Remember to add px units
sliderbar.style.top = sliderbarTop1 + 'px';
} else {
sliderbar.style.position = 'absolute';
sliderbar.style.top = sliderbarTop + 'px';
}
// When we scroll to the main box, the goback module is displayed
if (window.pageYOffset >= mainTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none'; }})Copy the code
Series summary – to be added
Their main uses:
1. The offset family is often used to get the element position offsetLeft offsetTop
2. Client is often used to get the element size clientWidth clientHeight
3. Scroll is often used to obtain the scrolling distance scrollTop scrollLeft
4. Note that the scrolling distance of the page is obtained from window.pagexoffset
5. Mouse series
window
window.pageYOffset
// Page scroll event
document.addEventListener('scroll'.function() {
// When we scroll to the main box, the goback module is displayed
if (window.pageYOffset >= mainTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none'; }})Copy the code
window.scroll()
window.scroll(x-coord, y-coord)
window.scroll(options)
// The x-coord value represents the x-coordinate of the pixel you want to place in the upper left corner.
// The y-coord value indicates the ordinate of the pixel you want to place in the upper left corner.
/ / sample<! -- Put the vertical axis on the100Three pixels at the top of the window --><button onclick="window.scroll(0, 100);">Click to scroll down 100 pixels</button>
/ / using the options:
window.scroll({
top: 100.left: 100.behavior: 'smooth'
});
Copy the code
The difference between mouseEnter and mouseover
- Mouseover is triggered when the mouse moves over its own box or over a child box. The mouseEnter is only triggered by its own box
- Mouseover —– is triggered whenever the mouse is over the box (even if there are sub-boxes on the box)
- Mousenter —— Entering its own box (containing the boundaries of the child box) triggers, at which point the child box and its parent can be seen as one
- And the reason for that is because
Mouseenter does not bubble
- Mouseleave also does not bubble when the mouse leaves the mouseEnter
- When all four functions are used in parent elements, mouseover and mouseout fire before mouseEnter and mouseleave;
Animation function
How animation works
Core principle: Continuously move the box position through timer setInterval().
Implementation steps:
- Gets the current position of the box
- Add one movement distance to the current position of the box
- Repeat this with a timer
- Add an end timer condition
- Note that this element needs to be positioned to use element.style.left
Animation function encapsulation
If more than one element uses the animation function, var declares the timer each time. We can use different timers for different elements (we use our own timer exclusively).
Core principle: using JS is a dynamic language, can be very convenient to add attributes to the current object.
function animate(dom, target) {
// As we click the button over and over again, the element gets faster and faster because there are too many timers on
// The solution is to have our element execute with only one timer
// Clear the previous timer and keep the current one running
clearInterval(dom.timerId);
dom.timerId = setInterval(function() {
if (dom.offsetLeft >= target) {
// Stop animation is essentially stop timer
// Return is added to stop the current timer from executing down
return clearInterval(dom.timerId);
}
dom.style.left = dom.offsetLeft + 1 + 'px';
}, 20);
}
// Call the function
animate(div, 300);
// Click btn1 to start the span animation
btn1.addEventListener('click'.function() {
animate(span, 200);
})
// Click btn2 to stop the span animation
btn2.addEventListener('click'.function() {
clearInterval(span.timerId)
})
Copy the code
Principle of slow motion effect
A slow animation is an element that moves at a different speed, most commonly to a slow halt
Ideas:
- Let the box move a smaller distance each time, the speed will slow down.
- Core algorithm:
(Target value - current position) / 10
As the distance step of each move - The stop condition is: make the current box position equal to the target position to stop the timer
- Note that the step size needs to be rounded
function animate(dom, target) {
// Clear the previous timer and keep the current one running
clearInterval(dom.timerId);
dom.timerId = setInterval(function() {
// Since the last few steps move 1px, you must reach the target position
if (dom.offsetLeft == target) {
// Stop animation is essentially stop timer
// Return is added to stop the current timer from executing down
return clearInterval(dom.timerId);
}
// Write the step value to the inside of the timer =(target value - current position) / 10
var step = (target - dom.offsetLeft) / 10;
// If step>0, it is moving to the right. Round up (0.2=>1); Otherwise, it moves to the right and needs to be rounded down (-1.2 => -2)
step= step > 0 ? Math.ceil(step) : Math.floor(step);
// Change the integral by 1 to a progressively smaller value
dom.style.left = dom.offsetLeft + step + 'px';
}, 20);
}
Copy the code
Animation function moves between multiple target values
You can move the animation function from 800 to 500.
When we click the button, determine whether the step size is positive or negative
1. If the value is positive, the step size is rounded to a larger value
2. If the value is a negative value, the step size is rounded from a smaller value
var step = (target - dom.offsetLeft) / 10;
// If step>0, it is moving to the right. Round up (0.2=>1); Otherwise, it moves to the right and needs to be rounded down (-1.2 => -2)
step= step > 0 ? Math.ceil(step) : Math.floor(step);
Copy the code
The action function adds the callback function
How callback functions work: A function can be taken as an argument. Passing this function as an argument to another function, and then executing the function when that function is finished, is called a callback.
Where the callback function is written: where the timer ends.
callback && callback instanceof Function && callback();
function animate(dom, target, callback){
if (dom.offsetLeft == target) {
Callback is called if callback exists and is a function
callback instanceof Function && callback();
// Stop animation is essentially stop timer
// Return is added to stop the current timer from executing down
return clearInterval(dom.timerId); }}Copy the code
Web page rotation map
Also known as the focus graph, it is a common webpage effect in web pages.
Functional requirements:
1. When the mouse passes over the multicast diagram module, the left and right buttons are displayed, and the left and right buttons are hidden when the mouse leaves.
2. Click the button on the right once to play the picture to the left, and so on.
3. While the picture is playing, the following small circle module changes along with it.
4. Click the small circle to play the corresponding picture.
5. If the mouse does not move over the image, the image automatically plays.
- Auto play function: equivalent to manually call click button event on the right
arrow_r.click();
6. When the mouse passes, the rotation graph module stops automatically.
let timerF = false;
focus.addEventListener('mouseenter'.function() {
// Suspends the auto-playing of the carousel graph
timerF = true;
});
focus.addEventListener('mouseleave'.function() {
// The rotation chart continues to play automatically
timerF = false;
});
setInterval(function() {
// If true, pause playback
if (timerF) return;
// Manually invoke the right click event
arrow_r.click();
}, 2000)
Copy the code
The complete code
window.addEventListener('load'.function() {
/ / the left arrow
let arrow_l = document.querySelector('.arrow-l');
/ / right arrow
let arrow_r = document.querySelector('.arrow-r');
// Round the box
let focus = this.document.querySelector('.focus');
let focusWidth = focus.offsetWidth;
// Determine whether to pause auto play
let timerF = false;
// 1. The arrow is displayed when the mouse cursor moves over the wheel cast graph
focus.addEventListener('mouseenter'.function() {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
// Suspends the auto-playing of the carousel graph
timerF = true;
});
// 2. Hide the arrow when the mouse cursor moves out of the cast image
focus.addEventListener('mouseleave'.function() {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
// The rotation chart continues to play automatically
timerF = false;
});
// Get the father ol of the bottom dot
let ol = this.document.querySelector('.circle');
// Get the parent ul of the focus graph
let ul = focus.querySelector('ul');
// 3. Dynamically generate small dots. If there are several images, generate several small dots
for (let i = 0; i < ul.children.length; i++) {
let li = document.createElement('li');
// Record the current dot index number
li.setAttribute('index', i);
ol.appendChild(li);
}
// 4. Bind the dot's click event to the father'S OL through event delegate
ol.addEventListener('click'.function(e) {
// Remember to check whether the current clicked node is li (possibly a text node)
if (e.target.nodeName == 'LI') {
// Set the current class name exclusively
for (let li of this.children) {
li.className = ' ';
}
e.target.className = 'current';
// Get the current li index
let index = e.target.getAttribute('index');
// When we click on a small li, we need to give the index number of the li to num and circle
num = index;
circle = index;
// 5. Click the small circle and move the image to ul
// the index of the small circle multiplied by the width of the image is negativeanimate(ul, -index * focusWidth); }});// Add current class name to the first dot by default
ol.children[0].className = 'current';
// 6. Clone the first image (li) and put it at the end of ul
let first = ul.children[0].cloneNode(true);
ul.appendChild(first);
// 7. Click the button on the right to scroll a picture
// Record the index of the image
let num = 0;
// Record the index of the small circle
let circle = 0;
/ / throttle valve
let flag = true;
arrow_r.addEventListener('click'.function() {
// 10. Only when one picture animation is finished, open the throttle and proceed to the next animation
if (flag) {
// Close the throttle valve
flag = false;
// If we get to the last image, our ul will quickly undo the left to 0
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth, function() {
// Open the throttle valve
flag = true;
});
// 8. Click the button on the right to change the small circle. You can declare another variable to control the playing of the small circle
circle++;
// If circle == 4, we have reached the end of the cloned image
if (circle == ol.children.length) {
circle = 0;
}
circleChange();
}
})
arrow_l.addEventListener('click'.function() {
// 10. Only when one picture animation is finished, open the throttle and proceed to the next animation
if (flag) {
// Close the throttle valve
flag = false;
// If we get to the first image, our ul should quickly reach the last image
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = -num * focusWidth + 'px';
}
num--;
animate(ul, -num * focusWidth, function() {
// Open the throttle valve
flag = true;
});
// 8. Click the button on the right to change the small circle. You can declare another variable to control the playing of the small circle
circle--;
// If circle <0, you have reached the first image and need to jump to the last small circle
if (circle < 0) {
circle = ol.children.length - 1; } circleChange(); }})// As the image changes, the small circle changes
function circleChange() {
for (let li of ol.children) {
li.className = ' ';
}
ol.children[circle].className = 'current';
}
// 10
setInterval(function() {
// If true, pause playback
if (timerF) return;
// Manually invoke the right click event
arrow_r.click();
}, 2000)})Copy the code
Throttle valve
To prevent fast playback caused by continuous clicking of the rotation chart button.
Choke valve purpose: When the previous function animation content is finished, to execute the next function animation, so that the event can not fire consecutively.
Core implementation idea: use callback function, add a variable to control, lock function and unlock function.
Start setting a variable var flag= true;
If(flag){flag = false; Do something} Turn off the tap
Using the callback function animation after execution, flag = true turn on the tap
arrow_l.addEventListener('click'.function() {
// Only when a picture animation is complete, open the throttle and proceed to the next animation
if (flag) {
// Close the throttle valve
flag = false;
.
.
animate(ul, -num * focusWidth, function() {
// Open the throttle valve
flag = true; }); ..}})Copy the code
A touch screen event
A touch screen event
Touch event object
Because we normally register touch events for elements, keep targetTocuhes in mind
The mobile side drags elements
- Touchstart, TouchMove, and TouchEnd can implement dragging elements
- But the drag element requires the current finger coordinate value. We can use pageX and pageY inside targetTouches[0]
- The principle of moving terminal drag: finger movement, calculate the distance of finger movement. Then take the original position of the box + the distance your finger moves
- Distance of finger movement: the position of the finger in the slide minus the position of the finger at the beginning of the touch
Drag elements in three steps:
(1) Touch element touchStart: to obtain the initial coordinates of the finger and the original position of the box
(2) Touchmove finger: calculate the sliding distance of finger and move the box
(3) Leave the finger touchend:
Note: finger movement also triggers scrolling so prevent default scrolling here. E.preventdefault ();
Click delay solution
The mobile click event has a 300ms delay because the mobile screen double tap to zoom the page.
Solution:
1. Disable zooming. The browser disables the default double click zoom behavior and removes the 300ms click delay.
<meta name="viewport" content="user-scalable=no">
Copy the code
2. Use the Touch event to encapsulate the event itself to resolve the 300ms delay.
The principle is:
- When we touch the screen with our finger, we record the current touch time
- When our finger leaves the screen, subtract the touch time from the time it leaves
- If the time is less than 150ms and the screen has not been swiped, we define it as a click
The code is as follows:
// Encapsulate tap to solve click 300ms delay
function tap (obj, callback) {
var isMove = false;
var startTime = 0; // Record the time variable when touching
obj.addEventListener('touchstart'.function (e) {
startTime = Date.now(); // Record the touch time
});
obj.addEventListener('touchmove'.function (e) {
isMove = true; // See if there is a slide. If there is a slide, it is drag, not click
});
obj.addEventListener('touchend'.function (e) {
if(! isMove && (Date.now() - startTime) < 150) { // Click if the finger touch and leave time is less than 150ms
callback && callback(); // Execute the callback function
}
isMove = false; // take the reverse reset
startTime = 0;
});
}
/ / call
tap(div, function(){ // execute code});
Copy the code
- Use plug-ins. The FastClick plug-in solves the 300ms delay.
Making website
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded'.function() {
FastClick.attach(document.body);
}, false);
}
Copy the code