JavaScript的組成結構梳理

Fardwn發表於2019-02-16

JavaScript經歷了殘酷的競爭,至今已經統治了web世界,現在系統梳理一下相關的知識。

JavaScript可以分為三部分:ECMAScript、DOM和BOM。

一、ECMAScript是JavaScript的核心,規定了這門語言的資料、語法、結構等基本概念。

Global是ECMAScript最頂級的物件(兜底物件),但體現在程式碼中它是不存在的。在JavaScript指令碼中使用此物件,會報錯(not defined),但是ECMAScript規定Number、Boolean、Object、NaN、Math等物件都是Global物件的屬性,對應的語法在此不做展開。

二、DOM是文件物件模型,是ECMAScript操作HTML的API。

DOM
DOM使用節點來把HTML以及XML文件描述成一個多層次的節點結構。

節點具有的通用屬性和方法:nodeType nodeName nodeValue childNodes parentNode previousSibling nextSibling fistChild lastChild ownerDocument ||方法 hasChildNodes() appendChild() insertBefore() replaceChild() cloneNode()

常用的節點型別:Document(9)、Element(1)、Text(3)、Doctype(10)型別。

Document型別:document物件是其例項物件,是window的屬性,表示整個HTML頁面。
document物件的特有屬性:documentElement(html節點) body(body節點) title URL(當前位址列顯示的url) domain(當前頁面的域名) referrer(連線到當前頁面的url)
document物件特有方法:getElementById() getElementByTagName() getElementByName(含有name屬性值)

Element型別:所有的常用標籤,<html>、<head>、<div>等標籤。
特殊屬性和方法:id、class等,getAttribute() setAttribute() removeAttribute() createElement()–建立一個元素節點。

Text型別:表示可以按字面意思解釋的純文字內容,可以是轉義後的HTML字元,不能包含HTML程式碼。
特殊屬性和方法:createTextNode() normalize()–去除空的文字節點以及合併兩個相鄰的文字節點 splitText(num)–將一個文字節點按照傳入的位置值分隔成兩個文字節點

DOM的擴充套件:(SelectorsAPI和HTML5兩部分)

SelectorsAPI部分
querySelector()和querySelectorAll()方法:Document和Element型別節點呼叫。
eg.var target = document.querySelector(`.abc/#abc/div`);//querySelectorAll()得到的是集合。

HTML5部分
getElementsByClassName()方法、scrollIntoView()方法(相當於錨點定位)

DOM2和DOM3(在DOM1基礎上引入了更多的互動能力):

DOM2級樣式部分
①通過style物件訪問css屬性(通過style標籤在HTML中定義的屬性),屬性含中劃線改為駝峰
document.getElementById(“abc”).style.width = “100px”;
document.getElementById(“abc”).style.backgroundColor = “red”;
②cssText屬性:設定多項屬性變化最快捷的方式
document.getElementById(“abc”).style.cssText = “width: 10px; height: 20px; color: red;……”
③getComputedStyle()方法:(三種定義方式)計算後的樣式的取值
var testItem = document.getElementById(“abc”)
document.defaultView.getComputedStyle(“testItem”).width//只讀屬性,不可更改設定。
④元素大小
偏移量:offsetHeight(元素可見高度+上下邊框高度+水平滾動條寬度)、offsetWidth、offsetLeft(元素左邊框距離其父元素的距離)、offsetRight【都為只讀屬性,每次訪問重新計算】
客戶區大小:clientWidth(元素內容寬度+左右邊框寬度)、clientHeight【都為只讀屬性,每次訪問重新計算】
滾動大小:scrollHeight(元素可見+滾動掉的+隱藏掉的的高度)、scrollWidth、scrollLeft(向左滾動掉的距離)、scrollTop
getBoundingClientRect()方法:該方法返回一個物件,包含四個屬性left、right、top、bottom,表示相對視口的位置(當前瀏覽器時候的左上角為(0,0))

DOM2級遍歷
NodeIterator型別和TreeWalker型別
document.createNodeIterator(root, whatToShow, filter, false)方法建立NodeIterator例項,其中root為遍歷的起點,whatToShow為顯示的節點型別(特定值),filter為顯示節點的過濾器函式(自定義),最後一個引數可忽略。
NodeIterator型別有個方法:nextNode()和previousNode(),表示深度遍歷的方向(向前、向後)
遍歷的過程:從給定的root根節點開始遍歷,由以上兩種方法確定方向向下遍歷。

<div id="test">
    <p><b>Hello</b> world!</p>
    <ul>
        <li>list item 1</li>
        <li>list item 2</li>
        <li>list item 3</li>
    </ul>
</div>
//想要遍歷div元素中的所有元素
var testItem = document.getElementById("test");
var iterator = document.createNodeIterator(testItem, NodeFilter.SHOW_ELEMENT, null, false);
var node = iterator.nextNode();
while(node!=null){
    alert(node.tagName);
    node = iterator.nextNode();
}
//輸入 DIV P B UL LI LI LI
//若只想輸出li標籤,可通過定義過濾器函式實現
var filter = function(node) {
    return node.tagName.toLowerCase() == `li`? NodeFilter.FILTER_ACCEPT: NodeFilter.FILTER_SKIP;
}
//NodeFilter.FILTER_ACCEPT表示接受該節點,NodeFilter.FILTER_SKIP表示跳過該節點

TreeWalker型別包含了NodeIterator型別的功能,更強大的是遍歷方向的多樣性
parentNode()、firstChild()、lastChild()、nextSibling()、previousSibling()
過濾器的屬性,增加一個NodeFilter.FILTER_REJECT表示跳過該節點包括該節點的整個子樹。

DOM2範圍控制(略)

DOM事件(JavaScript與HTML互動的橋樑)

DOM2級事件規定:事件流—事件捕獲階段->目標階段–>事件冒泡階段(可在一、三階段操作事件)
事件處理程式:
①HTML事件處理程式:

<div id="test" onclick="alert(`hellow world`)"></div>
<div id="test" onclick="sayHi()"></div>
function sayHi(){
    alert("hellow world")
}
//缺點,js和HTML耦合度高,載入HTML程式碼時js程式碼未載入(時差),作用域可能不同

②DOM0級事件處理程式:

var testItem = document.getElementById("test");
testItem.onclick = function() {
    alert("hellow world")
};
//移除事件處理程式 testItem.onclick = null;

③DOM2級事件處理程式:

testItem.addEventListener("click", function(){
    alert("hellow world")
},false);
//三參true表示捕獲階段處理事件,false冒泡階段處理,通過removeEventListener()移除事(僅限命名函式)

IE事件處理程式:

testItem.attachEvent("onclick", function(){});

事件物件(event物件)

觸發某個DOM事件時,會產生一個event物件,裡面記錄著所有與事件有關的資訊。
event常用屬性:currentTarget(當前元素)、target(事件目標)==>無事件委託時currentTarget=target=this,發生委託時==>currentTarget=this=事件註冊元素(一般父元素),target=事件目標元素(子元素)
阻止特定事件的預設行為:在event.cancelable == true時,用event.preventDefault()方法
阻止事件的冒泡行為:事先檢視event.bubbles == true,表示支援冒泡,用event.stopPropagation()。

事件型別(待續)

①window物件下的整體事件:
load(可發生在img、script標籤上,主要發生在window對喜愛那個上)、unload、resize、scroll
②焦點事件:blur、focus(均不支援冒泡)
③滑鼠和滾輪事件:
9個滑鼠事件mousedown、mouseup、click、dbclick、mouseenter、mouseover、mouseleave、mouseout、mousemove,一個滾輪事件mousewheel。
滑鼠的位置資訊:event中的clientX、clientY確定滑鼠的視窗位置,pageX,pageY確定滑鼠的頁面位置(包含發生滾動的部分),screenX、screenY確定滑鼠的物理螢幕位置。
click事件過程:mousedown->mouseup->click
dbclick事件過程:mousedown->mouseup->click->mousedown->mouseup->dbclick
Android和iOS裝置:不支援dbclick事件,輕擊觸發mousemove事件。
無障礙性(略)
④鍵盤事件
keydown(按任意鍵觸發),keypress(按任意可影響輸入字元鍵觸發)、keyup(釋放按鍵觸發)–以上可取到哦輸入的鍵碼,如ASCII碼。
textInput事件:相當於keypress事件,不同的是前者需可編輯區域觸發,後者焦點事件觸發,前者需實際字元鍵觸發,後者刪除鍵也可以,物件中有data屬性,儲存輸入的字元的字串表示。
⑤觸控和手勢事件
觸控事件:touchstart、touchmove(手指滑動時觸發,此事件預設滾動,可在此阻止滾動事件-preventDefault())、touchend.
在移動端觸控螢幕發生的事件依次為:touchstart->mouseover->mousemove->mousedown->mouseup->click->touchend.
手勢事件:兩隻手指觸控螢幕時(同一元素)會產生手勢,gesturestart(一個手指在螢幕上,另一隻手指觸屏時發生)、gesturechange(兩隻手指在螢幕上,任何一個手指移動時觸發)、gestureend(任何一個手指從螢幕移開時觸發)

事件委託:基於事件的冒泡機制,把子元素的事件委託給上級元素處理,減少了冗餘程式碼,增強了頁面效能。(對一類事件最少可定義一次,例如整個文件在最外層定義一個click事件)

三、BOM是瀏覽器物件模型,是ECMAScript操作瀏覽器的API。

window是BOM的核心物件,表示一個瀏覽器例項。它還充當著ECMAScript中的Global物件,因此網頁中定義的變數、物件、函式等都是它的屬性。

window物件瀏覽器相關的屬性和方法:
screenLeft和screenTop表示視窗相對螢幕的位置(moveTo()和moveBy()表示移動視窗的方法)。
innerWidth和innerHeight表示視窗的大小(resizeTo()和resizeBy()表示改變視窗的方法)。
open()和close()方法表示開啟和關閉某一URL的方法。
setTimeout()和setInterval()表示延時呼叫和間歇呼叫方法(毫秒數表示此毫秒後將任務新增到任務佇列)。
alert()、confirm()和prompt()為系統彈出提示框方法。

物件:
location物件:是window的屬性,也是document的屬性,即為應用同一屬性。
https://test.com.cn:8080/search/#info?wd=javascript(protocol「https:」、host「test.com.cn:8080」、hostname「test.com.cn」、port『8080』、pathname「search」、hash『info』、search「?wd=javascript」、href『完整url』和assign()、replace()、reload(),八個屬性三個方法)。
navigation物件:記錄瀏覽器相關引數。
screen物件:記錄顯示器相關引數。
history物件:go()、back()、forward()方法。

相關文章