DOM
1 basic sentence
Get element:
getElementByld: get the element object with ID
getElementByTagName(): Get a certain type of tag element
getElementsByClassName('class name'), get some element collection according to the class name
querySelector('selector') Returns the first element object according to the specified selector, and the selector needs to be marked with .class, #id
querySelectorAll('selector') returns a collection of all objects of the specified selector
document.body //return body element object
document.documentElement //return html element object
Element attribute value:
Get element attribute value:
element.property gets the built-in property value
element.getAttribute('attribute') custom attribute added by itself, compatibility acquisition
Note: The custom object data-... is stipulated, and dataset is a collection that stores all custom attributes starting with data
Added in H5, ie11 starts to support: element.dataset**.index** or element.dataset**['index']**, it can only get the beginning of data-
Modify element attribute value
element.attribute = 'value'
element.setAttribute('attribute','value')
remove attribute
removeAttribute(‘index’);
mouse event
mouse event | Triggering conditions |
---|---|
onclick | Triggered by left mouse click |
onmouseover | mouse over start |
onmouseout | mouse left |
onfocus | get mouse focus trigger |
onblur | lose mouse focus |
onmousemove | mouse move start |
mouseup | Mouse up trigger |
onmousedown | mouse down trigger |
mouseover和mouseenter
mouseenter mouse event
The mouseenter event is fired when the mouse moves over the element
The difference is: the mouseover will be triggered when the mouse passes through its own box, and it will also be triggered when it passes through the sub-box. mouseenter will only be triggered by its own box (sub-boxes will not be triggered (there is no concept of bubbling))
Mouseenter and mouseleave will also not bubble
operating elements
element.innerText: The content from the start position to the end position, but it removes html tags, and spaces and newlines are also removed
element.innerHTML: the entire content from the start position to the end position, including html tags, while retaining spaces and newlines
node operation
Use the parent-child sibling node relationship to obtain elements, which is logical but poorly compatible
All content in a web page is a node (label, attribute, text, comment, etc.), which is represented by a node in the DOM.
Generally, a node has at least three basic attributes: nodeType (node type), nodeName (node name), and nodeValue (node value).
- Element node: nodeType is 1, generally the main operation element node
- Attribute node: nodeType is 2
- Text node: nodeType is 3 (text nodes include text, spaces, newlines, etc.)
parent node:
node.parentNode: get the parent node closest to the element, if no parent node can be found, return null
child node:
parent.childNodes (standard) Returns the collection containing the children of the specified node, which is an immediately updated sum. A certain one is .childNodes[i]
parent.children (non-standard), but also supported by browsers
parentNode.firstChild returns the first node, whether it is a child node or an element node, including a newline node
parentNode.lastChild returns the last node
parentNode.firstElementChild returns the first child element node, there may be compatibility issues
parentNode.lastElementChild returns the last child element node
In actual development, there is no compatible way of writing
xx.children[0]
xx.children[xx.children.length-1]
Brother node:
node.nextSibling: Returns the next sibling node of the current element (including newline), if not found, returns null
node.previousSibling: returns the previous sibling node of the current element (including newline), if not found, return null
node.nextElementSibling: returns the next sibling element node of the current element, supported by ie9 and above
node.previousElementSibling: returns the previous sibling element node of the current element, supported by ie9 and above
Solving Compatibility: Encapsulating Functions by Yourself
function getNextElementSibling(element){
var el = element;
while(el = el.nextSibling){
if(el.nodeType === 1){
return el;
}
}
return null;
}
Create a (element) node:
document.createElement(‘tagName’)
Create HTML elements specified by tagName, because these elements do not exist, dynamically generated according to requirements
Add nodes:
node.appendChild(child): node is the parent, child is the child
Adds a node to the end of the list of children of the specified parent node, that is, appends elements after it. Similar to the after pseudo-element in css and the push in the array.
node.insertBefore(child, specified element)
Adds a node to the parent node in front of the specified node. Similar to the before pseudo element in css
ul.insertBefore(lili,ul.children[0]);//实现了在ul.children[0]前面插入子节点lili
delete node:
node.removeChild(child)
returns the deleted node
ul.removeChild(ul.children[0])
Copy node (clone node):
node.cloneNode() returns a copy of the node on which this method was called.
Bracket parameters: empty or false is a shallow copy, only the copy node itself is cloned without copying the content inside
true deep copy, copy the content inside the tag.
ul.children[0].cloneNode(true)
The difference between the three creation elements:
1. document.write(): directly writes the content into the content flow of the page, but after the document is executed, it will cause the entire page to be redrawn.
document.write('<div>123</div>')
2. element.innerHTML: write content to a DOM node without redrawing the entire page
var xx = document.querySelector('.xx');
xx.innerHTML = '<a herf='#'>百度</a>'
3. document.createElement(): Create multiple elements, which is more efficient than innerHTML, because innerHTML uses splicing
var xx = document.querySelector('.xx');
var a = document.createElement('a');
xx.appendChild(a);
Note: innerHTML creates multiple elements. It is more efficient to splice (push) in the form of an array, and the structure is slightly more complicated.
createElement() creates multiple elements, and the direct splicing efficiency is high, but it is less efficient than innerHTML splicing in array form, but the structure is clearer.
2. Operation examples
2.1 Click the button to change color
Five buttons, click on a button, its background color will change to pink, other button colors will be default
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-v8q0BogP-1650003500754) (C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\ image-20220408141239164.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
var btns = document.getElementsByTagName('button');
for(var i = 0;i < btns.length ; i++){
btns[i].onclick = function(){
for(var j = 0; j< btns.length;j++){
btns[j].style.backgroundColor = '';
}
this.style.backgroundColor = 'pink';
}
}
</script>
</body>
</html>
2.2 Skin changing effect
Click on the picture to change the page background to the current picture
[External link image transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the image and upload it directly (img-33Ds5dB7-1650003500757) (C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\ image-20220408110733486.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin:0;
padding: 0;
}
body{
background: url(D:/image/img1.jpg) no-repeat center top;
}
li{
list-style: none;
}
.backChange{
overflow: hidden;
margin:100px auto;
background-color: aquamarine;
width: 410px;
padding-top: 3px;
}
.backChange li{
float: left;
margin: 0 1 px;
cursor: pointer;
}
.backChange img{
/* display:block; */
width: 100px;
margin-left: 1px;
/* height: 56.25px; */
}
</style>
</head>
<body>
<ul class="backChange">
<li><img src="D:\image\img1.jpg" alt=""></li>
<li><img src="D:\image\img2.jpg" alt=""></li>
<li><img src="D:\image\img3.jpg" alt=""></li>
<li><img src="D:\image\img5.jpg" alt=""></li>
<!-- <li><img src="D:\image\img5.jpg" alt=""></li> -->
</ul>
<script>
var imgs = document.querySelector('.backChange').querySelectorAll('img');
for(i = 0;i < imgs.length ;i++){
imgs[i].onclick = function(){
console.log(this.src);
document.body.style.backgroundImage='url('+this.src+')';
}
}
</script>
</body>
</html>
2.3 Table placement color change effect
The mouse changes color when it passes a line, and changes back to its original color when it leaves
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-vfWK6Pgu-1650003500759) (C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\ image-20220408113727117.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
table{
width: 800px;
margin: 100px auto;
text-align: center;
border-collapse: collapse;
font-size: 14px;
}
thead tr{
height: 30px;
background-color: rgb(218, 114, 114);
}
tbody tr{
height: 30px;
}
tbody td{
border-bottom: 1px solid #999;
font-size: 12px;
color: rgb(255, 64, 0);
}
.bg{
background-color: rgb(241, 138, 101);
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>姓名</th>
<th>班级</th>
<th>年龄</th>
<th>成绩</th>
<th>排名</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
</tbody>
</table>
<script>
var trs = document.querySelector('tbody').querySelectorAll('tr');
for(var i = 0;i<trs.length;i++){
trs[i].onmouseover = function(){
this.className='bg';
}
trs[i].onmouseout = function(){
this.className='';
}
}
</script>
</body>
</html>
2.4 Form Select All and Unselect All
Requirement 1: Select all button - select all
Requirement 2: select all single buttons - select all selected; single button does not select all - select all not selected
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-yBItS0I3-1650003500760) (C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\ image-20220408144853661.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
table{
width: 800px;
margin: 100px auto;
text-align: center;
border-collapse: collapse;
font-size: 14px;
}
thead tr{
height: 30px;
color: crimson;
background-color: rgb(253, 209, 209);
}
tbody tr{
height: 30px;
}
tbody td{
border-bottom: 1px solid #999;
font-size: 12px;
color: rgb(255, 64, 0);
}
</style>
</head>
<body>
<div class="wrap">
<table>
<thead>
<tr>
<th>
<input type="checkbox" name="" id="cbAll">
</th>
<th>商品</th>
<th>价格</th>
</tr>
</thead>
<tbody id="cb">
<tr>
<td>
<input type="checkbox" name="" id="">
</td>
<td>iPhone</td>
<td>10000</td>
</tr>
<tr>
<td><input type="checkbox" name="" id=""></td>
<td>ipad</td>
<td>5000</td>
</tr>
<tr>
<td><input type="checkbox" name="" id=""></td>
<td>apple</td>
<td>10</td>
</tr>
</tbody>
</table>
</div>
<script>
var cbAll =document.getElementById('cbAll');
var cb=document.getElementById('cb').getElementsByTagName('input');
//要求一:全选-所有选
cbAll.onclick=function(){
console.log(this.checked);
for(var i = 0 ; i < cb.length ; i++){
cb[i].checked = this.checked;
}
}
// 要求二:每一个都选了-全选;有一个没选-全选不选
for(var i = 0 ; i < cb.length ; i++){
cb[i].onclick = function(){
var flag = true;
for(var j = 0 ; j < cb.length ; j++){
if(!cb[j].checked){
flag = false;
break;
}
}
cbAll.checked = flag;
}
}
</script>
</body>
</html>
2.5 tab bar switching
①Click the menu bar in the first row, click one to change its background color, and the other primary colors
② The content of the point displays the corresponding detailed information
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-wWe83Iss-1650003500760) (C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\ image-20220408163546207.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.tab_list li{
list-style: none;
float: left;
height: 39px;
line-height: 39px;
padding: 0 20px;
text-align: center;
cursor: pointer;
}
.tab_list .current{
background-color: rgb(224, 191, 191);
color: rgb(0, 0, 0);
}
/* .item_info{
padding: 20px 0 0 20px;
} */
.item{
display: none;
}
</style>
</head>
<body>
<div class="tab">
<div class="tab_list">
<ul>
<li class="current">商品介绍</li>
<li>规格包装</li>
<li>售后</li>
<li>商品评价</li>
<li>手机社区</li>
</ul>
</div>
<div class="tab_con">
<br><br>
<div class="item" style="display: block;">
商品模块介绍内容
</div>
<div class="item">
规格包装内容
</div>
<div class="item">
售后内容
</div>
<div class="item">
评价内容
</div>
<div class="item">
商品模块介绍内容
</div>
</div>
</div>
<script>
var tab_list = document.querySelector('.tab_list');
var lis = tab_list.querySelectorAll('li');
var items = document.querySelectorAll('.item');
for(var i=0 ; i<lis.length;i++){
lis[i].setAttribute('index',i);
lis[i].onclick = function(){
for(var j=0;j<lis.length;j++){
lis[j].className = '';
}
this.className = 'current';
var index = this.getAttribute('index');
console.log(index)
for(j = 0;j<items.length;j++){
items[j].style.display = 'none';
}
items[index].style.display = 'block';
}
}
</script>
</body>
</html>
2.6 Drop-down menu
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-IGWd0gJ2-1650003500762) (C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\ image-20220408200844472.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>下拉菜单</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
a {
text-decoration: none;
font-size: 14px;
}
.nav {
margin: 100px;
}
.nav>li {
position: relative;
float: left;
width: 80px;
height: 41px;
text-align: center;
}
.nav li a {
display: block;
width: 100%;
height: 100%;
line-height: 41px;
color: #333;
}
.nav>li>a:hover{
background-color: rgb(240, 193, 133);
}
.nav ul{
display: none;
position:absolute;
top: 41px;
left: 0;
width: 100%;
border-left: 1px solid #FECC5B;
border-right: 1px solid #FECC5B;
}
.nav ul li{
border-bottom:1px solid #FECC5B;
}
.nav ul li a:hover {
background-color: #FFF5DA;
}
</style>
</head>
<body>
<ul class="nav">
<li>
<a href="#">微博</a>
<ul>
<li><a href="#">私信</a></li>
<li><a href="#">评论</a></li>
<li><a href="#">@我</a></li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li><a href="#">私信</a></li>
<li><a href="#">评论</a></li>
<li><a href="#"> @我</a></li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li><a href="#">私信</a></li>
<li><a href="#">评论</a></li>
<li><a href="#">@我</a></li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li><a href="#">私信</a></li>
<li><a href="#">评论</a></li>
<li><a href="#">@我</a></li>
</ul>
</li>
</ul>
<script>
var nav = document.querySelector('.nav');
var lis = nav.children;
for(var i=0;i<lis.length;i++){
lis[i].onmouseover = function(){
this.children[1].style.display = 'block';
}
lis[i].onmouseout = function(){
this.children[1].style.display='none';
}
}
</script>
</body>
</html>
2.7 simple version release message
[External link image transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the image and upload it directly (img-lvE2QaPU-1650003500763) (C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\ image-20220409094424855.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
}
textarea {
width: 200px;
height: 100px;
border: 1px solid rgb(0, 73, 4);
outline: none;
resize: none;
}
ul {
margin-top: 50px;
}
li {
width: 300px;
padding: 5px;
background-color: rgb(248, 253, 179,0.5);
color: rgba(238, 144, 20, 0.76);
font-size: 14px;
margin: 15px 0;
}
</style>
</head>
<body>
<textarea name="" id=""></textarea>
<button>发布</button>
<ul>
<!-- <li>133</li> -->
</ul>
<script>
// 1. 获取元素
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
// 2. 注册事件
btn.onclick = function() {
if (text.value == '') {
alert('您没有输入内容');
return false;
} else {
// console.log(text.value);
// (1) 创建元素
var li = document.createElement('li');
// 先有li 才能赋值
li.innerHTML = text.value;
// (2) 添加元素
// ul.appendChild(li);
ul.insertBefore(li, ul.children[0]);
}
}
</script>
</body>
</html>
2.8 Followed by 2.7 to delete some messages
<script>
// 1. 获取元素
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
// 2. 注册事件
btn.onclick = function() {
if (text.value == '') {
alert('您没有输入内容');
return false;
} else {
// console.log(text.value);
// (1) 创建元素
var li = document.createElement('li');
// 先有li 才能赋值
li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
// (2) 添加元素
// ul.appendChild(li);
ul.insertBefore(li, ul.children[0]);
//删除元素
var as = document.querySelectorAll('a');
for(var i = 0 ; i<as.length ; i++){
as[i].onclick=function(){
ul.removeChild(this.parentNode);
console.log(this.parentNode);
}
}
}
}
</script>
3 DOM focus core
DOM (Document Object Model) is a standard programming interface recommended by the W3C organization for processing Extensible Markup Language (HTML or XML).
The DOm element we obtained is an object (Object), so it is called the document object model
dom operations: create, add, delete, modify, check, attributes, events
Create: document.write()
innerHTML
creatElement()
Increase: appendChild
insertBefore
Delete: removeChild()
Change: Modify dom element attributes, element content, form
Check: API methods provided by DOM: getElementById, getElementByTagName
New methods provided by H5: querySelector, querySelectorAll
Use nodes to get elements: parentNode, Children, previousElementSibling, nextElementSibling
Attribute: setAttribute: Set attribute value
getAttribute: get attribute value
removeAttribute: remove attribute
Events: Register events for elements: Event source. Event type = event handler
Each mouse event
4 Events Premium
4.1 Registration event (binding event)
Two ways: traditional way and method monitoring registration way
Traditional registration method: the uniqueness of the registration event, only one handler can be set for the same event on the same element, and the latter will overwrite the previous handler
btn.onclick = funtion()
Method monitoring registration method: addEventListener(); IE before IE9 does not support, you can use attachEvent() instead
4.1.1 addEventListener event monitoring method
Multiple listeners can be added to the same event
eventTarget.addEventListener(type, listener, useCapture)
btn.addEventListener('click', function(){
alert(22);})
btn.addEventListener('click', function(){
alert(33);})
type: event type, such as click, mouseover, pay attention without on, quotes
listener: event processing function, the listening function is called when the event occurs
useCapture: optional parameter, boolean value, default false
4.1.2 attachEvent event monitoring method
Only versions earlier than ie9 support
eventTarget.attachEvent(eventNameWithOn , callback)
Register the specified listener to the eventTarget (target object), and the callback function will be executed after the object triggers the specified event
eventNameWithOn:
callback:
btns[1].addEventListener('click', function() {
alert(33);})//attachEvent ie9以前的版本支持
4.2 Delete event (unbind event)
4.2.1 Traditional way
eventTarget.onclick = null;
divs[0].onclick = function() {
alert(11);
divs[0].onclick = null;
}
4.2.2 Method monitoring registration method
① eventTarget.removeEventListener(type, listener, useCapture)
divs[1].addEventListener('click', fn) // 里面的fn 不需要调用加小括号
function fn() {
alert(22);
divs[1].removeEventListener('click', fn);
}
② eventTarget.detachEvent(eventNameWithOn , callback)
divs[2].attachEvent('onclick', fn1);
function fn1() {
alert(33);
divs[2].detachEvent('onclick', fn1);
}
4.3 DOM event flow
The event flow describes the order in which events are received from the page. When an event occurs, it will propagate among element nodes in a specific order. This process is called DOM event flow.
document—html—body---------div--------body—html—document
DOM event flow has three phases:
- capture phase
- current target stage
- bubbling stage
①js code can only execute one of the stages of capturing or bubbling
②Onclick and attachEvent can only get the bubbling stage
③addEventListener(type, listener, useCapture), if the third parameter is true, it means that the event handler is called during the capture phase. If false the event handler is called during the bubbling phase.
④ actually pay more attention to bubbling
⑤ Some events do not bubble, such as onblur, onfocus, onmouseenrter, onmouseleave
⑥Event bubbling sometimes brings trouble, sometimes helps
4.4 Event object
4.4.1 Concept and use
var div = document.querySelector('div');
div.onclick = function(event){
}//event就是一个事件对象,当形参来看
The event object exists only when there is an event. It is automatically created by the system for us and does not require us to pass parameters.
The event object represents the state of the event, such as the state of the mouse button, the position of the mouse, and the state of the mouse button
We can name this event object by ourselves, such as event, evt, e
Event objects also have compatibility issues: ie678 uses window.event compatibility to write e = e || window.event;
4.4.2 Properties and methods of event objects:
e.target: returns the object (element) that triggered the event, this returns the object that binds the event
Difference: When e.target clicks on that element, it will return that element this, and that element is bound to this click event, then it will return who
this has a very similar attribute currentTarget ie6-8 does not know
The property method of the event object | illustrate |
---|---|
e.target | Returns the object criteria for the outgoing event |
e.srcElement | Returns the object that fired the event. Non-standard ie6-8 uses |
e.type | Return the type of event such as click, mouseover without on |
e.cancelBubble | This attribute prevents bubbling, non-standard ie6-8 use |
e.returnValue | This attribute prevents the default event (default behavior) non-standard ie6-8 use, such as not letting the link jump |
e.preventDefault() | This attribute prevents the default event (default behavior) standard, such as not letting the link jump |
e.stopPropagation() | prevent bubbling criteria |
4.5 Prevent event bubbling
e.stopPropagation(); // stop stops Propagation propagation
e.cancelBubble = true; // non-standard cancel to cancel the bubble bubble
var son = document.querySelector('.son');
son.addEventListener('click', function(e) {
alert('son');
e.stopPropagation(); // stop 停止 Propagation 传播
e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡
}, false);
4.6 Event delegation (proxy, delegation)
The bubbling feature brings benefits
The principle of event delegation: instead of setting an event listener for each child node separately, the event listener is set on its parent node, and then uses the bubbling principle to affect the setting of each child node.
For example, register an event for ul, use the target of the event object to find the currently clicked li, the event will bubble to ul, and if ul has a registered event, the event listener will be triggered.
<ul>
<li>冒泡</li>
<li>冒泡</li>
<li>冒泡</li>
<li>冒泡</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e){
alert('冒泡泡');
e.target.style.backgroundColor = 'pink';
})
</script>
4.7 Mouse Events (Others)
[The first part of the mouse event]:
4.7.1 Prohibit the contextmenu of the right mouse button menu
contextmenu mainly controls when the context menu should be displayed, and is mainly used for programmers to cancel the default context menu
document.addEventListener('contextmenu', function(e){
e.preventDefault();
})
4.7.2 Disable mouse selection (selectstart starts selection)
document.addEventListener('selectstart',function(e){
e.preventDefault();
})
4.7.3 Mouse event object
Mouse event object MouseEvent, keyboard event object KeyboardEvent
mouse event object | illustrate |
---|---|
e.clientX | Returns the X coordinate of the mouse relative to the visible area of the browser window (sliding the page does not affect) |
e.clientY | Returns the Y coordinate of the mouse relative to the visible area of the browser window |
e.pageX | Returns the X coordinate of the mouse relative to the document page, supported by IE9+ (sliding page change) |
e.pageY | Returns the Y coordinate of the mouse relative to the document page, supported by IE9+ |
e.screenX | Returns the X coordinate of the mouse relative to the computer screen |
e.screenY | Returns the Y coordinate of the mouse relative to the computer screen |
4.7.4 Case - picture following the mouse movement
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
img{
position:absolute;
height: 15px;
}
</style>
</head>
<body>
<img src="D:\image\img4.jpg" alt="">
<script>
var pic = document.querySelector('img');
document.addEventListener('mousemove', function(e){
console.log(1);
var x = e.pageX + 10;
var y = e.pageY + 10;
pic.style.left = x + 'px';
pic.style.top = y + 'px';
})
</script>
</body>
</html>
4.8 Keyboard Events
4.8.1 Basic Events
keyboard events | Triggering conditions |
---|---|
onkeyup | Triggered when a keyboard key is released |
onkeydown | Fired when a keyboard key is pressed |
onkeypress | Triggered when a keyboard key is pressed, but does not recognize function keys such as ctrl, shift, arrow, etc. |
<script>
// document.onkeyup = function(){
// console.log('弹起');
// }
document.addEventListener('keyup',function(){
console.log('keyup弹起');
})
document.addEventListener('keydown',function(){
console.log('keydown按下');
})
document.addEventListener('keypress',function(){
console.log('keypress按下');
})
</script>
Pay attention to the order of keydown and keypress
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-Tj93dUrf-1650003500764) (C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\ image-20220411155733001.png)]
4.8.2 keyCode attribute
keyCode returns the ASCII code value of the key to determine which key the user pressed
The keyup and keydown events are not case-sensitive, a and A are both 65
keypress case sensitive, a97, a65
4.8.3 Case - key input content
Press the keyboard "s", the input box is selected (focus)
<body>
<input type="text" name="" id="">
<script>
var search = document.querySelector('input');
document.addEventListener('keyup',function(e){
if(e.keyCode===83){
search.focus();
}
})
</script>
</body>
4.8.4 Case - the input content automatically displays the content in large font size
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-IbjGX1Wh-1650003500765)(C:\Users\Administrator\Pictures\image-20220411172915857.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.search {
position: relative;
width: 100px;
margin: 50px;
}
.con {
display: none;
position: absolute;
top: -40px;
width: 171px;
border: 1px solid rgba(0, 0, 0, .2);
box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
padding: 5px 0;
font-size: 20px;
line-height: 20px;
color: #333;
}
.con::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 28px;
left: 18px;
border: 8px solid #000;
border-style: solid dashed dashed;
border-color: #fff transparent transparent;
}
</style>
</head>
<body>
<div class="search">
<div class="con">空</div>
<input type="text" placeholder="请输入您的快递单号" class="input">
</div>
<script>
var con = document.querySelector('.con');
var input = document.querySelector('.input');
input.addEventListener('keyup',function(){
if(input.value == ''){
con.style.display = 'none';
}
else{
con.style.display = 'block';
con.innerHTML = this.value;
}
})
//失去焦点盒子隐藏
input.addEventListener('blur',function(){
con.style.display = 'none';
})
input.addEventListener('focus',function(){
if(this.value == ''){
con.style.display = 'none';
}
else{
con.style.display = 'block';
}
})
</script>
</body>
</html>
BOM
1 BOM overview
BOM Browser Object Model (Browser Object Model), which provides objects that interact with the browser window independently of the content, and its core object is window.
BOM lacks a standard and was originally part of the Netscape browser standard. The JavaScript syntax standardization organization is ECMA, and the DOM standardization organization is W3C.
DOM | BOM |
---|---|
Document Object Model | Browser Object Model |
DOM is to treat the document as an object | BOM is to treat the browser as an object |
The DOM top-level object is document | The BOM top-level object is window |
DOM is a W3C standard specification | BOM is defined by browser manufacturers on their respective browsers, and the compatibility is poor |
DOM mainly learns to manipulate page elements | The BOM learns some objects that the browser window interacts with |
The window object is the top-level object of the browser, and it has a dual role
1. It is an interface for JS to access the browser window
2、它是一个全局对象。定义在全局作用域中的变量、函数都会变成window对象的属性和方法
在调用的时候可以省略window
window下的一个特殊属性window.name,所以声明变量时不用name
2 window对象的常见事件
2.1窗口加载事件window.onload
window.onload = function(){
}
或者
window.addEventListener("load",function(){
});
当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等)
注:有了window.onload就可以把JS代码写到页面元素的上方,因为onload是等页面全部加载完毕再去执行处理函数
window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onoad为准
如果使用addEventListener则没有限制
DOMContentLoaded事件:
DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等等
document.addEventListener('DOMContentLoaded',function(){
});
2.2 调整窗口大小事件window.onresize
window.onresize = function(){
}
window.addEventListener("resize",function(){
})
只要窗口大小发生像素变化,就会触发这个事件
常利用这个事件完成响应式布局。window.innerWidth当前屏幕的宽度
<body>
<script>
window.addEventListener('load',function(){
var div = document.querySelector('div');
window.addEventListener('resize',function(){
console.log(window.innerWidth);
console.log('窗口变化');
if(window.innerWidth <= 800){
div.style.display = 'none';
}else{
div.style.display = 'block';
}
})
})
</script>
<div></div>
</body>
3 定时器setTimeout()、setInterval()
3.1 setTimeout()
3.1.1使用
window.setTimeout(调用函数,[延迟的毫秒数]);//当设置的毫秒数到期后执行调用函数,这个window在调用时可省略
<script>
function callback(){
console.log('到时间了')
}
setTimeout(callback, 3000);
setTimeout('callback()', 3000);//不提倡这样的写法
</script>
页面中可能有很多定时器,我们经常给定时器加标识符
var timer1 = setTimeout(callback, 3000);
var timer1 = setTimeout(callback, 5000);
*回调函数:需要等待时间,时间到了才去调用这个函数,因此称回调函数
3.1.2 案例-五秒关闭广告
<body>
<img src="D:/image/img4.jpg" alt="" class="ad">
<script>
var ad = document.querySelector('.ad');
setTimeout(function(){
ad.style.display = 'none'
},5000)
</script>
</body>
3.1.3 clearTimeout()
clearTimeout()停止setTimeout()定时器
window.clearTimeout(timeoutID)
btn.addEventListener('click',function(){//给按钮添加结束定时器事件
clearTimeout(timer);
})
①window可以省略
②参数里的定时器标识符不需要引号
3.3setInterval()
3.3.1使用
window.setInterval(回调函数,[间隔的毫秒数])//重复调用一个函数(每隔xx秒调用这个回调函数)
setInterval(function(){
console.log('setInterval定时器');
},1000);
3.3.2 案例-倒计时
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sGBPcpIG-1650003500766)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220413111636203.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>倒计时</title>
<style>
.countDown{
margin: 200px;
height: 50px;
width: 200px;
background-color: rgb(240, 176, 176);
}
span{
display: inline-block;
width: 50px;
height: 40px;
background-color: rgb(230, 241, 132);
text-align: center;
line-height: 40px;
margin: 5px;
}
.title{
background-color: rgba(144, 229, 255, 0.973);
position:absolute;
margin: -25px 200px;
color: burlywood;
}
</style>
</head>
<body>
<div class="title">倒计时:距离2022-4-15 10:00:00还有</div>
<div class="countDown">
<span class="hour">1</span>
<span class="minute">2</span>
<span class="second">3</span>
</div>
<script>
var hour = document.querySelector('.hour');
var minute = document.querySelector('.minute');
var second = document.querySelector('.second');
var inputTime = +new Date('2022-4-15 10:00:00');
countDown()//先调用一次这个函数,防止第一次刷新页面有空白
setInterval(countDown,1000);
function countDown(){
var nowTime = +new Date();//+new Date返回的是毫秒数,new Date返回标准时间
var times = (inputTime - nowTime) / 1000;
var h = parseInt(times / 60 / 60 % 24)
h = h < 10 ? '0' + h + '时' : h +'时';
hour.innerHTML = h ;
var m = parseInt(times / 60 % 60);
m = m < 10 ? '0' + m + '分' : m +'分';
minute.innerHTML = m ;
var s = parseInt(times % 60);
s = s < 10 ? '0' + s + ' 秒': s + '秒';
second.innerHTML = s ;
}
</script>
</body>
</html>
3.3.1 clearInterval()
使用:
var stop = document.querySelector('.stop');
stop.addEventListener('click',function(){
clearInterval(timer);
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PTzzCJy7-1650003500766)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220413112258013.png)]
3.3.4 案例-发送短信案例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hHD8jfNz-1650003500767)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220413114316557.png)]
<body>
手机号码:<input type="number"><button>发送短信</button>
<script>
var btn = document.querySelector('button');
var time = 10 ;
btn.addEventListener('click',function(){
btn.disabled = true;
var timer = setInterval(function(){
if(time == 0){
clearInterval(timer);
btn.disabled = false;
btn.innerHTML = '发送短信';
time = 10;
}
else{
btn.innerHTML = '还剩下'+ time +'秒';
time--;
}
},1000)
});
</script>
</body>
4 JS执行机制
4.1 JS是单线程
JavaScript的一大特点就是单线程,即一个时间只能做一件事
4.2 同步和异步
为解决单线程一些问题,利用多核CPU的计算能力,HTML5提出了Web Worker标准,允许JavaScript脚本创建多个线程。于是有了同步和异步。本质区别是这条流水线上的各个流程执行顺序不同。
异步即等待时间内可以做其他任务
如下:执行输出为:1 2 3
console.log(1);
setTimeout(function() {
console.log(3);
}, 1000);
console.log(2);
定时器定时等待0秒也输出1 2 3
console.log(1);
setTimeout(function() {
console.log(3);
}, 0);//等待0s,但是依旧后运行
console.log(2);
4.3执行过程
同步任务:都在主线程上执行,形成一个执行栈
异步任务:JS异步是通过回调函数实现
- 普通事件:如click、resize等
- 资源加载:如load、errord等
- 定时器:包括setInterval、setTimeout等
执行过程:
- 先执行执行栈中的同步任务
- 异步任务(回调函数)放入任务队列中
- 执行栈中的同步任务执行完毕后,系统会一次读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈开始执行
事件循环:主线程不断重复获得任务、执行任务、再获取任务、再执行,这种机制被称作事件循环。
5 location对象
5.1 什么是location对象
window对象给我们提供了一个location属性用于获取或设置窗体的URL,并且可以用于解析URL。因为属性返回的是一个对象,所以称为location对象。
5.2 URL
统一资源定位符(Uniform Resource Locator),是互联网上标准资源的地址。互联网上每个文件都有唯一一个URL,它包含的信息指出文件位置以及浏览器应该怎么处理它。
语法格式:
protocol://host[:post]/path/[?query]#fragment
https://www.......
组成 | 说明 |
---|---|
protocol | 通信协议,常用的http,ftp,maito等 |
host | 主机(域名) |
port | 端口号,可选,省略时使用方案的默认端口,如http默认端口是80 |
path | 路径 由零或多个’/'符号隔开的字符串,一般用来表示主机上的一个目录或文件地址 |
query | 参数 以键值对的形式,通过&符号分隔开来 |
fragment | 片段 #后面内容 常见于链接 锚点 |
5.3 location对象的属性
location对象属性 | 返回值 |
---|---|
location.href | 获取或设置整个URL |
location.host | 返回主机(域名) |
location.port | 返回端口号 如果未写返回空字符串 |
location.pathname | 返回路径 |
location.search | 返回参数 |
location.hash | 返回片段 #后面内容 常见于链接 锚点 |
5.4 相关案例
5.4.1 5秒后跳转页面
<body>
<button>点击立即跳转</button>
<div></div>
<script>
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.addEventListener('click',function(){
location.href = 'http://www.baidu.com';
})
var timer = 5 ;
setInterval(function(){
if(timer == 0){
location.href = 'http://www.baidu.com'
}else{
div.innerHTML = '您将在'+timer+'秒后跳转页面'
timer--;
}
},1000);
</script>
</body>
5.4.2 获取URL参数数据
<body>
<form action="041304案例-index.html">
用户名:<input type="text" name="uname">
<input type="submit" value="登陆" name="" id="">
</form>
</body>
<body>
<div></div>
<script>
console.log(location.search);
var params = location.search.substr(1);//去掉?uname=ss里面的?
console.log(params);
var arr = params.split('=');//利用等号把字符串分割成数组
console.log(arr);
//把数据写入div中
var div = document.querySelector('div');
div.innerHTML = arr[1]+'欢迎';
</script>
</body>
5.5 location对象的方法
location对象的方法 | 返回值 |
---|---|
location.assign() | 与href一样,可以跳转页面(也称为重定向页面) |
location.replace() | 替换当前页面,因不记录历史,所以不能后退页面 |
location.reload() | 重新加载页面,相当于刷新按钮或者f5,如果参数为true强制刷新ctrl+5 |
6 navigator对象
navigator对象包含有关浏览器的信息,属性如userAgent可以返回由客户机发送服务器的user-agent头部的值。
//判断用户用哪个终端打开页面
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 = "";//手机
}
else{
window.location.href = "";//电脑
}
7 history对象
window对象提供了一个history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL。
history对象方法 | 作用 |
---|---|
back() | 可以后退功能 |
forward() | 前进功能 |
go(参数) | 前进后退功能,参数如果是1前进一个页面,如果是-1后退一个页面 |
<script>
var btn = document.querySelector('button');
btn.addEventListener('click',function(){
history.forward();
})
</script>
PC端网页特效
- offset
- client
- scroll
- 封装简单动画
- 网页轮播图
1 offset元素偏移量
1.1概述
使用offset系列相关属性可以动态得到该元素的位置(偏移)、大小等。
- 获得元素距离带有定位父元素的位置
- 获得元素自身的大小(宽度高度)
- 注意:返回的数值都不带单位
offset系列属性 | 作用 |
---|---|
element.offsetParent | 返回作为该元素带有定位的父级元素,如果父级都没有定位则返回body |
element.offsetTop | 返回元素相对带有定位父元素上方的偏移 |
element.offsetLeft | 返回元素相对带有定位父元素左边框的偏移 |
element.offsetWidth | 返回自身包括padding、边框、内容区的宽度,返回数值不带单位 |
element.offsetHeight | 返回自身包括padding、边框、内容区的高度,返回数值不带单位 |
1.2 offset与style的区别
offset | style |
---|---|
offset可以得到任意样式表中的样式值 | style只能得到行内样式表中的样式值 |
offset系列获得的数值是没有单位的 | style.width获得的是带单位的字符串 |
offsetWidth包含padding+border+width | style.width获得不包括padding和border的值 |
offsetWidth等属性是只读属性,只能获取不能赋值 | style.width是可读写属性,可以获取也可以赋值 |
结论:想要获取元素大小位置,用offset更合适 | 结论:想要给元素更改值,需要style改变 |
1.3 案例-获取鼠标在盒子内的坐标
利用鼠标在页面内的坐标pageX、pageY,盒子距离左和上的距离offsetLeft、offsetTop,求出鼠标在盒子里面的坐标
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
height: 300px;
width: 300px;
background-color: rgb(233, 201, 201,0.5);
margin: 30px;
text-align: center;
line-height: 200px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
var box = document.querySelector('.box');
box.addEventListener('click',function(e){
console.log(e.pageX);
console.log(e.pageY);
console.log(box.offsetLeft);
console.log(box.offsetTop);
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
this.innerHTML = 'x坐标是'+x+'y坐标是'+y;
})
</script>
</body>
</html>
1.4 拖动模态框
点击链接,弹出登陆框,点关闭关闭登陆框,同时可以鼠标按下登陆会员位置,移动鼠标可以拖动登陆框。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.login-header{
width: 100%;
height: 30px;
text-align: center;
font-size: 30px;
}
a {
text-decoration: none;
color: #000000;
}
.login{
display: none;
width: 512px;
height: 250px;
position: fixed;
border: rgb(32, 237, 252) solid 2px;
left: 50%;
top: 40%;
background: #d4a9a9;
z-index: 9999;
transform: translate(-50%, -50%);
box-shadow: 0px 0px 20px #ddd;
}
.login-title{
width: 100%;
height: 40px;
margin: 10px 0 0 0;
text-align: center;
cursor: move;
font-size: 20px;
}
.close-login{
position: absolute;
border-radius: 50%;
text-align: center;
line-height: 40px;
right: -30px;
top: -30px;
background: rgba(0, 225, 255,0.3);
font-size: 14px;
width: 40px;
height: 40px;
border: rgba(122, 220, 250, 0.3) solid 1px;
}
.login-input-content {
margin-top: 20px;
}
.login-input {
overflow: hidden;
/* margin: 0px 0px 20px 0px; */
}
.login-input label {
margin: 0 0 0 15px;
float: left;
width: 90px;
padding-right: 10px;
text-align: right;
line-height: 35px;
height: 35px;
font-size: 18px;
}
.login-input .list-input {
float: left;
line-height: 35px;
height: 35px;
width: 350px;
border: #ffd903 1px solid;
text-indent: 5px;
}
.login-button {
width: 50%;
margin: 30px auto 0px auto;
line-height: 40px;
font-size: 14px;
border: #fa6c6c 1px solid;
text-align: center;
}
/* .login-button a {
display: block;
} */
.login-bg {
display: none;
width: 100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background: rgba(0, 0, 0, .3);
}
</style>
</head>
<body>
<div class="login-header"><a href="javascript:;" id="link">点击弹出登录框</a></div>
<div class="login" id="login">
<div class="login-title" id="title">登陆会员
<span><a class="close-login" id="closeBtn" href="Javacript:void(0);">关闭</a></span>
</div>
<div class="login-input-content">
<div class="login-input">
<label>用户名:</label>
<input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
</div>
<br>
<div class="login-input">
<label>登陆密码:</label>
<input type="password" placeholder="请输入登陆密码" name="info[password]" id="password" class="list-input">
</div>
</div>
<div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登陆会员</a></div>
</div>
<!-- 遮盖层 -->
<div id="bg" class="login-bg"></div>
<script>
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');
link.addEventListener('click',function(){
mask.style.display = 'block';
login.style.display = 'block';
});
closeBtn.addEventListener('click',function(){
mask.style.display = 'none';
login.style.display = 'none';
})
title.addEventListener('mousedown',function(e){
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
document.addEventListener('mousemove',move);
function move(e){
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
}
document.addEventListener('mouseup',function(){
document.removeEventListener('mousemove',move);
})
})
</script>
</body>
</html>
2 client元素可视区
使用client系列相关属性来获取元素可视区的相关信息。动态得到元素边框大小、元素大小
client 宽度 和我们offsetWidth 最大的区别就是 不包含边框
client系列属性 | 作用 |
---|---|
element.clientTop | 返回元素上边框大小 |
element.clientLeft | 返回元素左边框大小 |
element.clientWidth | 返回自身包括padding、内容区宽度,不含边框,返回数值不带单位 |
element.clientHeight | 返回自身包括padding、内容区高度,不含边框,返回数值不带单位 |
2.1 立即执行函数
立即执行函数,不需要调用,立马能够自己执行的函数。
立即执行函数最大的作用就是 独立创建了一个作用域, 里面所有的变量都是局部变量 不会有命名冲突的情况。
(function(){})()
//或者
(function(){}());
(function(a,b){
console.log(a + b);
})(1,2);//两个立即执行函数前一个最后一定要有分号
(function(a,b){
console.log(a+b);
}(2,3));
2.2 物理像素比dpr
pc端物理像素比为1,一些移动端如iphone678,dpr为2
var dpr = window.devicePixelRatio || 1
2.3 pageshow
页面发生变化时,重新设置。
load事件触发:a标签超链接、F5或刷新按钮(强制刷新)、前进后退按钮
一些浏览器如火狐,特点往返缓存,村村中保存着页面数据、DOM和JavaScript状态,实际上是整个页面都保存在内存里。所以,此时后退按钮不会刷新页面。
pageshow事件在页面显示时触发,无论页面是否来自缓存。在重新加载页面中,pageshow会在load事件触发后触发;根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件。
注意:这个事件给window添加。
window.addEventListener('pageshow',function(e){
//e.persisted返回的true就是从缓存取出来的页面
alert('11');
})
window.addEventListener('load',function(){
alert('11');
})
3 元素滚动scroll
动态得到元素大小、滚动距离等。(内容大小,如盒子内文字超出盒子范围,返回内容的实际属性)
scroll系列属性 | 作用 |
---|---|
element.scrollTop | 返回被卷上去的上侧距离,返回数值不带单位 |
element.scrollLeft | 返回被卷上去的左侧距离,返回数值不带单位 |
element.scrollWidth | 返回自身的实际宽度,不含边框,返回数值不带单位 |
element.scrollHeight | 返回自身的实际高度,不含边框,返回数值不带单位 |
3.1 onscroll事件
页面被卷去的头部,滚动条向下滚动,页面上被隐藏的高度,称页面被卷去的头部。滚动条在滚动时会触发onscroll事件。
div.addEventListener('scroll',function(){
console.log(div.scrollTop)
})
3.2 案例-侧边栏定位
页面滚动到一定位置,出现返回顶部操作
*页面被卷去的头部:可以通过window.pageYOffset获得,被卷去的左侧window.pageXOffset
*元素被卷去的头部element.scrollTop
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.slider-bar {
position: absolute;
left: 50%;
top: 300px;
margin-left: 600px;
width: 45px;
height: 130px;
background-color: pink;
}
.w {
width: 1200px;
margin: 10px auto;
}
.header {
height: 150px;
background-color: rgb(231, 203, 231);
}
.banner {
height: 250px;
background-color: rgb(198, 236, 252);
}
.main {
height: 1000px;
background-color: rgb(211, 223, 188);
}
span {
display: none;
position: absolute;
bottom: 0;
}
</style>
</head>
<body>
<div class="slider-bar">
<span class="goBack">返回顶部</span>
</div>
<div class="header w">头部区域</div>
<div class="banner w">banner区域</div>
<div class="main w">主体部分</div>
<script>
var sliderbar = document.querySelector('.slider-bar');
var banner = document.querySelector('.banner');
var main = document.querySelector('.main');
var goBack = document.querySelector('.goBack');
var sliderbarTop = sliderbar.offsetTop - banner.offsetTop;
document.addEventListener('scroll',function(){
if(window.pageYOffset > banner.offsetTop){
sliderbar.style.position = 'fixed';
sliderbar.style.top = sliderbarTop + 'px';
}
else{
sliderbar.style.position = 'absolute';
sliderbar.style.top = '300px';
}
if(window.pageYOffset > main.offsetTop){
goBack.style.display = 'block';
}
else{
goBack.style.display = 'none';
}
})
</script>
</body>
</html>
3.3 页面被卷去的头部兼容性解决方法
因为兼容性问题,所以被卷去的头部通常有如下几种写法:
- 声明了DTD,使用document.documentElement.scrollTop
- 未声明DTD,使用document.body.scrollTop
- 新方法window.pageYOffset和window.pageXOffset,ie9开始支持
function getScroll(){
return{
left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0 ,
top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
};
}
//使用
getScroll().left
3.4 三大系列总结
- offset系列用于获得元素位置 offsetLeft、offsetTop
- client常用于获取元素大小clientWidth、clientHeight
- scroll常用于获得滚动距离scrollTop、scrollLeft
- 注意页面滚动的距离通过window.pageXOffset获得
4 动画函数封装
4.1动画实现原理
核心原理:定时器setInterval()不断移动盒子位置。
- 获得盒子当前位置
- 让盒子在当前位置加上1个移动距离
- 利用定时器不断重复这个操作
- 加一个结束定时器的条件
- 注意此元素需要添加定位, 才能使用element.style.left
<script>
//动画元素需要添加定位position
var div = document.querySelector('div');
var timer = setInterval(function(){
if(div.offsetLeft > 400){
clearInterval(timer)
}
div.style.left = div.offsetLeft + 5 +'px';
},30);
</script>
4.2 动画函数封装
需要传递两个参数:动画对象和移动的距离
<button>点击开始小方块</button>
<div></div>
<span></span>
<script>
//动画元素需要添加定位position
var div = document.querySelector('div');
var span = document.querySelector('span');
var btn = document.querySelector('button');
animate(div,300);
btn.addEventListener('click',function(){
animate(span,200);
})
function animate(obj, target){
// 当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
// 解决方案就是 让我们元素只有一个定时器执行
// 先清除以前的定时器,只保留当前的一个定时器执行
clearInterval(obj.timer);
obj.timer = setInterval(function(){
if(obj.offsetLeft > target){
clearInterval(obj.timer)
}
obj.style.left = obj.offsetLeft + 5 +'px';
},30);
}
</script>
4.3 缓动动画
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
- 让盒子每次移动的距离慢慢变小,速度慢慢落下来
- 核心算法:(目标值-现在位置)/10 作为每次移动的步长
function animate(obj, target){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
//步长
var step = Math.ceil((target - obj.offsetLeft) / 10)
if(obj.offsetLeft > target){
clearInterval(obj.timer)
}
obj.style.left = obj.offsetLeft + step +'px';
},15);
}
若添加回掉函数,回调函数写在定时器结束里面
4.4 实例-缓动动画
鼠标移动到箭头位置,展开问题反馈盒子
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RP3qkNDB-1650003500769)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220415103855591.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AZjfIYfG-1650003500769)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220415103810021.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.sliderbar {
position: fixed;
right: 0;
bottom: 100px;
width: 40px;
height: 40px;
text-align: center;
line-height: 40px;
cursor: pointer;
color: rgb(248, 116, 116);
}
.con {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 40px;
background-color: rgb(240, 193, 240);
z-index: -1;
}
</style>
<script src="animate.js"></script>
</head>
<body>
<div class="sliderbar">
<span>←</span>
<div class="con">问题反馈</div>
</div>
<script>
var sliderbar = document.querySelector('.sliderbar');
var con = document.querySelector('.con');
sliderbar.addEventListener('mouseenter',function(){
animate(con,-160,function(){
sliderbar.children[0].innerHTML = '→';
});
})
sliderbar.addEventListener('mouseleave',function(){
animate(con,0,function(){
sliderbar.children[0].innerHTML = '←';
});
})
</script>
</body>
</html>
5 常见网页特效案例
j.timer)
}
obj.style.left = obj.offsetLeft + 5 +‘px’;
},30);
}
#### 4.3 缓动动画
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
1. 让盒子每次移动的距离慢慢变小,速度慢慢落下来
2. 核心算法:(目标值-现在位置)/10 作为每次移动的步长
```javascript
function animate(obj, target){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
//步长
var step = Math.ceil((target - obj.offsetLeft) / 10)
if(obj.offsetLeft > target){
clearInterval(obj.timer)
}
obj.style.left = obj.offsetLeft + step +'px';
},15);
}
若添加回掉函数,回调函数写在定时器结束里面
4.4 实例-缓动动画
鼠标移动到箭头位置,展开问题反馈盒子
[外链图片转存中…(img-RP3qkNDB-1650003500769)]
[外链图片转存中…(img-AZjfIYfG-1650003500769)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.sliderbar {
position: fixed;
right: 0;
bottom: 100px;
width: 40px;
height: 40px;
text-align: center;
line-height: 40px;
cursor: pointer;
color: rgb(248, 116, 116);
}
.con {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 40px;
background-color: rgb(240, 193, 240);
z-index: -1;
}
</style>
<script src="animate.js"></script>
</head>
<body>
<div class="sliderbar">
<span>←</span>
<div class="con">问题反馈</div>
</div>
<script>
var sliderbar = document.querySelector('.sliderbar');
var con = document.querySelector('.con');
sliderbar.addEventListener('mouseenter',function(){
animate(con,-160,function(){
sliderbar.children[0].innerHTML = '→';
});
})
sliderbar.addEventListener('mouseleave',function(){
animate(con,0,function(){
sliderbar.children[0].innerHTML = '←';
});
})
</script>
</body>
</html>