黑马javascript笔记
JAVASCRIPT基礎
一、javascript導讀
1.1 歷史
發明人:布蘭登.艾奇
1.2 javascript是什么
運行在客戶端的腳本語言
腳本語言:不需要編譯,由js解釋器逐行進行解釋并執行
1.3作用
- 表單驗證
- 網頁特效
- 服務端開發
- 桌面程序
- app
- 控制硬件
- 游戲開發
1.4 html/css/js關系
HTML/css為標記語言-描述類語言
js為腳本語言-編程類語言
1.5瀏覽器執行js
瀏覽器由渲染引擎和js引擎組成
- 渲染引擎:解析HTML和CSS也就是內核
- js引擎:用于讀取網頁中的js代碼,比如chrome的v8
二、js三種書寫位置
與css類似
1、行內式
- 可以將單行或少量js代碼寫在HTML標簽屬性中(以on開頭的屬性),如:onclick
- 特殊情況下使用
2、內嵌式
<head><script>里面為js代碼</script> </head>3、外鏈式
以.js為后綴的文件
<script src="my.js"></script>三、注釋
1、單行注釋
//
ctrl+/
2、多行注釋
/**/
shift+alt+a
四、js輸入輸出語句
| alert(msg) | 瀏覽器彈出警示框 | 瀏覽器 |
| console.log(msg) | 瀏覽器控制臺打印輸出信息 | 瀏覽器 |
| prompt(info) | 瀏覽器彈出輸出框,用戶可以輸入 | 瀏覽器 |
五、變量
1、聲明變量
var 變量名;
js中var用來聲明變量
可以同時聲明多個變量
var age=18,name=“stive”,gz=2000;
允許不聲明直接賦值,但是不提倡(會變成全局變量)
2、賦值
var age;
age=18;
3、初始化
var age=18;
4、獲取輸入值
var myname=prompt(“輸入名字:”);
5、命名規范
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DJ1IhXte-1673928790986)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221203203039745.png)]
六、數據類型
js是一種弱類型或者說動態語言,這意味著不用提前聲明變量的類型,在程序運行過程中,類型會被自動確定
根據=右側的值來判斷數據類型
1、分類
簡單數據類型
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YOD7qH2B-1673928790987)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221203203534510.png)]
①Number數字型
數字型最大值和最小值(了解)
Number.Max_VALUE 數字型最大值
Number.Min_VALUE 數字型最小值
Number.Max_VALUE*2 無窮大(Infinity)
-Number.Max_VALUE*2 無窮小(-Inifinity)
isNaN()用于判斷非數字,是數字則返回false
②String字符串型
’ ‘或者“ ”都可
推薦單引號(因為html推薦是雙引號)
轉義字符
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-mvFppx1j-1673928790988)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221203204539212.png)]
字符串長度獲取
str.length
字符串拼接
str1+str2
注意:字符串+數字/boolean 輸出的是字符串,也可以用
字符串+變量
③Boolean布爾型
true和false
參與運算時true當1,false當0
④Undefined和Null
typeof 變量 顯示變量類型
數字類型轉換
| toString() | 轉成字符串 | |
| String() | 強制轉成字符串 | |
| 加號拼接字符串 | 和字符串拼接的結果是字符串 |
| parseInt(string) | string轉整數值 | |
| parseFloat(string) | string轉浮點值 | |
| Number() | 強制轉數值型 | |
| js隱式轉換(- * /) | 利用運算轉數值型 | ‘a’-0 |
| Boolean() | 其它類型轉成布爾值 |
復雜數據類型
七、運算符
| + | 加 | |
| - | 減 | |
| * | 乘 | |
| / | 除 | |
| % | 取余 |
| ++ | 遞增 | |
| – | 遞減 |
| < | ||
| > | ||
| >= | ||
| <= | ||
| == | 判斷兩邊值是否相等,有隱式轉換 | |
| != | ||
| === !== | 全等 要求值和數據類型都一致 | 37===‘37’ false |
| && | 與 | |
| || | 或 | |
| ! | 非 |
邏輯運算中有邏輯中斷特性
| = | ||
| +=、-= | ||
| *=、/=、%= |
八、流程控制(與c一樣)
1、分支結構
if語句
if(){} else if(){} else{}三元表達式
條件表達式? 表達式1:表達式2
真則返回1的值,假則返回2的值
switch語句
switch(n){case 值1:...break;case 值2:...break;defualt:case值不匹配時執行的代碼}2、循環
1、for循環
2、while循環
3、do/while循環
以上循環基本和c一致
九、數組
1、數組創建
①var a=new Array();
a[0]=1;
a[1]=2;
②var a=new Array(1,2);
③var a=[1,‘a’,3];
數組的下標是基于0的
數組里的數據類型可以為任意,類似python的列表
2、訪問數組元素
數組名[索引號]
索引 從0開始
3、遍歷數組
for(var i=0;i<a.length;i++){console.log(a[i]) }4、數組新增元素
1、修改length長度(擴容)
? 例如本來為3長度的數組
a.length=5則改為長度為5的數組,后兩個元素默認為undifined
2、通過下一位索引號(追加元素)
arr=[1,2,3,4];
arr[4]=‘pink’;追加元素
十、函數
1、語法
聲明函數
①命名函數方式聲明
function funcname(參數1,參數2) {//執行代碼 }調用函數
fucname(參數1,參數2)②函數表達式
var 變量名=function(){}; //調用 變量名();2、return
函數沒有return就會返回undefined
3、arguments
當形參個數不確定時可以用arguments來獲取。
arguments存儲了所有傳遞過來的實參
function fn() {console.log(arguments); } fn(1,2,3)偽數組并不是正真意義上的數組
1、具有數組的length屬性
2、按照索引方式進行存儲
3、沒有真正數組的一些方法如pop() push()等
4、可以按照數組的遍歷方式遍歷
十一、作用域
js作用域分為全局和局部
1、全局作用域:整個script標簽,或者單獨的js文件
2、局部作用域:函數作用域
變量分為全局變量和局部變量
1、全局變量
①函數外聲明的變量
②函數內沒有聲明的變量(沒有用var聲明)
2、局部變量
①函數內聲明的變量(要用var聲明)
全局變量只有瀏覽器關閉才會銷毀,占用內存資源。局部變量當程序執行完畢就會直接銷毀,節約內存資源。
js沒有塊級作用域,es6新增了塊級作用域
塊級作用域,即{}中的作用域
十二、js預解析
js引擎運行js分為兩步:預解析 代碼執行
js預解析:會把js里所有var還有function提升到當前作用域最前面
代碼執行:按照代碼書寫順序從上往下執行
預解析分為變量預解析和函數預解析
變量預解析:所有變量聲明提升到當前作用域最前面,不提升賦值
函數預解析:就是把所有函數聲明提升到當前作用域最前面,不調用函數。
其實可以不用管這個前提是有良好的代碼習慣
十三、對象(類似python的字典,就是多了方法)
對象:具體的事物,在編程中,對象由屬性和方法組成
1、創建對象
1】字面量創建對象
var obj={};創建空對象
var obj={
? name=“小明”,
? age=‘18’,
? gender=‘男’,
? sayHi:function(){//定義方法
? console.log(‘hello’);
? }
}
類似python的字典采用鍵值對的形式
2】new Object創建對象(個人不推薦)
var obj=new Object();//創建空對象 obj.name="張三豐"; obj.age=18; obj.sayHi=function(){console.log("hai"); }我個人是不推薦這種寫法的,因為c和python等語言并沒有類似的這種對象的寫法,而且結構不清晰
3】利用構造函數創建對象(個人推薦)
構造函數:一種特殊的函數,主要用于初始化對象,即為對象成員變量賦初始值,它總與new運算符一起使用,我們可以把對象中一些公共屬性和方法抽取出來,然后封裝到這個函數里面
語法
function 構造函數名(參數1,參數2,...){//定義構造函數this.屬性=參數或值;this.方法=function(){} } var 變量名=new 構造函數名();//調用構造函數創建對象構造函數首字母大寫
例:
2、使用對象
1】調用對象屬性
①對象名.屬性名
②對象名[‘屬性名’]
2】調用對象方法
對象名.方法名()
3、遍歷對象
for in語句
for(變量 in 對象){} for(var k in obj){console.log(k);//輸出屬性名console.log(obj[k]);//輸出屬性名 }十四、內置對象
js對象分為自定義對象、內置對象、瀏覽器對象
前兩者對象是js基礎內容屬于ECMAScript;最后一個是js獨有的,js API中會講解
1】查文檔MDN
官網http://developer.mozilla.org/zh-CN/
1、查閱方法的功能
2、查看參數意義和類型
3、查看返回值意義和類型
4、測試
2】Math對象
- Math.PI圓周率
- Math.max(value1,value2,…)最大值
- Math.abs()絕對值
- Math.floor()向下取整,往最小取值
- Math.ceil()向上取整
- Math.round()四舍五入
- Math.random()隨機數
Math.random()
? 返回隨機小數[0,1)
? 構造返回整數的方法:
function getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min}//包含了最大值和最小值3】封裝自己的數學對象
var myMath={PI:3.141592653,max:function(){var max=arguments[0];for(var i=1;i<arguments.length;i++){if(arguments[i]>max){max=arguments[i];}}return max;} }4】日期對象Date
Date()是一個構造函數必須用new調用來創建一個對象
1、使用Date
var date=new Date();
console.log(date);
如果無參數則返回系統當前時間
2、參數常用寫法
①數字型 2019,10,01
②字符串型‘ 2019-10-1 8:8:8’
var date1=new Date(2019,10,1);
返回11月不是10月
var date2=new Date(‘2019-10-1 8:8:8’)
返回10月
3、日期格式化
var date=new Date();
date.getFullYear() ;//獲取當前日期年
date.getMonth();//獲取月份(0-11)小一個月
date.getDate();//返回幾號
date.getDay();//返回周幾(0-6)周日返回0
date.getHours();
date.getMinutes();
date.getSeconds();
4、時間戳(總毫秒數)
距離1970年1月1號過了多少毫秒數
1、通過valueOf() 或getTime()
var date=new Date();2、簡單寫法
var date= +new Date();
返回的date就是毫秒數
3、H5新增寫法
console.log(Date.now());
5、倒計時
核心算法:規定時間減去剩余時間即倒計時,但是不能拿時分秒相減
可以用時間戳來做,用戶輸入時間總的毫秒數減去現在時間的總的毫秒數得到的就是剩余時間的毫秒數。再把總的毫秒數轉換為天、時、分、秒
轉換公式如下:
- d=parseInt(總秒數/60/60/24);計算天數
- h=parseInt(總秒數/60/60%24);計算小時
- m=parsent(總秒數/60%60);計算分
- s=parsentInt(總秒數%60);計算秒
5】數組內置對象Array
1、字面量創建數組
var arr=[1,2,3]; console.log(arr[0]);2、利用new Array()
var arr1=new Array();//創建空數組 var arr2=new Array(2);//創建長度為2的數組,有兩個空元素 var arr3=new Array(2,3);//創建[2,3]數組3、添加數組元素
| push() | 給原數組末尾添加一個或多個元素,返回新數組長度 | arr.push(4,5,6); |
| unshift() | 再數組開頭添加一個或多個元素,返回新數組長度 | arr.unshift(4,5,6) |
4、刪除數組元素
| pop() | 刪除最后一個元素,返回刪除的元素 | a.pop() |
| shift() | 刪除第一個元素,返回刪除的元素 | a.shift() |
5、數組排序
| reverse() | 數組倒序 | arr.reverse() |
| sort() | 冒泡排序 | arr.sort() |
降序
arr1.sort(function(a,b){return b-a;})升序
arr1.sot(function(a,b){return a-b;})6、獲取數組索引
| indexOf(元素) | 返回對應元素值的第一個滿足的索引,若找不到則返回-1 | arr.index(‘blue’) |
| lastIndexOf() | 與indexOf類似,只是從后往前找 |
7、數組轉字符串
| toString() | 把數組轉換成字符串,逗號分隔每一項 | arr.toString() |
| join(‘分隔符’) | 把數組中的元素轉換成一個字符串 | arr.join(‘-’) |
6】字符串對象string
基本包裝類型:就是把簡單數據類型包裝成為了復雜數據類型,這樣一個簡單數據類型就有了屬性和方法
str.length()獲取字符串長度
字符串不可變
根據字符返回位置
str.indexOf(‘查找字符’[,查找起始位置])
| concat(str1,str2,…) | 用于連接兩個或者多個字符串相當于+,+更常用 |
| substr(start,length) | 從start位置開始,取length個數 |
| slice(start,end) | 從start位置開始,截取到end位置,不包括end |
| substring(start,end) | 從start位置開始截取到end位置,不包括end,但是不接受負值 |
| replace(‘被替換字符’,‘替換字符’) | 只會替換第一個字符 | |
| split(‘分隔符’) | 分隔字符串 |
WEB APIs
webapis簡介
1、js組成
只有js基礎是做不了網頁交互效果的
2、web APIS
- 是w3c組織的標準
- 主要學習DOM和BOM
- 是js獨有的部分
- 我們主要學習頁面交互功能
- 需要js基礎
3、API
應用程序編程接口,是給程序員提供的一種工具以便更輕松實現想要完成的功能
4、web API
是瀏覽器提供的一類API,用于操作瀏覽器功能和頁面元素
(1)DOM
一、簡介
1、什么是dom
文檔對象模型,是w3c推薦的處理html的標準編程接口
可以改變網頁內容、結構和樣式
2、DOM樹
- 文檔:一個頁面就是一個文檔,dom中用document表示
- 元素:頁面中所有標簽都是元素,dom中使用element表示
- 節點:網頁中所有內容都是節點(標簽屬性文本注釋等),dom中用node表示
二、獲取元素
| document.getElementById(‘id’) | 獲取對應唯一ID的元素對象,返回一個獲取的元素對象 | ID | var element = document.getElementById(id); |
| document.getElementsByTagName() | 更讓據標簽名返回元素對象,返回的是存放所有標簽的一個偽數組 | 標簽名 | var element = document.getElementsByTagName(‘標簽名’); |
| document.getElementsByClassName() | 更具類名返回存放所有標簽的偽數組 | 類名,H5新增 | var element=document.getElementsByClassName(類名) |
| document.querySelector(選擇器名) | 通過選擇器,返回指定選擇器的第一個元素對象 | 選擇器名第一個,H5新增 | var firstBox=document.querySelector(選擇器名)//類選擇器名前要加. ID選擇器前要加# |
| document.querySelectorAll(選擇器名) | 根據指定選擇器返回所有集合 | 選擇器名所有,H5新增 | var boxs=document.querySelectorAll(選擇器名) |
- 獲取的元素對象可以用.符號嵌套使用例如
- 可以用console.dir打印我們的元素對象,更好的查看里面的屬性和方法
三、獲取特殊元素
1、獲取body元素
var bodyEle=document.body;2、獲取html元素
var htmlEle=document.documentElement;四、事件三要素
事件的組成:事件源、事件類型、事件處理程序
- 事件源:事件被觸發的對象(誰)
- 事件類型:如何觸發 什么事件 比如鼠標點擊(干了什么)
- 事件處理程序:通過函數 (怎么辦)
五、執行事件的過程
1、獲取事件源
例如:
var div=document.querySelector('div');2、綁定事件
div.onclick=3、添加事件處理程序
div.onclick=function(){ }| onclick | 鼠標點擊左鍵觸發 |
| onmouseover | 鼠標經過觸發 |
| onmouseout | 鼠標離開觸發 |
| onfocus | 獲得鼠標焦點觸發 |
| onblur | 失去鼠標焦點觸發 |
| onmousemove | 鼠標移動觸發 |
| onmouseup | 鼠標彈起觸發 |
| onmousedown | 鼠標按下觸發 |
六、操作元素
6.1改變元素內容
element.innerText從起始位置到終止位置的內容,但它不識別html標簽,同時空格和換行也會去掉(不常用)
element.innerHTML起始位置到終止位置的全部內容,識別html標簽,同時保留空格和換行 (W3C推薦)
innerText例子:
//點擊按鈕改變文字 1、獲取元素 var btn=document.querySelector('btn'); var div=document.querySelector('div'); 2、注冊事件 btn.onclick=function(){div.innerText='2019-6-6'; }innerHTML例子:
1、獲取元素 var btn=document.querySelector('btn'); var div=document.querySelector('div'); 2、注冊事件 btn.onclick=function(){div.innerText='<strong>2019-6-6</strong>'; }6.2改變元素屬性
常用屬性:src/title/href/id/alt等
var ldh=document.getElementById('ldh'); var zxy=document.getElementById('zxy'); var img=document.getElementById('img'); zxy.onclick=function(){img.src='images/zxy.jpg'; }總結:元素對象.屬性=值
6.3修改css樣式屬性
1、獲取元素
2、注冊元素 處理程序
1】element.style.樣式名 行內樣式操作 樣式少時使用
2】element.className 類名樣式操作 樣式復雜時使用
var div=document.querySelector('div'); div.onclick=function(){this.style.backgroundColor='purple';this.style.width='200px'; } var div=document.querySelector('div'); div.onclick=function(){this.className='change';//把類名改成change,之后只要在css里添加change類名對應的樣式即可 }注意:
-
JS里的樣式采取駝峰命名方法,比如fontSize,backgroundColor
-
修改style樣式的操作產生的是行內樣式,css權重高
-
修改樣式多時可以用修改類名的方式來更改元素樣式
-
className會直接更改元素的類名,會覆蓋原先的類名
循環精靈圖(案例)
1、首先精靈圖排列得有規律
2、利用for循環修改精靈圖背景位置
3、剩下的就是數學問題了
顯示隱藏文本框內容(案例)
1、首先需要兩個事件:失去焦點和獲取焦點
var text=document.querySelector('input'); text.onfoncus=function(){if(text.value==='手機'){text.value='';this.style.color='gray';} } text.onblur=function(){if(text.value===''){text.value='手機'this.style.color='#fff';} }七、排他思想
<body><botton>按鈕1</botton><botton>按鈕1</botton><botton>按鈕1</botton><botton>按鈕1</botton><botton>按鈕1</botton><script>var btns=document.getElementsByTagName('button');for(var i=0;i<btns.length;i++){//通過for循環給所有button元素注冊事件btns[i].onclick=function(){//1、把所有按鈕背景色還原for(var i=0;i<btns.length;i++){btns[i].style.backgroundColor='';}//2、把當前按鈕變成背景色this.style.backgroundColor="pink";}}</script></body>通過上面案例可知,排他思想就是
1、所有元素設置原先樣式
2、設置當前元素樣式
表格隔行換色(案例)
<!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></style> </head><body><table><thead><tr><td>姓名</td><td>性別</td><td>年齡</td></tr></thead><tbody><tr><td>小明</td><td>男</td><td>18</td></tr><tr><td>小芳</td><td>女</td><td>17</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.style.backgroundColor = 'pink';}trs[i].onmouseout = function() {this.style.backgroundColor = '#fff';}}</script> </body></html>表單全選/取消全選(案例)
<!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>thead tr {background-color: skyblue;}</style> </head><body><table cellspacing="0px"><thead><tr><td><input type="checkbox" id="All_c"></td><td>姓名</td><td>性別</td><td>年齡</td></tr></thead><tbody><tr><td><input type="checkbox" id="c"></td><td>小明</td><td>男</td><td>18</td></tr><tr><td><input type="checkbox" id="c"></td><td>小芳</td><td>女</td><td>17</td></tr></tbody></table><script>//全選或者取消全選的方法var a_cbox = document.getElementById('All_c');var cbox = document.querySelector('tbody').querySelectorAll('input');a_cbox.onclick = function() {for (var i = 0; i < cbox.length; i++) {cbox[i].checked = this.checked;}}//子按鈕狀態影響全選框狀態for (var i = 0; i < cbox.length; i++) {cbox[i].onclick = function() {if (!this.checked) {a_cbox.checked = false;} else {var flag = 1;for (var i = 0; i < cbox.length; i++) {if (cbox[i].checked == false) {flag = 0;break;}}if (flag) {a_cbox.checked = true;}}}}</script></body></html>八、自定義屬性
8.1獲取元素自定義屬性值
1、獲取元素的屬性值
- element.getAttribute(‘屬性’) ;用于獲得自定義屬性
- element.屬性值 ;獲取元素本身自帶屬性
自定義屬性:程序員自己添加的屬性
2、設置屬性值
- element.setAtrribute(‘屬性’,‘值’);設置自定義屬性
- element.屬性值=‘值’;設置內置屬性
3、移除屬性
element.removeAtrribute(‘屬性’)
tab欄切換案例-重要
<!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>.clearfix:before,.clearfix:after {content: "";display: table;}.clearfix:after {clear: both;}.clearfix {*zoom: 1;}.tab_list li {float: left;list-style: none;margin-left: 10px;}.current {float: left;list-style: none;margin-left: 10px;background-color: pink;}.item {display: none;}</style> </head><body><div class="tab"><div class="tab_list clearfix"><ul><li class="current">商品介紹</li><li>規格包裝</li><li>售后保障</li><li>商品評價</li><li>手機社區</li></ul></div><div class="tab_con"><div class="item">商品介紹模塊</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.querySelector('.tab_con').querySelectorAll('.item');items[0].style.display = 'block';for (var i = 0; i < lis.length; i++) {//設置索引號(自定義屬性index)lis[i].setAttribute('index', i);}for (var i = 0; i < lis.length; i++) {lis[i].onclick = function() {//改變底色for (var i = 0; i < lis.length; i++) {lis[i].className = '';}this.className = 'current';//改變內容var index = this.getAttribute('index');for (var i = 0; i < items.length; i++) {items[i].style.display = 'none';}items[index].style.display = 'block';}}</script> </body></html>8.2H5自定義屬性
1、H5自定義屬性概念
為了防止歧義自定義屬性必須是data-開頭的
比如data-index
2、設置H5自定義屬性
必須以data-屬性名的形式創建自定義屬性
3、獲取H5自定義屬性
-
兼容性獲取:element.getAttribute(‘data-屬性名’)
-
H5新增:element.dataset.屬性名
? element.dataset[‘屬性名’]
? 這兩個屬性名不需要帶data-且只有IE11才開始支持這兩個方法
PS: 對于這樣命名的自定義屬性data-list-name
必須采用駝峰命名法獲取,也就是element.dataset.listName
十一、節點操作
11.1節點概述
獲取元素通常有兩種方式:
1、利用DOM提供的方法獲取,邏輯不強且繁瑣
2、利用節點層級關系獲取元素,邏輯性強但是兼容性差
這兩種方式都可以獲取元素節點,后面都會使用,但是節點操作更加簡單
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-oKTW1EC7-1673928790989)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221205171441111.png)]
網頁中的所有內容都是節點(標簽、屬性、文本、注釋等),在DOM 中,節點使用 node 來表示。
HTML DOM 樹中的所有節點均可通過 JavaScript 進行訪問,所有 HTML 元素(節點)均可被修改,也可以創建或刪除。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Wcq61A0T-1673928790990)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221215142925754.png)]
實際操作中主要的是元素節點
11.2節點層級
常見的為父子兄節點關系
1、父節點node.parentNode
返回某節點的最近父節點,若找不到則返回null
var a=document.querySelector('.son');//獲取節點 console.log(a.parentNode);//獲取并打印最近父節點2、子節點
- node.childNodes
返回指定節點的所有子節點(不僅僅是元素節點)
var a=document.querySelector('.father'); console.log(a.childNodes);//獲取并打印所有子節點 for(var i=0;i<ul.childNodes.length;i++){//通過for循環通過nodeType來過濾出子節點中的元素節點if(ul.childNodes[i].nodeType==1){console.log(ul.childNodes[i]);} }由于想要獲取里面的元素節點,則需要專門處理,所以我們一般不提倡使用childNodes
- node.children 重點
返回所有子元素節點,雖然他是非標準的獲取方式,但是瀏覽器都支持,所以可以大量使用這種方式,也是實際開發常用的
- node.firstChild/node.lastChild
獲取第一個子節點/最后一個子節點(不管是文本還是元素節點等)
- node.firstElementChild/lastElementChild
獲取第一個/最后子元素節點,
注意這兩種方法有兼容性問題ie9以上才支持
【解決方案】
實際開發里一般通過node.children[0]獲取第一個子元素節點
node.children[node.children.length-1]獲取最后一個元素節點
3、兄弟節點
- node.nextSibling
獲取下一個兄弟節點(包括文本節點,元素節點等)
可以用這個自己封裝一個函數來找到兄弟節點避免兼容性
- node.previousSibling
獲取上一個兄弟節點(包括文本節點,元素節點等)
- node.nextElementSibling
獲取下一個元素節點,ie9以上才支持
- node.previousElementSibling
獲取上一個元素節點,ie9以上才支持
11.3節點的創建和添加
1.創建節點
document.createElement(‘tagName’);
var li=document.createElement('li');2、追加節點
node.appendChild(child)
添加到節點的最后子節點末尾
var ul.document.querySelector('ul'); ul.appendChild(li);3、插入節點
node.insertBefore(child,指定元素);
ul.insertBefore(li,ul.children[0])11.4節點的刪除
- node.removeChild(child) 刪除子節點
例:ul.removeChild(ul.children[0]);刪除ul中第一個子元素節點
11.5節點的復制
- node.cloneNode() 返回調用該方法的節點的一個副本
- 若括號里為空或者false則為淺拷貝,即只復制標簽不復制內容
- 若為true則為深拷貝,復制標簽和內容
十二、DOM總結重點核心
對于DOM操作,我們主要針對子元素的操作,主要有
創建,增,刪,改,查,屬性操作,時間操作
1.創建
document.write,innerHTML,createElement
2.增
appendChild,insertBefore
3.刪
removeChild
4.改
主要修改dom的元素屬性,dom元素的內容、屬性、表單的值等
修改元素屬性:src、href、title 等
修改普通元素內容:innerHTML、innerText
修改表單元素:value、type、disabled
修改元素樣式:style、className
5.查
主要獲取查詢dom的元素
DOM提供的API方法:getElementById、getElementsByTagName (古老用法,不推薦)
H5提供的新方法:querySelector、querySelectorAll (提倡)
利用節點操作獲取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling) 提倡
6.屬性操作
主要針對于自定義屬性
setAttribute:設置dom的屬性值
getAttribute:得到dom的屬性值
removeAttribute:移除屬性
十三、事件高級
13.1注冊事件
注冊事件有兩種方式:傳統方式和方法監聽注冊方式
| 利用on開頭的事件 onclick | w3c標準推薦方式 |
| <button οnclick=“alert(hi)”></button> | addEventListener()是一個方法 |
| btn.οnclick=function(){} | IE9及之后支持,可使用attachEvent()代替 |
| 特點:注冊事件唯一性,同一個元素同一個事件只能當設置一個處理函數 | 特點:同一個元素同一個事件可以注冊多個監聽器 |
| 最后注冊的處理函數將會覆蓋前面注冊的處理函數 | 按注冊順序依次執行 |
13.2addEventListener事件監聽方式
eventTarget.addEventListener(type,listener[,userCapture]);-
該方法將指定的監聽器注冊到目標對象eventTarget上,
-
當該對象觸發指定的事件時,就會執行事件處理函數。
該方法接受三個參數:
type:事件類型字符串,比如click,mouseover這里不用帶on
listener:事件處理函數,事件發生時,會調用該監聽函數
useCapture:可選參數,是一個布爾值,默認時false
例:
<body><button>傳統注冊事件</button><button>方法監聽注冊事件</button><button>ie9 attachEvent</button><script>var btns = document.querySelectorAll('button');// 1. 傳統方式注冊事件btns[0].onclick = function() {alert('hi');}btns[0].onclick = function() {alert('hao a u');}// 2. 事件監聽注冊事件 addEventListener // (1) 里面的事件類型是字符串 所以加引號 而且不帶on// (2) 同一個元素 同一個事件可以添加多個偵聽器(事件處理程序)btns[1].addEventListener('click', function() {alert(22);})btns[1].addEventListener('click', function() {alert(33);})// 3. attachEvent ie9以前的版本支持btns[2].attachEvent('onclick', function() {alert(11);})</script> </body>13.3attachEvent注冊方式-了解
ie9以前版本,該特性是非標準不提倡使用
eventTarget.attacjEvent(eventNameWithOn,callback)指定監聽器注冊到eventTarget上,當該對象觸發指定的事件時,指定的回調函數就會被執行
參數
- eventNameWithOn:事件類型字符串,比如onclick、onmouseover
- callback:事件處理函數,當目標觸發事件時回調函數被調用
注冊事件兼容性解決方案
function addEventListener(element, eventName, fn) {// 判斷當前瀏覽器是否支持 addEventListener 方法if (element.addEventListener) {element.addEventListener(eventName, fn); // 第三個參數 默認是false} else if (element.attachEvent) {element.attachEvent('on' + eventName, fn);} else {// 相當于 element.onclick = fn;element['on' + eventName] = fn;}13.3刪除事件
1】removeEventListener方法監聽注冊方式
eventTarget.removeEventListener(type,listener[,useCapture]);參數
-
type:事件類型字符串,比如click,mouseover,注意這里不要帶on
-
listener:事件處理函數,事件發生時,會調用該監聽函數
-
useCapture:可選參數,是一個布爾值,默認是 false。學完 DOM 事件流后,我們再進一步學習
- div[1].addEventListener('click',fn)//注冊事件函數
function fn(){//事件函數alter(22)//輸出22divs[1].removeEventListener('click',fn)//移除fn事件函數
}
該移除函數,在綁定函數時綁定的函數需要先分離寫法。
2】detachEvent刪除事件方式
eventTarget.detachEvent(eventNameWithOn,callback);參數:
- eventNameWithOn:事件類型字符串,比如 onclick 、onmouseover ,這里要帶 on
- callback: 事件處理函數,當目標觸發事件時回調函數被調用
- ie9以前的版本支持
3】傳統事件刪除方式
eventTarget.onclick = null;十四、DOM事件流
事件流描述的是頁面中接收事件的順序
事件發生時會在元素節點之間按照特定的順序傳播,這個傳播過程即DOM事件流
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-51NpLW5O-1673928790990)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221215200959839.png)]
- 事件冒泡: IE 最早提出,事件開始時由最具體的元素接收,然后逐級向上傳播到到 DOM 最頂層節點的過程。
- 事件捕獲: 網景最早提出,由 DOM 最頂層節點開始,然后逐級向下傳播到到最具體的元素接收的過程。
1、js代碼只能執行捕獲或者冒泡中的一個階段
2、onclick和attachEvent只能執行冒泡階段
3、addEventLisenner(type,listener[,useCapture])第三個參數如果是true,表示再事件捕獲階段調用事件處理程序;如果是false,默認是false,表示再事件冒泡階段調用事件處理程序
十五、事件對象
div.onclick=function(event){}1、event就是一個事件對象,寫在偵聽函數的小括號中,當作形參來看
2、事件對象只有有了事件才會存在它是系統自動創建的不需要傳遞參數
3、事件對象是我們事件的一系列相關數據的集合與事件相關的,比如鼠標點擊里面就包含了鼠標的相關信息。
4、事件對象可以自己命名。比如event,evt,e
5、事件對象也有兼容性問題ie678通過window.event兼容性的寫法
十六、事件對象的常見屬性和方法
| e.target | 返回觸發事件的對象 標準 |
| e.srcElement | 返回觸發事件的對象 非標準ie6-8使用 |
| e.type | 返回事件的類型 |
| e.cancelBubble | 該屬性阻止冒泡 ie678使用 |
| e.returnValue | 該屬性阻止默認事件 ie678使用 |
| e.preventDefault() | 該方法阻止默認事件 標準 |
| e.stopPropagation() | 阻止冒泡 標準 |
注:e.target返回的是觸發事件的對象,this返回的是綁定事件的對象
阻止默認事件
<body><div>123</div><a href="http://www.baidu.com">百度</a><form action="http://www.baidu.com"><input type="submit" value="提交" name="sub"></form><script>// 常見事件對象的屬性和方法// 1. 返回事件類型var div = document.querySelector('div');div.addEventListener('click', fn);div.addEventListener('mouseover', fn);div.addEventListener('mouseout', fn);function fn(e) {console.log(e.type);}// 2. 阻止默認行為(事件) 讓鏈接不跳轉 或者讓提交按鈕不提交var a = document.querySelector('a');a.addEventListener('click', function(e) {e.preventDefault(); // dom 標準寫法})// 3. 傳統的注冊方式a.onclick = function(e) {// 普通瀏覽器 e.preventDefault(); 方法// e.preventDefault();// 低版本瀏覽器 ie678 returnValue 屬性// e.returnValue;// 我們可以利用return false 也能阻止默認行為 沒有兼容性問題 特點: return 后面的代碼不執行了, 而且只限于傳統的注冊方式return false;alert(11);}</script> </body>阻止冒泡的兩種方式
1】標準寫法:利用事件對象里的e.stopPropagation();
2】非標準:window.event.cancelBubble=true;
阻止冒泡的兼容性寫法
if(e && e.stopPropagation){e.stopPropagation();}else{window.event.cancelBubble = true;}十七、事件委托(代理、委派)
事件委托原理
給父節點添加偵聽器,利用事件冒泡影響每個子節點
作用:只操作一次DOM提高程序性能
<body><ul><li>知否知否,點我應有彈框在手!</li><li>知否知否,點我應有彈框在手!</li><li>知否知否,點我應有彈框在手!</li><li>知否知否,點我應有彈框在手!</li><li>知否知否,點我應有彈框在手!</li></ul><script>// 事件委托的核心原理:給父節點添加偵聽器, 利用事件冒泡影響每一個子節點var ul = document.querySelector('ul');ul.addEventListener('click', function(e) {// alert('知否知否,點我應有彈框在手!');// e.target 這個可以得到我們點擊的對象e.target.style.backgroundColor = 'pink';// 點了誰,就讓誰的style里面的backgroundColor顏色變為pink})</script> </body>以上案例:給 ul 注冊點擊事件,然后利用事件對象的 target 來找到當前點擊的 li,因為點擊 li,事件會冒泡到 ul 上, ul 有注冊事件,就會觸發事件監聽器。那么每個li都會觸發ul的事件
十八、禁止選中文字和禁止右鍵菜單
1、禁止鼠標右鍵菜單
contextmenu主要控制應該何時顯示上想問菜單,主要用于程序員取消默認的上下文菜單
document.addEventListener('contextmenu',function(e){ e.preventDefault(); })2、禁止鼠標選中
selectstart
<body><h1>我是一段不愿意分享的文字</h1><script>// 1. contextmenu 我們可以禁用右鍵菜單document.addEventListener('contextmenu', function(e) {e.preventDefault(); // 阻止默認行為})// 2. 禁止選中文字 selectstartdocument.addEventListener('selectstart', function(e) {e.preventDefault();})</script> </body>十九、獲得鼠標在頁面坐標
鼠標事件對象MouseEvent
| e.clientX | 返回鼠標相對于瀏覽器窗口可視區的X坐標 |
| e.clientY | 返回鼠標相對于瀏覽器窗口可視區的Y坐標 |
| e.pageX(重點) | 返回鼠標相對于文檔頁面的X坐標 IE9+ 支持 |
| e.pageY(重點) | 返回鼠標相對于文檔頁面的Y坐標 IE9+ 支持 |
| e.screenX | 返回鼠標相對于電腦屏幕的X坐標 |
| e.screenY | 返回鼠標相對于電腦屏幕的Y坐標 |
二十、常用鍵盤對象
| onkeyup | 某個鍵盤按鍵被松開時觸發 |
| onkeydown | 某個鍵盤按鍵被按下時觸發 |
| onkeypress | 某個鍵盤按鍵被按下時觸發,但是它不識別功能鍵,比如 ctrl shift 箭頭等 |
- 如果使用addEventListener 不需要加 on
- onkeypress 和前面2個的區別是,它不識別功能鍵,比如左右箭頭,shift 等
- 三個事件的執行順序是: keydown – keypress — keyup
鍵盤對象屬性
| keyCode | 返回該鍵值的ASCII值 |
- onkeydown和 onkeyup 不區分字母大小寫,onkeypress 區分字母大小寫。
- 在我們實際開發中,我們更多的使用keydown和keyup, 它能識別所有的鍵(包括功能鍵)
- Keypress 不識別功能鍵,但是keyCode屬性能區分大小寫,返回不同的ASCII值
(2)BOM
一、概述
BOM即瀏覽器對象模型,提供了獨立于內容而與瀏覽器窗口進行交互的對象,其核心對象是window。
BOM由一系列相關的對象構成,并且每個對象都提供了很多方法與屬性
BOM缺乏標準,最初是Netscape瀏覽器標準的一部分
DOM針對的是文檔,而BOM是把瀏覽器當作一個對象shi瀏覽器廠商在各自瀏覽器上定義的,兼容性差
BOM包含DOM
- BOM的構成
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-beBvaOTK-1673928790991)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221216132347517.png)]
window對象是瀏覽器的頂級對象,具有雙重角色
1、是js訪問瀏覽器窗口的一個接口
2、是一個全局對象,定義在全局作用域中的變量、函數都會變成window對象的屬性和方法。在調用時可以省略window,前面學習的對話框屬于window對象方法,如alert(),prompt()等其完整寫法是window.alert()。
注意:window下有個特殊屬性window.name,所以不要聲明name變量
二、window對象常見事件
2.1窗口加載事件
window.onload=function(){} 或者window.addEventListener("load",function(){})window.onload是窗口加載事件,當文檔內容完全加載完成會觸發該事件(包括圖像、腳本文件、css文件等),就調用的處理函數
一般需要標簽在js段之上才能觸發事件,因為html是從上往下執行,而加上window.οnlοad=function(){}將js代碼寫入{}內就可以將js放置在任何地方,應為他會等待頁面全部加載完畢才會執行該js
- 有了window.onload就可以把js代碼寫到頁面元素的上方,因為onload是等頁面內容全部加載完畢再去執行處理函數
- window.onload傳統注冊事件方式只能寫一次,如果有多個,會以最后一個window.onload為準
- window.addEventListener(‘load’,function(){})可以寫任意次推薦用這種方法。
DOMContentLoaded事件觸發時,僅當DOM加載完成,不包括樣式表、圖片、flash等等ie9以上才支持
如果頁面圖片很多的話,從用戶訪問到onload觸發可能需要較長的事件教書效果就會延遲實現,必然影響用戶的體驗,此時用DOMContentLoaded事件比較合適
2.2窗口調整大小事件
window.onresize=function(){}; 或者window.addEventListener('resize',function(){});window.onresize是窗口調整大小事件。
- 只要窗口尺寸變化就會觸發這個事件
- window.innerWidth可以獲取當前屏幕的寬度
2.3定時器
window對象提供兩種定時器
- setTimeout()
- setInterval()
setTimeout
window.setTimeout(調用函數,[延遲的毫秒數])setTimeout()方法用于設置一個定時器,該定時器在定時器到期后執行調用函數。
- window可以省略
- 調用函數可以直接寫函數,或者寫函數名
- 延遲的毫秒數省略默認是0
- 定時器有很多可給經常使用的定時器賦值一個標識符(timeoutID)
這個調用函數也稱為**回調函數callback,**意思就是回頭調用函數,下一件事情干完(時間或者條件到了)再回頭調用這個函數
清除定時器
window.clearTimeout(timeoutID)- window可省略
- 里面的參數就是定時器的標識符(變量)
開啟定時器setInterval
window.setInterval(調用函數,[間隔時間ms])- window可以省略
- 每隔間隔時間就會調用一次函數,可以一直調用
停止定時器clearInterval
window.clearInterval(timeoutID)- window可以省略
2.4this
this的指向在函數定義的時候是確定不了的,只有函數執行的時候才能確定this到底指的是誰,一般情況下this的最終指向是調用它的對象
- 全局作用域或者普通函數中this指向的是window
- 定時器里的this指向window
- 方法調用中誰調用this就指向誰
- 構造函數中this指向構造函數的實例
三、js同步和異步
js一大特點就是單線程,即同一時間只能做一件事。
單線程意味著所有任務都需要排隊
同步
程序執行結果和排列順序一致
異步
同一時間宏觀上做多個任務
js執行機制
- 同步任務:在主線程上執行,形成一個執行棧
- 異步任務:js的異步通過回調函數實現,
? 一般而言異步任務有一下三種類型
? 1、普通事件:click、resize等
? 2、資源加載,如load、error等
? 3、定時器
? 異步任務相關回調函數會放入任務隊列(消息隊列)中
機制:
- 先執行同步任務
- 遇到回調函數,放入任務(消息)隊列中
- 再執行下一個同步任務
- 一旦執行棧中所有同步任務完成,系統就會依次執行任務隊列中的任務
四、location對象
1、location屬性用于獲取或設置窗體的URL,并且可以用于解析URL。因為這個屬性返回的是一個對象,所以我們將這個屬性稱為location對象。
URL:統一資源定位符
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-7BeKBMmF-1673928790992)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221216145136595.png)]
2、location對象屬性
| location.href | 獲取或者設置(跳轉)整個URL |
| location.host | 返回主機(域名)www.baidu.com |
| location.port | 返回端口號,如果未寫返回空字符串 |
| location.pathname | 返回路徑 |
| location.search | 返回參數 |
| location.hash | 返回片段 #后面內容常見于鏈接 錨點 |
重點記住: href和search
3、獲取URL參數
-
location.search返回參數
-
去除? 利用substr(‘起始位置’,截取字符數) 省略字符數則截取到最后
-
split(‘=’)利用=分隔字符串為數組
- <body><form action='index.html'>用戶名:<input type='text' name='uname'><input type='submit' value='登錄'></form>
</body>
index.html:
4、location常見方法
location.assign(‘URL’)跳轉網頁到指定URL,可以瀏覽器后退頁面
location.repleace(‘URL’)跳轉網頁,但不記錄歷史無法后退
location.reload()刷新頁面 參數為true則強制刷新
五、navigator對象-了解
包含瀏覽器的相關信息,有很多屬性,常用userAgent可以返回由客戶機發送服務器的user-agent頭部的值
下面前端代碼可以判斷用戶那個終端打開頁面,如果是用 PC 打開的,我們就跳轉到 PC 端的頁面,如果是用手機打開的,就跳轉到手機端頁面
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 = ""; //電腦}不用背
六、History對象
與瀏覽器歷史記錄進行交互
包含用戶訪問過的URL
| back() | 可以后退功能 |
| forward() | 前進功能 |
| go(參數) | 前進后退功能,參數如果是 1 前進1個頁面 如果是 -1 后退1個頁面 |
七、PC端網頁特效
7.1offset
offset翻譯就是偏移量,使用offset相關屬性可以動態的得到元素的位置、大小等
- 獲得元素距離帶有定位父元素的位置(父級必須帶定位,否則以body為準)
- 獲得元素自身的大小
- 返回的數值都不帶單位
offest常用屬性
| element.offsetParent | 返回作為該元素帶有定位的父級元素,如果父級都沒用定位則返回body |
| element.offsetTop | 返回元素相對帶有定位父元素上方的偏移 |
| element.offsetLeft | 返回元素相對帶有定位父元素的左邊框的偏移 |
| element.offsetWidth | 返回自身包括padding、邊框、內容區的寬度,返回數值不帶單位 |
| element.offsetHeight | 返回自身包括padding、邊框、內容區的高度,返回數值不帶單位 |
7.2offset與style的區別
| 可以得到任意樣式表的樣式值 | 只能得到行內樣式表中的值 |
| 得到的數值沒有單位 | 帶有單位 |
| offsetWidth包含padding+border+width | 不包含padding和border |
| 只讀屬性,只能獲取不能賦值 | 可讀可寫 |
| 適合用于獲取元素大小位置 | 用于修改元素樣式 |
7.3cilent
翻譯過來就客戶端,我們使用client的相關屬性來獲取元素可視區的相關信息。通過client系列的相關屬性可以動態的得到元素的邊框大小、元素大小
| element.clientTop | 返回元素上邊框大小 |
| element.clientLeft | 返回元素左邊框大小 |
| element.clientWidth | 返回自身包括padding、內容區的寬度、不含邊框、返回數值不帶單位 |
| element.clientHeight | 返回自身包括padding、內容區的高度,不含邊框,返回數值不帶單位 |
7.4立即執行函數
立即執行函數不需要調用直接執行
語法
(function(形參){})(實參); 或者 (function(形參){}(實參));第二個小括號可以看作是調用函數,里面可以傳實參
作用:將整個js代碼寫在立即執行函數中,里面的變量都是立即執行函數里的局部變量,在引用多個js文件時可以避免沖突,如下:
(function flexible(window,document){代碼 }(window,document));7.5pageshow事件
有三種情況會刷新頁面觸發load事件:
1、a標簽
2、F5或者刷新
3、前進后退按鈕
但是火狐中,有個特點,有個“往返緩存”,這個緩存中不僅保存著頁面數據,還保存了DOM和JavaScript的狀態;實際上是將整個頁面都保存在了內存里。所以此時后退按鈕不能刷新頁面。
此時可以使用pageshow事件來觸發。這個事件在頁面顯示時觸發,無論頁面是否來自緩存。在重新加載頁面中,pageshow會在load事件觸發后觸發,根據事件對象中的persisted來判斷是否是緩存中的頁面觸發的pageshow事件,注意這個事件給window添加。
7.6scroll事件
滾動事件,可以獲得元素的大小和滾動距離
| element.scrollTop | 返回被卷上去的上側距離,返回數值不帶單位 |
| element.scrollLeft | 返回被卷上去的左側距離,返回數值不帶單位 |
| element.scrollWidth | 返回自身實際的寬度不含邊框(包含內容超出容器的部分),返回數值不帶單位 |
| element.scrollHeight | 返回自身實際的高度(包含內容超出容器的部分),不含邊框,返回數值不帶單位 |
補充:mouseover和mouseenter區別
當鼠標移動到元素上就會觸發
- mouseover
? 經過父盒子和子盒子都會觸發一次(會冒泡)
- mouseenter
? 只有經過自身盒子才會觸發
八、動畫函數封裝
8.1動畫實現原理
核心原理:通過定時器setInterVal()不斷移動盒子位置
實現步驟:
1、獲得盒子當前位置(盒子記得加定位)
2、讓盒子在當前位置加上一個移動距離
3、利用定時器不斷重復這個操作
4、加一個結束定時器的條件
5、注意此元素需要添加定位,才能使用element.style.left
8.2簡單動畫函數封裝
注意需要兩個參數 動畫對象和移動距離
<script>var div=document.querySelector('div');function animate(obj,target){//封裝var timer=setInterval(function(){if(obj.offsetLeft>=target){clearInterval(timer);}obj.style.left=obj.offsetLeft+1+'px';},30);}animate(div,400);//調用 </script>8.3給不同元素記錄不同定時器
給封裝的對象創建一個屬性值timer令其等于一個定時器
obj.timer=setInterval(function(){})
所以優化8.2的代碼為
<script>var div=document.querySelector('div');function animate(obj,target){//封裝clearInterval(obj.timer);//先清除定時器防止一個對象的多個定時器同時運行obj.timer=setInterval(function(){if(obj.offsetLeft>=target){clearInterval(timer);}obj.style.left=obj.offsetLeft+1+'px';},30);}animate(div,400);//調用 </script>九、緩動動畫
緩動動畫就是讓元素運動速度有所變化,最常見的就是讓速度慢慢停下來
思路:
- 讓盒子每次移動距離變小
- 核心算法:步長=(目標值-現在的位置)/10 作為每次移動的距離
- 步長盡量取整數
- 盒子位置到目標位置就停止定時器
9.1緩動效果代碼
function animate(obj, target) {// 目的是讓元素只能有一個定時器,防止定時器效果累加clearInterval(obj.timer);obj.timer = setInterval(function () {// 步長值寫在定時器里面// 把步長值改為整數,盡量避免小數的出現// 前進:向上取整// 后退:向下取整var step = (target - obj.offsetLeft) / 10;step = step > 0 ? Math.ceil(step) : Math.floor(step);//必須是取最大整數,這樣沒有到0就會1像素前進保證能夠剛好到達目的地,因此目標位置和起始位置也應該為整數,以保證下面if語句必然觸發if (obj.offsetLeft == target) {clearInterval(obj.timer);}obj.style.left = obj.offsetLeft + step + 'px';}, 30) }例子:
<!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>.screen {position: relative;left: 50%;margin-left: -450px;width: 900px;height: 300px;border: 1px solid #999;}.box {position: absolute;top: 150px;margin-top: -25px;width: 50px;height: 50px;background-color: skyblue;}</style></head><body><div class="screen"><div class="box"></div></div><script>var box = document.querySelector('.box');function animate(obj, target) {clearInterval(obj.timer);obj.timer = setInterval(function() {var s = (target - obj.offsetLeft) / 10;s = s > 0 ? Math.ceil(s) : Math.floor(s); //必須是取最大整數,這樣沒有到0就會1像素前進保證能夠剛好到達目的地,因此目標位置和起始位置也應該為整數,以保證下面if語句必然觸發if (target == obj.offsetLeft) {clearInterval(obj.timer);} else {obj.style.left = obj.offsetLeft + s + 'px';}console.log(s);}, 30);}box.onclick = function() {animate(box, box.offsetLeft + 200);}</script> </body></html>9.2動畫函數添加回調函數
回調函數:函數作為參數麻將這個函數作為參數傳到另一個函數中,當那個函數執行完成后再去執行傳進去的這個函數,這個過程叫做回調
function animate(obj, target, callback) {clearInterval(obj.timer);obj.timer = setInterval(function () {var step = (target - obj.offsetLeft) / 10;step = step > 0 ? Math.ceil(step) : Math.floor(step);// 回調函數寫在定時器結束里if (obj.offsetLeft == target) {clearInterval(obj.timer);// 如果有回調函數傳進來if (callback) {// 調用函數callback();}}obj.style.left = obj.offsetLeft + step + 'px';}, 30) }十、網頁輪播圖
推薦看視頻
十一、移動端網頁特效
略
十二、本地存儲
- 數據存儲在用戶瀏覽器中
- 設置、讀取方便、甚至刷新不丟失數據
- 容量大,sessionStorage約5M,localStorage約20M
- 只能存儲字符串,可以將對象JSON.stringify()編碼后存儲
12.1 sessionStorage
- 生命周期為 關閉瀏覽器窗口消失
- 在同一窗口(頁面)下數據可以共享
- 以鍵值對的形式存儲使用
存儲數據
sessionStorage.setItem('key',value) var ipt =document.querySelector('input'); var set=document.querySelector('.set'); set.addEventListener('click',function(){var val=ipt.value;sessionStorage.setItem('uname',val); })獲取數據
sessionStorage.getItem('key');刪除數據
sessionStorage.removeItem('Key');刪除所有數據
sessionStorage.clear();12.2localStorage
-
生命周期永久生效,除非手動刪除否則關閉頁面也存在
-
可以多窗口共享(同一瀏覽器共享)
-
以鍵值對形式使用
存儲數據
localStorage.setItem('Key',value);獲取數據
localStorage.getItem('key');刪除數據
localStorage.removeItem('key');清除所有數據
localStorage.clear(); height: 50px;background-color: skyblue;} </style> ```9.2動畫函數添加回調函數
回調函數:函數作為參數麻將這個函數作為參數傳到另一個函數中,當那個函數執行完成后再去執行傳進去的這個函數,這個過程叫做回調
function animate(obj, target, callback) {clearInterval(obj.timer);obj.timer = setInterval(function () {var step = (target - obj.offsetLeft) / 10;step = step > 0 ? Math.ceil(step) : Math.floor(step);// 回調函數寫在定時器結束里if (obj.offsetLeft == target) {clearInterval(obj.timer);// 如果有回調函數傳進來if (callback) {// 調用函數callback();}}obj.style.left = obj.offsetLeft + step + 'px';}, 30) }十、網頁輪播圖
推薦看視頻
十一、移動端網頁特效
略
十二、本地存儲
- 數據存儲在用戶瀏覽器中
- 設置、讀取方便、甚至刷新不丟失數據
- 容量大,sessionStorage約5M,localStorage約20M
- 只能存儲字符串,可以將對象JSON.stringify()編碼后存儲
12.1 sessionStorage
- 生命周期為 關閉瀏覽器窗口消失
- 在同一窗口(頁面)下數據可以共享
- 以鍵值對的形式存儲使用
存儲數據
sessionStorage.setItem('key',value) var ipt =document.querySelector('input'); var set=document.querySelector('.set'); set.addEventListener('click',function(){var val=ipt.value;sessionStorage.setItem('uname',val); })獲取數據
sessionStorage.getItem('key');刪除數據
sessionStorage.removeItem('Key');刪除所有數據
sessionStorage.clear();12.2localStorage
-
生命周期永久生效,除非手動刪除否則關閉頁面也存在
-
可以多窗口共享(同一瀏覽器共享)
-
以鍵值對形式使用
存儲數據
localStorage.setItem('Key',value);獲取數據
localStorage.getItem('key');刪除數據
localStorage.removeItem('key');清除所有數據
localStorage.clear();總結
以上是生活随笔為你收集整理的黑马javascript笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: areas表-省市区
- 下一篇: JavaScript基础语法(一)