DOM&BOM.1

第一章

1.什么是DOM

DOM: Document Object Model(文檔對象模型)

是JavaScript的方法硅堆,僅當與特殊文檔對象配合使用時(如選擇器)妆距,才能發(fā)揮作用

什么是: 專門操作網頁內容的API標準

? ? ? ? W3C指定的標準肴茄,所有瀏覽器廠商遵照實現(xiàn)

何時: 今后只要操作網頁內容击你,就必須用DOM提供的API

為什么: 為了統(tǒng)一操作網頁內容的API

? ? ? ? 用DOM標準操作網頁內容幾乎100%兼容

分為: 核心 DOM 和 HTML DOM

核心DOM: 萬能剃氧,但繁瑣

HTML DOM: 對核心DOM中部分常用API的簡化敏储,專門操作HTML文檔的API

? ? ? ? ? ?不是萬能,但簡潔

總結: 實際開發(fā)中不必區(qū)分核心DOM和HTML DOM朋鞍,優(yōu)先使用簡單的API已添,如果實現(xiàn)不了,用復雜的補充

DOM樹:

什么是: 網頁中的一切內容在內存中都是以樹形結構存儲在一起的滥酥,每項內容(元素更舞,屬性,文本)都是樹上的一個節(jié)點對象

為什么: 樹形結構是保存不確定層級深度的上下級包含關系最好的結構

根節(jié)點:樹結構都有唯一的一個根節(jié)點:document節(jié)點坎吻,所有網頁內容缆蝉,都是document的子節(jié)點

節(jié)點對象:?網頁中的每一項內容都是一個節(jié)點對象,節(jié)點對象封裝了節(jié)點可用的屬性和功能

如何:三大屬性(返回的值):

.nodeType: 節(jié)點類型

什么是: 定義了節(jié)點的類型

何時: 區(qū)分節(jié)點的類型時

為什么: 不同類型的節(jié)點可用的屬性和可執(zhí)行的操作不同

值是整數(shù):4個:?document: 9 ? 根節(jié)點

? ? ? ? ? ? ? element: ? 1 ? ?元素節(jié)點禾怠,如<html>返奉、<body>、<p>

? ? ? ? ? ? ? attribute: 2 ? ?屬性節(jié)點吗氏,元素的屬性芽偏,如a標簽的鏈接屬性

? ? ? ? ? ? ? text: ? ?? 3 ? ?文本節(jié)點,標簽中的純文本

document.createTextNode("..."): 創(chuàng)建文本節(jié)點(無標簽)弦讽,括號內為文本值

問題: nodeType無法進一步區(qū)分具體的元素名

解決:nodeName

.nodeName: 節(jié)點名(元素的標簽名)

什么是: 保存節(jié)點名稱的屬性

何時: 進一步區(qū)分具體的元素名

為什么: 不同的元素擁有的屬性和可執(zhí)行的操作都不一樣

包括: document:? #document

? ? ? element: ? 元素的標簽名(全大寫)

? ? ? attribute: 屬性名

? ? ? text: ? ?? #text(文本節(jié)點)

其實, nodeName可代替nodeType來鑒別節(jié)點類型

.nodeValue: 節(jié)點值(了解)

什么是: 保存節(jié)點的值(幾乎不用)

包括: document:? null

? ? ? element: ? null

? ? ? attribute: 屬性值

? ? ? text: ? ?? 文本內容

_______________________________________________________________________________________________

DOM 操作流程:(增刪改查+事件處理)

查找觸發(fā)事件的元素 → 綁定事件處理函數(shù) → 查找要修改的元素 → /添加/刪除/修改:內容/屬性/樣式

_______________________________________________________________________________________________

2.查找:4種:

1. 不需要查找可直接獲得的元素:

? ?document.documentElement: html

??document.head: ? ? ? ? ? ?head

??document.body: ? ? ? ? ? ?body

2. 按節(jié)點間關系查找:

何時: 如果已經獲得一個元素污尉,要找周圍元素時

包括: 2大類關系:

節(jié)點樹: 包含所有節(jié)點的完整樹結構

父子:elem.parentNode: 獲得一個節(jié)點的父節(jié)點

? ? ? elem.childNodes: ? 獲得父節(jié)點下的所有直接子節(jié)點

? ? ? elem.firstChild: ? 獲得父節(jié)點下的第一個直接子節(jié)點

? ? ? elem.lastChild: ? ?獲得節(jié)點下的最后一個直接子節(jié)點

兄弟:?elem.nextSibling: ? ? 獲得一個節(jié)點相鄰的下一個兄弟節(jié)點

? ? ? elem.previousSibling: 獲得一個節(jié)點相鄰的前一個兄弟節(jié)點

問題: 受看不見的空字符文本節(jié)點的干擾,可用元素樹解決

元素樹: 僅包含元素節(jié)點的樹結構(父子關系中與CSS有差異)

何時: 只要僅關心元素往产,不關心其它類型的節(jié)點時

父子: elem.parentElement: ? ? ? ?獲得一個節(jié)點的父元素

? ? ?elem.children:? ? ? ? ? ?獲得父元素(elem)下的所有直接子元素

? ? ?elem.firstElementChild:獲得父元素(elem)下的第一個直接子元素

? ? ?elem.lastElementChild:獲得父元素(elem)下的最后一個直接子元素

兄弟:elem.nextElementSibling: ??獲得一個元素相鄰的下一個兄弟元素

? ? ??elem.previousElementSibling:獲得一個元素相鄰的前一個兄弟元素

說明: 元素樹不是一棵新樹被碗,僅是節(jié)點樹的一個子集

優(yōu): 不受空文本的干擾

缺: IE8不兼容

比較:childNodes和children返回的不是數(shù)組,而是類數(shù)組對象

? 類數(shù)組對象: 長的像數(shù)組的對象

? VS 數(shù)組: 相同: 1.下標仿村;2. ?.length锐朴;3.用for循環(huán)遍歷

? ? ? ? ?? 不同: 類型不同,API不通用

非動態(tài)/動態(tài)集合可以直接在選擇器后面加數(shù)字下標使用: elem.children[i]

其實,childNodes和children都返回動態(tài)集合

動態(tài)集合: 不實際存儲數(shù)據(jù)蔼囊,每次訪問集合焚志,都重新查找DOM樹

? 問題: 反復訪問集合衣迷,會導致反復查找DOM樹

? 遍歷動態(tài)集合:?錯誤: for(var i=0;i<children.length;i++){...}

? ? ? ? ? ? ? ? 正確:for(var i=0,len=children.length;i<len;i++){...}(按值傳遞)

用節(jié)點間關系,遍歷查找一個父元素下所有后代節(jié)點

1. 遞歸遍歷: 2步:

? ① 定義函數(shù)僅遍歷直接子節(jié)點

? ② 對每個碰到的子節(jié)點酱酬,調用和父節(jié)點完全相同的函數(shù)

算法:深度優(yōu)先: 每當同時有子元素和兄弟元素時壶谒,總是先遍歷子元素。子元素遍歷完膳沽,才返回遍歷兄弟元素

問題: 遞歸的執(zhí)行效率極低汗菜,可用循環(huán)代替

arguments.callee: 專門指代當前正在調用的函數(shù)自己

何時: 只要遞歸,在函數(shù)內調用自己挑社,必須加arguments.callee()代替

為什么: 避免修改外層函數(shù)名后陨界,還要重復修改內部調用的函數(shù)名

強調: 因為遞歸算法效率極低,所以ES6或新版瀏覽器中已經禁止使用arguments.callee滔灶,意味著不再推薦使用遞歸算法

caller? ? 返回一個對函數(shù)的引用普碎,該函數(shù)調用了當前函數(shù)

functionName.caller:? functionName對象是所執(zhí)行函數(shù)的名稱

callee? ? 返回正被執(zhí)行的Function對象,也就是所指定的Function對象的正文

[function.]arguments.callee:? 可選項function參數(shù)是當前正在執(zhí)行的Function對象的名稱

2. 用循環(huán)代替遞歸:

節(jié)點迭代器對象(NodeIterator): 專門按照深度優(yōu)先遍歷的順序依次訪問每個子元素的對象

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 內置"深度優(yōu)先"算法

如何用節(jié)點迭代器對象:2步:

1. 創(chuàng)建節(jié)點迭代器對象:

var iterator=document.createNodeIterator( ? ? ? ? //傳遞四個參數(shù)

? parent录平,NodeFilter.SHOW_ALL麻车,null,false ? ? ?? //NodeFilter.SHOW_ALL: 遍歷所有節(jié)點

? ? ? ? ? ? ? ? ? ? ?SHOW_ELEMENT ? ? ? ? ? ? ? ? //NodeFilter.SHOW_ELEMENT: 只遍歷元素節(jié)點

);

2. 用循環(huán)反復調用NodeIterator的nextNode()函數(shù)斗这,直到返回null退出:

do{

? var node=iterator.nextNode(); ? ? ?? //返回當前節(jié)點(同時會首先返回parent元素)

? if(node!=null){

? ? console.log(node.nodeType!=3?node.nodeName:node.nodeValue); ? ?//輸出node,跳到下一個節(jié)點

? }else break; ? ? ? ? ? ? ? ? ? ? ? ? //如果返回null,就退出循環(huán)

}while(true);

3.按HTML查找:4種:

?① 按id查找一個元素:var elem=document.getElementById("id值");

? ? 強調:1.必須用document調用动猬;2.只返回一個元素

?② 按標簽名查找多個元素:?var elems=parent.getElementsByTagName("標簽名");

? ? 強調:1. 可在任意父元素上調用(標簽名為*時,可查找所有后代元素)

? ? ? ?? 2.?不但找直接子元素表箭,而且查找所有(符合條件的)后代元素

? ? ? ?? 3.返回多個元素組成的動態(tài)集合

?③ 按name屬性查找(了解):?var elems=document.getElementsByName("name的值");

? ? 何時: 查找擁有name屬性的表單元素時

? ? 強調:1. 只能用document調用

? ? ? ?? 2.?返回動態(tài)集合

?④ 按class屬性查找:?var elems=parent.getElementsByClassName("class的值");

? ? 強調:1. 可在任意父元素上調用(IE8以下不支持)

? ? ? ?? 2.?不但找直接子元素赁咙,而且找所有(符合條件的)后代元素

? ? ? ?? 3.返回動態(tài)集合

? ? ? ?? 4.只要包含指定的類名,就選擇該元素免钻,不必完全匹配

問題: 每次只能按一種條件查找彼水,如果條件復雜,代碼會很繁瑣

解決: 當查找條件復雜時极舔,要用選擇器查找

4.按選擇器查找: Selector API:2個:

① 只找一個元素:

?var elem=parent.querySelector("selector");

② 找多個元素:

?var elems=parent.querySelectorAll("selector");

強調:1. 可在任意父元素上調用

? ?? 2. 不僅查找直接子元素凤覆,且查找所有(符合條件的)后代元素

? ?? 3.返回非動態(tài)集合

? ? ? ? 非動態(tài)集合: 實際存儲數(shù)據(jù),即使反復訪問拆魏,也不會導致反復查找DOM樹(遍歷時不用緩存length)

? ?? 4. 受制于當前瀏覽器的兼容性要求(IE8以下不支持)

this關鍵字:自動獲得 當前觸發(fā)事件的元素對象(在函數(shù)中時盯桦,用于回調函數(shù)或有實參的函數(shù))

if('querySelector' in document){? ? //檢查此函數(shù)是否存在

? document.querySelector("#id");

}else{

? document.getElementById("id");

}

var elems = parent.querySelectorAll("selector");

elems是NodeList對象,無法使用一些屬于數(shù)組的函數(shù)渤刃,可將elems轉換為數(shù)組拥峦,就能使用這些函數(shù)

方法① var arrayElements = [].slice.call(elems);

方法② var arrayElements = Array.from(elems);

_______________________________________________________________________________________________

筆試:

按HTML查找 VS 按Selector API 選擇器查找

?① 返回值: 按HTML查找,返回動態(tài)集合

? ? ? ? ? ? 按Selector API 選擇器查找卖子,返回非動態(tài)集合

?② 效率: 首次查找HTML效率高

? ? ? ? ? Selector API 查找稍慢

?③ 易用性: HTML查找更繁瑣

? ? ? ? ? ? Selector API 查找更簡潔

總結:1. 如果已經獲得一個元素略号,找周圍元素用節(jié)點間關系查找

? ? ?2. 如果通過一個條件就可找到想要的元素,用HTML查找

? ? ?3. 如果查找條件復雜時,用Selector API 選擇器查找

總結返回值:

? ? 1. 凡是返回一個元素的API玄柠,如果沒找到氛琢,都返回null

? ? 2. 凡是返回多個元素的API,如果沒找到随闪,都返回空元素的集合

_______________________________________________________________________________________________

過渡動畫: 不要用display

① js中: 用支持過渡的css屬性修改樣式:width、height骚勘、opacity...

② css中: 起始樣式铐伴;過渡的新屬性;transition:all .5s linear...

凡是帶transition的元素俏讹,無論以任何手段修改樣式屬性值当宴,都自帶過渡效果

測速比較:

console.time("getChildren1"); ? ?//開始:time() 和 結束:timeEnd()里的參數(shù)必須相同才能計算時間

getChildren1(document.body);

console.timeEnd("getChildren1");

console.time("getChildren2");

getChildren2(document.body);

console.timeEnd("getChildren2");

第二章*****************************************************************************************

修改內容:

.innerHTML: 獲取或設置元素 開始標簽到結束標簽之間的HTML代碼片段(設置會清除舊元素)

? ? ? ? ? ? 單標簽無返回值,沒有標簽的文本節(jié)點返回undefined

? ? ? ? ? ? 不包括本身的標簽,但包括子標簽及其屬性(轉義字符和正文會相互轉化)

.textContent:獲取或設置元素 開始標簽到結束標簽之間的純文本內容泽疆,單標簽無返回值

? ? ? ? ? ? ?不包括任何標簽户矢、轉義字符

? ? ? ? ? ? ? ? ① 去掉了內嵌的標簽

? ? ? ? ? ? ? ? ② 將所有轉義字符翻譯為正文(而不是標簽)

? ? ? ? ? ? ? ? 強調: IE8不兼容,用.innerText代替

.value: 專門獲得或設置 表單元素的輸入內容

? 注意: var a=input.value殉疼;變量string(原始類型)梯浪,a="";無法改變input的輸入內容

_______________________________________________________________________________________________

修改屬性:

標準屬性: 2種方式訪問:

1. 核心DOM: 4個API: 所有屬性節(jié)點都保存在元素的attributes集合中 ———繁瑣

? 獲取指定屬性值: ? elem.getAttribute("屬性名") ? ? ? ? ? ? →attribute.nodeValue 屬性的值

? 修改指定屬性值: ? elem.setAttribute("屬性名","屬性值")

? 是否包含指定屬性: elem.hasAttribute("屬性名")

? 移除指定屬性: ? ? elem.removeAttribute("屬性名")

elem.getAttributeNode("屬性名"); ?→text.nodeValue 返回屬性的節(jié)點內容,表示指定的屬性和值

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .value: ?返回屬性的值

指元素的第幾個屬性(從0開始): ?elem.attributes[i];

elem.getAttributeNode(elem.attributes[i]);? →elem2.nodeValue? 返回null

2. HTML DOM: 所有標準屬性都被提前封裝在了元素對象中瓢娜,可直接用.訪問 ———簡潔挂洛,首選

?獲取屬性值: elem.屬性名

?修改屬性值: elem.屬性名="屬性值"

?是否包含: ? elem.屬性名!=""? ? ? ? /*是否為空字符串*/

?移除屬性: ? elem.屬性名=""? ? ? ? ?/*設置為空字符串*/

注意: div沒有標準屬性width/height,所以要用style.css屬性名

特殊: class屬性: class是JS語言的保留字眠砾,所以DOM中的class屬性被迫改名為className

狀態(tài)屬性: .selected ? ?.checked ? ?.disabled ? ?屬性為boolean類型虏劲,無值

? ? ? ? ? 不能用核心DOM訪問,只能用HTML DOM訪問褒颈,訪問的結果都是boolean類型

比如: checked 屬性設置或返回checkbox是否應被選中:elem.checked = true / false

注意: preventDefault 即使是在checked屬性被切換的情況下也會阻止瀏覽器改變輸入選擇框的選擇

自定義擴展屬性: 如: data-toggle="dropdown" ? ?//大寫字母會自動轉為小寫

1. 核心DOM: ———繁瑣

? ?自定義擴展屬性不能用HTML DOM訪問

2.HTML5語法: ———簡潔

定義自定義屬性: ?data-屬性名="值"

獲取/修改屬性值: elem.dataset.屬性名="屬性值" ? ? /*與HTML DOM類似*/

elem.classList 屬性返回元素的類名柒巫,該屬性用于在元素中添加,移除及切換 CSS 類

elem.classList 屬性只讀谷丸,但可用.add("class1","class2")和.remove("myStyle")方法 添加/刪除 類名

? ? ? ? ? ? ? ?? 可添加/刪除多個堡掏,若已存在則不會添加,刪除不存在的類名也不會報錯

? ? ? ? ? ? ? ? ?但不要加空格

elem.classList 返回元素的類名組成的數(shù)組

elem.classList.length 屬性返回類列表中類的數(shù)量(只讀)

elem.classList.toggle(class1, true/false) 在元素中切換類名(移除返回false淤井,添加返回true)

? ? ? 第二個參數(shù)可選布疼,設置元素是否強制添加或移除類名,不管該類名是否存在(false移除币狠,true添加)

_______________________________________________________________________________________________

修改樣式: 2種:

單獨修改一個css屬性

1. 內聯(lián): 寫在元素的style屬性中的樣式

獲取或設置內聯(lián)樣式:?elem.style.css屬性名="值"

注意:都要先找到元素游两,在使用elem.style.屬性="值"來修改屬性值,要分成兩條語句

強調: ①css屬性名都要去橫線變駝峰:

? ? ? ?? 比如: background-color->backgroundColor

? ? ? ? ? ? ?? list-style-type->listStyleType

? ? ? ② 所有css屬性名的值都是字符串(需要帶單位)

? ? ? ?? 計算前都要先去單位漩绵,轉數(shù)字再計算

問題: 實際開發(fā)中可能幾乎不包含內聯(lián)樣式贱案,用elem.style可能無法獲得任何樣式

解決: 凡是讀取樣式,都要讀取計算后的樣式: getComputedStyle(elem)

ComputedStyle:計算后的樣式: 最終應用到元素上的所有樣式的綜合,并將相對單位計算為絕對單位

如何:①?var style=getComputedStyle(elem)?//獲得計算后的所有css屬性

? ? ? ? ? ?? //無法直接獲得img的原尺寸寬高宝踪,要等圖片加載完成(.onload)后才可以獲得

? ?? ②?style.css屬性名? ? ? ? ? ? ? ? ? ? ??//從style中獲得想要的css屬性

簡寫為:getComputedStyle(elem).display? ? ?? //獲取侨糟,不建議修改

強調: 計算后的css屬性都是只讀,不允許修改瘩燥,而應使用elem.style.css屬性名秕重,進行修改

因為計算后的css屬性可能原來是共用的,一旦修改厉膀,牽一發(fā)而動全身

elem.style.cssText? ? 批量修改元素的style屬性

elem.style.cssText += elem.style.cssText + '; 樣式';? ? //避免之前的屬性被覆蓋溶耘,在前面加分號避免瀏覽器會自動去除最后一個屬性的分號

2. 內部/外部樣式表: ———危險

3步:1. 找樣式表對象: var sheet=document.stylesheets[i]

? ? 2. 找cssRule對象: var cssRule=sheet.cssRules[i]

? ? ?? 如果是keyframes,就需要繼續(xù)找下級cssRule

? ? 3. 修改cssRule的style下的css屬性值:?cssRule.style.css屬性=值

問題: 一次只能修改一個css屬性

解決: 批量修改一個元素的多個class屬性

2步: ① 先在css中將多個屬性定義為一個class

? ? ?② 在js中修改元素的className為指定的class

_______________________________________________________________________________________________

2.添加/刪除/替換:

添加: 3步:

1.創(chuàng)建空元素:?var elem=document.createElement("標簽名")

?? 比如: var a=document.createElement("a"),相當于 <a></a>

2.設置關鍵屬性:

? ?比如:a.go to tmooc";

? ? ?? 相當于 <a > go to tmooc </a>

3. 將新元素添加到 DOM 樹指定父元素下:

? ?一個新元素服鹅,必須追加到 DOM 樹下指定的父元素下凳兵,才能顯示出來

?? 3種:末尾追加:parent.appendChild(elem)? ? //最常用

? ? ? ? ? ? ? ? ? ?//把頁面上現(xiàn)有元素追加到另一個parent中,原先的元素會移動到那個parent中

? ? ?? 中間插入:parent.insertBefore(elem,child)? ? /*將新elem 插在舊child前面*/

? ? ?? 替換: ? ??parent.replaceChild(elem,child)

_______________________________________________________________________________________________

優(yōu)化: 盡量減少操作 DOM 樹(即添加企软、修改庐扫、刪除元素)

原理: 頁面加載過程: ?html -> DOM Tree

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?↓

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Render Tree ->layout-> paint(繪制)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ↑ ? ?? 計算每個元素的絕對位置

? ? ? ? ? ? ? ? ? ?? css -> CSSRules

為什么: 每修改一次DOM樹,都會反復觸發(fā)layout仗哨,降低頁面響應速度

解決: 2種:

1.如果同時添加父元素和子元素時, 就要先在內存中將子元素添加到父元素中形庭,最后再將拼好的父元素整體一次性添加到DOM樹

2. 如果父元素已經在頁面上,要同時添加多個平級子元素藻治,就要用文檔片段

文檔片段: 內存中臨時保存多個子節(jié)點的虛擬父節(jié)點

何時: 要添加多個平級子元素

如何:3步:

? ① 創(chuàng)建文檔片段:?var frag=document.createDocumentFragment();

? ② 將子元素臨時追加到frag中:?frag.appendChild(elem);(在這之前先創(chuàng)建子元素碘勉,并設置關鍵元素)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //比如: 可以先設置left/top、canvas先畫好

? ③ 將frag整體追加到 DOM 樹:?parent.appendChild(frag);

說明: frag不會成為實際頁面元素桩卵,將子元素添加到DOM樹后验靡,frag自動釋放,不占用頁面空間

刪除:parent.removeChild(child);

第三章*****************************************************************************************

1.HTML DOM常用對象:

Image: 指代頁面上一個img元素

創(chuàng)建: ? ?var img=new Image();

指定屬性:img.src="banner_01.jpg";

追加: ? ?parent.appendChild(img);

圖片加載完成再進行操作:

方法① img.onload = function(){ ... }

方法②?img.onreadystatechange = function(){ if(this.readyState == "complete"){ ... }

Select: 指代頁面上一個<select>元素

屬性:sel.selectedIndex ? 獲得當前選中項的下標位置

? ?? sel.value ? ? ? ? ? 獲得當前sel的值(value),如果選中項沒有value,則用內容(innerHTML)代替

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<select>元素的值就是當前選中項的值

? ?? sel.options ? ? ? ?? 獲得當前sel下所有option元素的集合

? ?? sel.options.length ? 選項的個數(shù) <=> sel.length

? ?? sel.options.length=0 清除所有選項 <=> sel.length=0

? ? ?sel.options[sel.selectedIndex].text?獲取選中項的文本

方法:① sel.add(option) ? ? 向sel末尾追加一個option

? ? ? ? 強調: 不支持文檔片段(frag)(用frag時不用.add)

? ? ?② sel.remove(i)?? 移除i位置的選項

事件:sel.onchange? 當選中項發(fā)生改變時觸發(fā)此事件函數(shù)

Option: 指代頁面上一個option元素

創(chuàng)建/設置屬性:var opt=new Option(text,value)? ?? /*內容和值一起創(chuàng)建*/

屬性:opt.text代替opt.innerHTML

_______________________________________________________________________________________________

Table:指代一個table元素:?管著行分組: 創(chuàng)建雏节,刪除胜嗓,獲取

創(chuàng)建行分組: var thead=table.createTHead();

? ? ? ? ? ? var tbody=table.createTBody();

? ? ? ? ? ? var tfoot=table.createTFoot();

刪除行分組: table.deleteTHead();

? ? ? ? ? ? table.deleteTFoot();

獲取行分組: table.tHead

? ? ? ? ? ? table.tBodies[i]

? ? ? ? ? ? table.tFoot

行分組:tHead tBody tFoot: 管著行tr

創(chuàng)建行: var tr=行分組.insertRow(i);

? ? ? ? 說明: 如果i位置有行,則原位置的行向后順移

固定套路: 1.末尾追加新行: 行分組.insertRow();

? ? ? ? ? 2.開頭插入新行: 行分組.insertRow(0);

刪除行: 行分組.deleteRow(i) ? ? /*刪除當前行分組中下標為i的行*/

獲取所有行: 行分組.rows

行:管著格:

創(chuàng)建格: var td=tr.insertCell(i)

? ? 固定套路:末尾追加: tr.insertCell()

? ? 強調: insertCell只能創(chuàng)建td

刪除格: tr.deleteCell(i)

獲取格: tr.cells

刪除行:2種:

1. 行分組.deleteRow(i)

?? i是行在行分組內的相對下標位置, 無法直接獲得

2. table.deleteRow(i)

?? i是行在整個table中的絕對下標位置钩乍,可直接獲得:?tr.rowIndex ? ?表示tr在整個表格中的位置

固定套路:刪除行: table.deleteRow(tr.rowIndex)

_______________________________________________________________________________________________

三大對話框: 彈出的是窗口(對話框辞州,css/js改變的是body),無法改變標題寥粹、樣式等

alert(): 警告框

prompt(str1,str2): 輸入框

? str1:?輸入框的提示信息

? str2:?文本框的默認值变过,默認為空

? 返回值:?點擊確定返回文本框中的內容,點擊取消返回null

confirm(): 確認框(有確認和取消操作的對話框)

? 何時:只要執(zhí)行危險的操作前(提交更新涝涤、刪除)都要先確認再執(zhí)行操作

? 如何:var bool=confirm("提示消息");

? ? ? ? 如果點確定膀值,就返回true此虑,執(zhí)行操作

? ? ? ? 否則搂擦,就返回false雳灵,不執(zhí)行操作

Form: 代表頁面上一個form元素

獲取:var form=document.forms[i/'id']? ?獲取頁面上的第i個form元素或為此id的form元素

屬性: form.elements ? ? ? ? 獲得表單中的所有表單元素: input select button textarea

? ? ? form.elements.length ?獲得表單中表單元素的個數(shù) <=>?form.length

方法:form.submit(); ? ?? 用程序手動提交表單(定義一個變量,提交前修改其值,防止重復提交)

何時: 只要希望通過自定義的驗證去決定是否提交表單: 2種

1.?<input type="button"/>(代替input->submit: 自動提交,不驗證)在<input type="button"/>的單擊事件中自己手動調用form.submit();

2.<input type="submit"/>?用 e.preventDefault() 阻止表單默認提交

事件: form.onsubmit=function(){ }

獲取表單中的表單元素:var elem=form.elements[i/id/name]

簡寫:如果表單元素有name屬性: ? form.name

? ? ?如果表單元素沒有name屬性: form.elements[form.length-2] ? ?獲得倒數(shù)第2個按鈕(元素)

方法:elem.focus(); ?讓elem獲得焦點

? ? ?elem.blur(); ? 讓elem失去焦點

_______________________________________________________________________________________________

2.什么是BOM:Browser Object Model(瀏覽器對象模型)

BOM: 專門操作瀏覽器窗口/軟件的API(沒有標準辨宠,瀏覽器不同)

window:2個角色:

? 1. 代替ES遗锣、NodeJS中的Global充當全局作用域對象

? 2. 封裝所有瀏覽器內置的/DOM/BOM 的API

window的功能: 打開和關閉窗口,彈出對話框...

包括: history: ? 保存當前窗口打開后嗤形,成功訪問過的url的歷史記錄棧精偿,控制前進后退

? ? ? location:? 保存瀏覽器正在打開的url的地址

? ? ? document:? 封裝頁面內容和 DOM API的根對象

? ? ? navigator: 保存瀏覽器的配置信息

? ? ? screen: ?? 保存顯示設備的信息

? ? ? event: ? ? 定義事件對象

_______________________________________________________________________________________________

3.打開和關閉窗口:

打開一個新窗口: window.open("url","name")

所有在window下,都可省略window.

name: 內存中每個窗口都有一個唯一的name屬性

瀏覽器規(guī)定: 同一個name屬性的窗口只能打開1個

? ? ? ? ? ? 后打開的同名窗口會覆蓋先打開的

預定義name: _self: 用當前窗口的name打開新窗口

? ? ? ? ? ? ? ? ? ?結果: 新窗口替換當前窗口

? ? ? ? ? ? _blank: 不指定name屬性赋兵,用空name打開新窗口还最,讓瀏覽器隨機分配name

? ? ? ? ? ? ? ? ? ? 結果: 每個窗口的name都不一樣,就可打開多個

第三個參數(shù)可指定窗口樣式:

? 如:?var?newWindow = window.open("url","_blank",'top=100,left=100,width=300,height=300');

? ? ? top/left:?窗口頂部距離屏幕頂部/左端的像素數(shù)(指定寬高時有效)

? ? ? width/height:?窗口的寬/高毡惜,單位像素

? 可使用newWindow.close()關閉打開的窗口

打開和關閉窗口: 4種:

1. 在當前窗口打開,可后退:

? ?HTML: <a href="url" target="_self"></a>

? ?js: open("url","_self")

2. 在當前窗口打開斯撮,不可后退:

?? 當前窗口每打開一個新url经伙,都會將新url保存在history中

?? 如果新url是追加進history中,則可后退勿锅;如果新url將當前url替換掉帕膜,則無法后退到此頁面(其它正常)

? ?HTML: 無法實現(xiàn)

??js:location.replace("url")

3. 在新窗口打開,可打開多個:

?? HTML: <a href="url" target="_blank"></a>

?? js: open("url","_blank")

4. 在新窗口打開溢十,只能打開一個:

?? HTML: <a href="url" target="自定義name"></a>

??js: open("url","自定義name")

close(): ?關閉頁面

窗口大小: 文檔顯示區(qū)的大小:

寬:?window.innerWidth? ? ? ? 高:?window.innerHeight

body的寬垮刹、高(最短,不包括border、滾動條):? document.body.clientWidth/clientHeight;

屏幕可用工作區(qū)寬度(實際寬度):? window.screen.availHeight/Width;

_______________________________________________________________________________________________

4.定時器:2種:

周期性定時器:(盡量不要嵌套定時器)

若想要使等待的時間不斷變化张弛,只能在回調函數(shù)中荒典,先清除定時器,再啟動定時器(不要用var)

var reqParam = {

? arr: [0, 10000, 60000, 180000, 420000],? //請求間隔(0表示倒計時結束立即請求一次)

? max: [1, 10, 10, 10, 10],? ? ? ? ? ? ? ? //每種間隔最大請求次數(shù)

? index: 0,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //請求數(shù)組的當前下標

??count: 0,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //當前請求次數(shù)

??timer: null,? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//初始化請求次數(shù)定時器

??countTimer: null,? ? ? ? ? ? ? ? ? ? ? ? //初始化倒計時定時器

??ajaxType: 'jsonp',? ? ? ? ? ? ? ? ? ? ? ?//發(fā)起ajax請求的方式(可在單獨頁面中定義)

??jsonp: 'jsonp_callback',? ? ? ? ? ? ? ? ?//jsonp跨域函數(shù)名

? countdown: true,? ? ? ? ? ? ? ? ? ? ? ? ?//是否倒計時

? desc: '等待開獎',? ? ? ? ? ? ? ? ? ? ? ? //不顯示分吞鸭、秒時的字段

? jumpIssue: true? ? ? ? ? ? ? ? ? ? ? ? ? //是否允許跳期(在render中使用)

};

var?req= function(url1, url2){? ? //計算請求次數(shù)的函數(shù)

?reqParam.count++;

? if(reqParam.count?>=?reqParam.max[reqParam.index]){? //請求次數(shù)到達限定次數(shù)寺董,此間隔結束

? ? clearInterval(reqParam.timer);

? ?requestData(url1, url2);? ? ? ?//清理定時器之后,立即請求一次(本輪的最后一次)

? ? console.log("請求數(shù)組的當前下標:"+reqParam.index+"\n"+

? ? "當前請求次數(shù):"+reqParam.count+"\n"+"當前間隔時間:"+reqParam.arr[reqParam.index]);

? ? reqParam.index++;

? ? if(!reqParam.arr[reqParam.index]) return;? //reqParam.arr中的請求完畢后刻剥,不再進行請求

? ?reqParam.count?= 0;

? ?reqParam.timer= setInterval(function(){? //清除周期性定時器后遮咖,需要重新調用

? ? ?req(url1, url2);? ? ? ? ? ? ? ? ? ? ? ? //回調自己,進行請求

? ? }, reqParam.arr[reqParam.index]);

? }else{

? ?requestData(url1, url2);? ? ? ? //只在此處和階段循環(huán)結束時請求數(shù)據(jù)

? ? console.log("請求數(shù)組的當前下標:"+reqParam.index+"\n"+

? ? "當前請求次數(shù):"+reqParam.count+"\n"+"當前間隔時間:"+reqParam.arr[reqParam.index]);

? }

}

function?requestData(url1, url2){? ? //url1: 獲取多期造虏,url2: 獲取一期

? $.ajax({

? ? url: url1,

? ? data: window.param,? ? ? ? //傳入相應請求參數(shù)

? ? dataType: reqParam.ajaxType,

? ? jsonp: reqParam.jsonp,

? ? success: function(res){

? ? ? if(typeof res !== 'object'){

? ? ? ? res = $.parseJSON(res);

? ? ? }

? ? ? var countTimes = res.data.issueTime.recentDrawTime;? ? //倒計時

? ? ? if(countTimes < 0?&& window.param.num === 1)

? ? ? ? return false;? ? ? ? ? ? ? //后續(xù)請求時御吞,請求到的倒計時小于0,相當于沒請求成功

? ? ?clearInterval(reqParam.timer);? ? ?//請求成功后漓藕,需要第一時間清除定時器

? ? ? reqParam.index = 0;

? ? ? reqParam.count = 0;

? ? ? varrand= 1000;? ? ? ? ? ? ? ? ? ? //用于隨機數(shù)

? ? ? if(typeof render === 'function'){? ?//渲染數(shù)據(jù)(并在其中防止數(shù)據(jù)重復)

? ? ? ?render(res.data);

? ? ? }

? ? ?reqParam.countTimer= setInterval(function(){

? ? ? ? countTimes--; ? ? ? ? ? ? ? ? ?? //每秒減1進行倒計時

? ? ? if(countTimes > 0){

if(reqParam.countdown){

? ? ? ? ? var minute = parseInt(countTimes / 60);

? ? ? ? ? var seconds = parseInt(countTimes % 60);

? ? ? ? ? minute = minute >= 10 ? minute : '0' + minute;

? ? ? ? ? seconds = seconds >= 10 ? seconds : '0' + seconds;

? ? ? ? ? $('#timing').text(minute+':'+seconds);

? ? ? ? }

? ? ? }elseif(countTimes <= 0){

? ? ? ? ? clearInterval(reqParam.countTimer);? ? ? ? ? //倒計時結束陶珠,清除定時器

? ? ? ? ? $('#timing').text(reqParam.desc);

? ? ? ? ?rand*= parseInt(Math.random()*(10 + 1));? ? ?//隨機0-10秒

? ? ? ? ?rand+= res.data.issueTime.queryTime*1000;? ? //倒計時完畢后的查詢時間

? ? ? ? ? setTimeout(function(){

? ? ? ? ? ? console.log('隨機和查詢共:'+rand/1000+'秒');

? ? ? ? ? ? if(window.param.num){

? ? ? ? ? ? ? window.param.num = 1;? ?//當url1和url2相同時,修改window.param里的參數(shù)即可

? ? ? ? ? ? }

? ? ? ? ? ?req(url2, url2);? ? ? ? ? ?//請求一次成功后撵术,將url1替換為url2

? ? ? ? ? },?rand)

? ? ? ?}

? ? ?}, 1000)

? ? }

? })

}

$(function(){

?requestData(url1, url2);? ? //第一次請求數(shù)據(jù)不用定時器背率,所有js加載完畢后開始請求

})

什么是: 讓程序每隔一段時間間隔反復執(zhí)行一項任務(可在定時器中改變某個變量)

何時: 只要讓程序每隔一段時間間隔反復執(zhí)行一項任務

如何: 3件事:

1.任務函數(shù): function task(){...}

?? 定義了定時器每次要執(zhí)行的任務,可用if判斷臨界值,執(zhí)行操作(如停止定時器)

? ? ?停止當前定時器要把函數(shù)放在定時器內寝姿,不能單獨定義

2.啟動定時器: var timer=setInterval(task,間隔(ms))? ? //不要多次聲明(var),可以直接用(=)

?? 強調:task是回調交排,不用加(),要傳參數(shù)時可以把要執(zhí)行的函數(shù)放在回調函數(shù)內

?? 其中: timer是定時器在內存中唯一標識的一個整數(shù)序號(從1開始)

? ?何時: 只要一個定時器可能被停止饵筑,都要在啟動時先保存序號(var timer=...)

3.停止定時器: clearInterval(timer)

? ?其中: timer是要停止的定時器序號

?? 問題: 停止定時器不會自動清空timer變量中的序號埃篓,有可能影響下次啟動

?? 解決: 建議先停止定時器時,再手動清空timer(timer=null)

2種方式:① 手動停止: 用戶通過操作來停止定時器(用timer!=null判斷啟動/停止)

? ? ? ? ② 自動停止:?在任務函數(shù)內反復判斷臨界值

? ? ? ? ? ? ? ? ? ?? 只要達到臨界值根资,就自動停止定時器

一次性定時器:

什么是: 讓程序先等待一段時間架专,再自動執(zhí)行一次任務,執(zhí)行一次后自動停止

何時: 只要讓程序先等待一段時間玄帕,再自動執(zhí)行一次任務

如何: 3件事:?1. 任務函數(shù): ? function task(){...}

? ? ? ? ? ? ?2. 啟動定時器:var timer=setTimeout(task,等待ms)

? ? ? ? ? ? ?3. 停止定時器:clearTimeout(timer);

? ? ? ? ? ? ? ? ? ? ? ? ?? 用于在任務執(zhí)行前部脚,取消等待,不再執(zhí)行

window.onload: 當頁面中所有內容(html,css,js)都加載完裤纹,才自動觸發(fā)onload事件

原理: 定時器中的回調函數(shù)(task)只能在主程序所有語句執(zhí)行完才能開始執(zhí)行

筆試:

var a=10;

setTimeout(function(){console.log(a);},0); ?//先算a++委刘,再輸出11

a++;

注意:js中所有的異步回調函數(shù)(如定時器、ajax)都在正常代碼(非異步代碼)執(zhí)行完之后才執(zhí)行

原因: JavaScript是單線程執(zhí)行的

注意:① 定時器有一個最小執(zhí)行時間鹰椒,IE8及以下最小15.6ms锡移,其它最少4ms

? ? ?② 定時器中的this默認指向window,可使用bind()改變回調函數(shù)中的this

? ? ?③ 定時器的第3漆际、4...個參數(shù)表示第一個參數(shù)(回調函數(shù))傳入的參數(shù)

? ? ?④ 微信內置瀏覽器中淆珊,等待時間為0時,定時器可能會失效奸汇,建議改為10ms

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末施符,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子擂找,更是在濱河造成了極大的恐慌操刀,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件婴洼,死亡現(xiàn)場離奇詭異骨坑,居然都是意外死亡,警方通過查閱死者的電腦和手機柬采,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門欢唾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粉捻,你說我怎么就攤上這事礁遣。” “怎么了肩刃?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵祟霍,是天一觀的道長杏头。 經常有香客問我,道長沸呐,這世上最難降的妖魔是什么醇王? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮崭添,結果婚禮上寓娩,老公的妹妹穿的比我還像新娘。我一直安慰自己呼渣,他們只是感情好棘伴,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屁置,像睡著了一般焊夸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蓝角,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天淳地,我揣著相機與錄音,去河邊找鬼帅容。 笑死,一個胖子當著我的面吹牛伍伤,可吹牛的內容都是我干的并徘。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼扰魂,長吁一口氣:“原來是場噩夢啊……” “哼麦乞!你這毒婦竟也來了?” 一聲冷哼從身側響起劝评,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤姐直,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蒋畜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體声畏,經...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年姻成,在試婚紗的時候發(fā)現(xiàn)自己被綠了插龄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡科展,死狀恐怖均牢,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情才睹,我是刑警寧澤徘跪,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布甘邀,位于F島的核電站,受9級特大地震影響垮庐,放射性物質發(fā)生泄漏松邪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一突硝、第九天 我趴在偏房一處隱蔽的房頂上張望测摔。 院中可真熱鬧,春花似錦解恰、人聲如沸锋八。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挟纱。三九已至,卻和暖如春腐宋,著一層夾襖步出監(jiān)牢的瞬間紊服,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工胸竞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留欺嗤,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓卫枝,卻偏偏與公主長得像煎饼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子校赤,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容