DOM
- 什么是window? window是一個(gè)全局對(duì)象 指瀏覽器中的每個(gè)窗口就是window對(duì)象

-
什么是document? document是window的一個(gè)屬性,也是一個(gè)對(duì)象,通過document可以操作頁(yè)面上的內(nèi)容,是指瀏覽器顯示內(nèi)容的區(qū)域
document.png 什么是DOM?
DOM定義了操作和訪問html文檔的標(biāo)準(zhǔn)方法
DOM全稱: Document Object Model, 即文檔模型對(duì)象
所以學(xué)習(xí)DOM就是學(xué)習(xí)如何通過document對(duì)象操作網(wǎng)頁(yè)上的內(nèi)容
獲取DOM元素
document.getElementById() ; 通過Id獲取指定元素
由于id不可以重復(fù), 所以找到了就會(huì)將找到的標(biāo)簽包裝成一個(gè)對(duì)象返回給我們, 找不到就返回Null
注意點(diǎn): DOM操作返回的是一個(gè)對(duì)象, 這個(gè)對(duì)象是宿主類型對(duì)象(瀏覽器提供的對(duì)象)document.getElementsByClassName(); 通過類名獲取指定元素
由于class可以重復(fù), 所以找到了就返回一個(gè)存儲(chǔ)了標(biāo)簽對(duì)象的數(shù)組, 找不到就返回一個(gè)空數(shù)組document.getElementsByTagName(); 通過標(biāo)簽名獲取指定元素
由于class可以重復(fù), 所以找到了就返回一個(gè)存儲(chǔ)了標(biāo)簽對(duì)象的數(shù)組, 找不到就返回一個(gè)空數(shù)組document.getElementsByName();通過name名獲取指定元素
由于name可以重復(fù), 所以找到了就返回一個(gè)存儲(chǔ)了標(biāo)簽對(duì)象的數(shù)組, 找不到就返回一個(gè)空數(shù)組
注意點(diǎn):
getElementsByName 在不同的瀏覽器其中工作方式不同。在IE和Opera中, getElementsByName() 方法還會(huì)返回那些 id 為指定值的元素。
重點(diǎn)掌握
- document.querySelector(); 通過選擇器獲取(會(huì)根據(jù)指定選擇器拿到第一個(gè)元素)
- document.querySelectorAll(); 通過選擇器獲?。ǜ鶕?jù)指定選擇器獲取所有的元素)
- 獲取指定元素的所有子元素
兩種屬性可以獲取: 1. children(拿到所有子元素標(biāo)簽) 2.childNodes(拿到所有節(jié)點(diǎn))
<div class="box" id="div1">
<p>box1</p>
<form action="">
<input type="text" name="sex">
<input type="text" name="sex">
</form>
</div>
let odiv = doucument.querySelector(".box");//將返回的對(duì)象放在oDiv中
console.log(oDiv.children); //打印出所有子元素
什么是節(jié)點(diǎn)?
DOM對(duì)象,通過樹的形式保存了頁(yè)面上所有的內(nèi)容
HTML頁(yè)面上的每一個(gè)部分都是一個(gè)節(jié)點(diǎn)(屬性,標(biāo)簽,文本)。
節(jié)點(diǎn)
let odiv = doucument.querySelector(".box");
console.log(oDiv.childNodes);// 拿出所有節(jié)點(diǎn)
如果只要拿出標(biāo)簽怎么辦
for(let node of oDiv.childNodes) {//node 中有個(gè)nodeType屬性
//console.log(oDiv.childNodes); //標(biāo)簽對(duì)應(yīng)的nodeType為1,文本為3
//if( node.nodeType ===1) {
if(node.nodeNodes === Node.ELEMENT_NODE){ //專業(yè)寫法
console.log(node); //拿到標(biāo)簽
)
- 獲取指定節(jié)點(diǎn)中的第一個(gè)子節(jié)點(diǎn)
let odiv = doucument.querySelector(".box"); //拿到指定子節(jié)點(diǎn)
console.log(oDiv.firstChild);// 拿出第一個(gè)節(jié)點(diǎn) - 獲取指定節(jié)點(diǎn)中的第一個(gè)子標(biāo)簽
console.log(oDiv.firstElementChild);// 拿出第一個(gè)標(biāo)簽 - 獲取指定節(jié)點(diǎn)中的第一個(gè)子節(jié)點(diǎn)
console.log(oDiv.lastChild);// 拿出最后一個(gè)節(jié)點(diǎn) - 獲取指定節(jié)點(diǎn)中的第一個(gè)子標(biāo)簽
console.log(oDiv.lastElementChild);// 拿出最后一個(gè)標(biāo)簽 - 通過子元素獲取父元素/ 父節(jié)點(diǎn)
console.log(oDiv.parentElement); // 返回父元素(火狐低版本不支持)
console.log(oDiv.parentNode); //火狐支持
let parentEle = oDiv.parentElement || oDiv.parentNode //兼容性處理(通過子元素獲取父元素) - 獲取相鄰上一個(gè)節(jié)點(diǎn)
console.log(oDiv.previousSibling);
獲取相鄰上一個(gè)元素(標(biāo)簽)
console.log(oDiv.previousElementSibling); - 獲取相鄰下一個(gè)節(jié)點(diǎn)
console.log(oDiv.nextSibling);
獲取相鄰下一個(gè)元素(標(biāo)簽)
console.log(oDiv.nextElementSibling);
節(jié)點(diǎn)增刪改查
- 創(chuàng)建節(jié)點(diǎn)
let Ospan = document.createElement("span"); - 添加節(jié)點(diǎn)
注意點(diǎn): appendChild方法會(huì)將指定的元素添加到最后
let Ospan = document.createElement("span");
let oDiv = document.querySelector("div");
oDiv.appendChild(oSpan); //將span添加到選中的div中,默認(rèn)添加到最后 - 插入節(jié)點(diǎn)
let oSpan = document.createElement("span");
let oDiv = document.querySelector("div");
let oH1 = document.querySelector("h1");
oDiv.insertBefore(oSpan,oH1); // 將span添加到h1之前 - 刪除節(jié)點(diǎn)
只能通過父節(jié)點(diǎn)刪除(不能自己刪除自己);removeChild(); //刪除指定節(jié)點(diǎn)
let oSpan = document.querySelector("span");
console.log(oSpan.parentNode); //拿到span的父節(jié)點(diǎn)
oSpan.parentNode.removeChild(oSpan); 通過span的父元素刪除span - 克隆節(jié)點(diǎn)
注意:cloneNode方法默認(rèn)不會(huì)克隆子元素,如果需要克隆子元素,則需要傳入一個(gè)參數(shù) true
let oDiv = document.querySelector("div");
//oDiv.cloneNode(); //不會(huì)克隆子元素
let newDiv = oDiv.cloneNode(true); //克隆子元素
console.log(newDiv);
屬性增刪改查
<div class="box" id="div1" wj="666">
</div>
- 獲取元素屬性
let oDiv = document.querySelector("div");
console.log(oDiv.id); // div1
console.log(oDiv.getAttribute("wj")); // 666
oDiv.id與oDiv.getAttribute("wj")的區(qū)別 前者不能獲取自定義的屬性,后者可以
- 如何修改元素屬性
let oDiv = document.querySelector("div");
oDiv.id = "box" ; //將id的值改為box
oDiv.setAttribute("wj","888"); //將“wj”的值改為888(第一個(gè)參數(shù)為需要更改的屬性,第二個(gè)參數(shù)為修改的值)
兩種方式的區(qū)別: 前者不能更改自定義屬性,而后者可以 - 如何新增元素屬性
let oDiv = document.querySelector("div");
oDiv.setAttribute("ww","9527"); //只有這一種方法
setAttribute方法如果屬性不存在就是新增, 如果屬性存在就是修改 - 如何刪除元素屬性
let oDiv = document.querySelector("div");
oDiv.id = "" ; //將id的值清空 ,但會(huì)保留屬性名稱
oDiv.removeAttribute("wj"); //會(huì)將屬性名稱也刪掉
前者不能刪除自定義屬性,而后者可以
元素內(nèi)容操作
- 獲取元素內(nèi)容(3種方式)
- innerHTML // 獲取的內(nèi)容包含標(biāo)簽和空格
- innerText //只獲取內(nèi)容不包含標(biāo)簽和空格
- textContent //獲取內(nèi)容包含空格但不包含空格
let oDiv = document.querySelector("div");
console.log(oDiv.innerHTML);
console.log(oDiv.innerText);
console.log(oDiv.textContent);
- 設(shè)置元素內(nèi)容
用innerHTML/innerText /textContent 設(shè)置內(nèi)容,都會(huì)將原有的內(nèi)容覆蓋
innerHTML設(shè)置內(nèi)容,內(nèi)容中包含標(biāo)簽,會(huì)轉(zhuǎn)化成標(biāo)簽再添加
innerText /textContent 設(shè)置內(nèi)容,會(huì)將標(biāo)簽當(dāng)做字符串直接設(shè)置
let oDiv = document.querySelector("div");
oDiv.innerHTML = "123";
oDiv.innerText = "wfwf";
oDiv.textContent = "wj666";
兼容性處理 可以定義一個(gè)函數(shù)來解決
let oDiv = document.querySelector("div");
function setContent(obj,text) {
if("innerText" in obj){ //判斷obj對(duì)象中是否存在innerText屬性
obj.innerText = text;
}
else{
obj.textContent = text;
}
}
操作元素樣式
-
設(shè)置元素樣式
第一種方式 通過綁定類名
<style>
.box {
width: 300px;
height: 300px;
background: #000;
}
</style>
let oDiv = document.querySelector("div");
// 注意點(diǎn): 由于class在JS中是一個(gè)關(guān)鍵字, 所以叫做className
// oDiv.className = "box";
第二種方式
// 注意點(diǎn): 過去CSS中通過-連接的樣式, 在JS中都是駝峰命名
// 注意點(diǎn): 通過JS添加的樣式都是行內(nèi)樣式, 會(huì)覆蓋掉同名的CSS樣式
let oDiv = document.querySelector("div");
oDiv.style.width = "200px";
oDiv.style.height = "200px";
oDiv.style.backgroundColor = "red";
-
獲取元素樣式
let oDiv = document.querySelector("div");
oDiv.style.width = "300px";
console.log(oDiv.style.width);
通過style屬性只能過去到行內(nèi)樣式的屬性值, 獲取不到CSS設(shè)置的屬性值
如果想獲取到CSS設(shè)置的屬性值, 必須通過getComputedStyle方法來獲取
etComputedStyle方法返回一個(gè)對(duì)象, 這個(gè)對(duì)象中就保存了CSS設(shè)置的樣式和屬性值let style = window.getComputedStyle(oDiv);
console.log(style.width); //獲取css設(shè)置的屬性值
事件
什么是事件? 是指用戶和瀏覽器之間的交互行為 比如鼠標(biāo)單擊 移入移出 等
在JavaScript中所有的標(biāo)簽都可以綁定事件
如何給標(biāo)簽綁定事件
格式 : 元素.事件名 = function(){
事件被觸發(fā)需要執(zhí)行的內(nèi)容
}
當(dāng)事件被觸發(fā)時(shí),就會(huì)執(zhí)行function中的代碼
有些標(biāo)簽系統(tǒng)默認(rèn)會(huì)綁定事件,如a標(biāo)簽 就綁有點(diǎn)擊事件
如果再給a標(biāo)簽綁定點(diǎn)擊事件,不會(huì)覆蓋系統(tǒng)綁定的事件,運(yùn)行時(shí)會(huì)先執(zhí)行我們綁定的事件,然后再執(zhí)行系統(tǒng)執(zhí)行的事件
let oA = document.querySelector("a");
oA.onclick = function (){
alert("我先執(zhí)行");
//return false ; //會(huì)覆蓋系統(tǒng)綁定的事件
}
如果需要覆蓋系統(tǒng)綁定的事件,只要在函數(shù)的最后寫上 return false 即可
定時(shí)器
定時(shí)器的作用就是隔一段時(shí)間再執(zhí)行(和定時(shí)關(guān)機(jī)效果一樣)
定時(shí)器分為 重復(fù)執(zhí)行的定時(shí)器 和 只執(zhí)行一次的定時(shí)器
定時(shí)器的用法
重復(fù)執(zhí)行的定時(shí)器
window.setInterval(function () {} , 1000);
//第一個(gè)參數(shù)是需要執(zhí)行的內(nèi)容,第二參數(shù)是間隔時(shí)間,單位是毫秒
定時(shí)器會(huì)返回一個(gè)值,將這個(gè)值清空定時(shí)器就會(huì)停止
let oBtn = document.querySelector(".start");
let id = null; //定義一個(gè)變量接收定時(shí)器返回的數(shù)值
oBtn.onclick = function () {
id = window.setInterval(function(){
console.log(123); },1000)// 等待1000ms然后打印123
}
let oBtn1 = document.querySelector(".close");
oBtn1.onclick = function() {
clearInterval(id); //清空id的值,停止定時(shí)器
}
只執(zhí)行一次的定時(shí)器
let oBtn = document.querySelector(".start");
let id = null; //定義一個(gè)變量接收定時(shí)器返回的數(shù)值
oBtn.onclick = function () {
id = window.setTimeout(function(){
console.log(123); },1000)// 等待1000ms然后打印123
}
let oBtn1 = document.querySelector(".close");
oBtn1.onclick = function() {
clearTimeout(id); //清空id的值,停止定時(shí)器
}
ES6箭頭函數(shù)和普通函數(shù)的區(qū)別
ES6箭頭函數(shù)中this指向的是他父作用域的this(并不是調(diào)用他的函數(shù))
普通函數(shù)中this指向的調(diào)用函數(shù)的對(duì)象
let obj = {
name : "wj" ,
say : function() {
console.log(this);
},
speak : () => {console.log(this);}
}
obj.say();// 結(jié)果 obj對(duì)象
obj.speak();// 結(jié)果 window
普通函數(shù)中this的指向可以通過call等方法改變
箭頭函數(shù)中this的指向無法改變
class Person{
constructor(){
this.name = "wj";
}
say(){
console.log(this);
}
speak = () => {
console.log(this);
}
}
class Son{
constructor(){
this.name = "wj666";
}
say(){
console.log(this);
}
speak = () => {
console.log(this);
}
}
let obj = new Person();
let objj =new Son();
obj.say(); // Person
obj.say.call(objj); // Son (使用call方法改變了this)
obj.speak.call(objj);// Person (使用call并沒有改變this的指向)
閉包
- 閉包也是一種函數(shù)
- 如何實(shí)現(xiàn)閉包: 兩個(gè)要求:(1)、函數(shù)嵌套 (2)、內(nèi)部的函數(shù)要引用外部函數(shù)的數(shù)據(jù)
- 閉包的特點(diǎn): 延長(zhǎng)了局部變量的生命周期
- 注意: 如果后期不使用閉包,要手動(dòng)設(shè)置閉包為null 否則會(huì)出現(xiàn)內(nèi)存泄漏
- ES6中{}是一個(gè)塊級(jí)作用域,在這個(gè)塊級(jí)作用域定義了一個(gè)函數(shù)并且引用了外部塊級(jí)作用域的數(shù)據(jù),這個(gè)函數(shù)就是一個(gè)閉包。
for( let i = 0;i<10;i++){
function f() { //閉包
console.log(i + 1);
}
}
f(); //10 (后面的父f()將前面的f覆蓋了)
