本篇文章已授權微信公眾號 dasu_Android(大蘇)獨家釋出
宣告
本系列文章內容全部梳理自以下四個來源:
- 《HTML5權威指南》
- 《JavaScript權威指南》
- MDN web docs
- Github:smyhvae/web
作為一個前端小白,入門跟著這四個來源學習,感謝作者的分享,在其基礎上,通過自己的理解,梳理出的知識點,或許有遺漏,或許有些理解是錯誤的,如有發現,歡迎指點下。
正文-JavaScript-客戶端API & jQuery
JavaScript 是用來豐富網站的內容的,讓網站支援各種互動行為功能等等。
JavaScript 是一門指令碼語言,自然有它自己的語法標準,這個標準由 ECMAScript 釋出,因此相對應的版本標準通常都簡寫成 ES5、ES6。
這次入門系列,並不打算先從語法入手學習,而是打算先學學客戶端 API,也就是瀏覽器提供的相關 JS API,用來操作 HTML 文件,畢竟入門學習的話,並不會涉及很多複雜的業務邏輯,相反,大多都是 JS 操作 DOM 的相關操作,因此,先從這方面進行學習。
基礎語法
如果有一定的 Java 基礎,那麼,只需瞭解下一些基礎的 JS 語法,便可開始學習相關的客戶端 API,熟悉後,足夠編寫 JS 程式碼來操作 DOM,達到動態網頁的效果了。
- 弱語言型別
所謂的弱語言型別,就是說,宣告變數型別時不必明確宣告其型別,只需用 var 宣告即可:
比如 Java 中需要定義如下變數:
int a;
float a;
double a;
String a;
boolean a;
而 JavaScript 中,統一用 var 定義一個變數:
var a;
- 變數的資料型別
雖然宣告變數時,不必指出變數的型別,但也要清楚下,JS 中的基本資料型別 :
在 JavaScript 中,只要是數,就是 Number 數值型的。無論整浮、浮點數、無論大小、無論正負,都是 Number 型別的。
可以使用內建方法:isNaN(),來判斷某個變數是否是數值型別。
關鍵字 typeof 可以打出變數的型別,如果需要檢視某個變數的型別時。
- 型別的強制轉換
轉 String:
- 變數 + “”
- 變數.toString()
- String(變數)
轉 Number:
- parseInt/Float(變數)
跟 Java 有些類似。
- 函式
function sum(a, b){
return a+b;
}
var sum = function(a, b) {
return a+b;
}
函式宣告有兩種方式,這兩種方式的宣告是有一定的區別的,在於 JS 中的宣告提前的影響,這部分先不用過多瞭解,後續詳細講語法時再來討論。在其他方面,這兩種宣告方式基本等效。
當需要有返回值時,直接在最後一行程式碼里加上 return。函式名也可以省略,此時稱匿名函式。
當定義了函式之後,需要呼叫函式的時候,直接用函式名(),如 sum(1,2)
但如果只是想把函式跟某一事件繫結時,此時只需要函式名,如:
button.onclick() = sum;
如果此時 sum 也帶上括號: sum(),那麼函式就會被呼叫,這裡需要注意。
- 物件
在 Js 中可以不必像 Java 那樣新建個類,然後從這個類 new 出物件。在 Js 中,需要物件時,直接 new Object(),然後賦予想要的屬性和行為即可。
首先建立一個物件:
var obj = new Object();
向物件中新增屬性:
obj.name = "dasu";
obj.age = 25;
物件的屬性值可以是任何的資料型別,也可以是個函式:
obj.sayName = function () {
console.log(`dasu`);
};
建立物件的方式也可以用另外一種方式:
var o = {
name: "dasu",
age: 25,
sayName: function() {
console.log(this.name);
}
};
當然也可以使用類似於 Java 定義類,例項化物件的方式。
- 相等比較
Js 中比較分兩種,嚴格和非嚴格,對應的操作符:===&!==
和 ==&!=
兩個等號的比較時,比較的兩個變數只要數值上相等,那麼就返回 true,三個等號的比較時,需要同時滿足型別和數值相等兩個條件才會返回 true。
以上基本的語法瞭解後,至少就知道如何宣告變數、函式、物件,如何使用了,這就足夠了,那麼接下去就是熟悉下客戶端 API,也可以說是瀏覽器按照標準提供的各 API 的使用。
DOM 概念
DOM(document object model):文件物件模型
瞭解 JavaScript 基本語法後,就要接著瞭解 DOM 概念。類似於 CSS 通過選擇器來操作 HTML 文件中的元素。那麼,同樣的道理,js 也需要有個中間媒介來操作 HTML 文件中的元素,這個媒介就是 DOM。
概念
那麼,什麼是 DOM 呢,其實就是瀏覽器根據 HTML 文件構建出的一顆 DOM 樹,樹中每個節點對應著 HTML 文件中的每個元素標籤,因此樹的結構可以很好的表現出各個元素之間的層級關係。
另外,每個節點都攜帶著當前元素的所有資訊,包括 CSS 作用的樣式屬性表,設定的型別,id 等等,這些資訊可以通過節點的各種屬性方法獲取到。
但有一點需要注意下,元素修飾的文字內容也會被建立成一個節點,作為這個元素的子元素加入 DOM 樹中。
這種 DOM 樹的概念跟 Android 中的檢視樹很類似。所以,每份 HTML 文件都會對應一顆 DOM 樹。
JavaScript 可以通過全域性變數 document 拿到這個 DOM 樹物件,那麼之後就可以根據 DOM 提供的各種 API 介面來操縱這顆 DOM 樹,包括獲取指定節點的元素,動態修改該節點元素的資訊,給這個節點元素繫結上事件操作等等。
模型示例
一顆DOM樹究竟長什麼樣子呢?看個例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>博雅</title>
</head>
<body>
<div>這裡<span>行內</span>不行</div>
<p>示例</p>
</body>
</html>
上述是一份特別簡單的 HTML 文件,看看它相對應的 DOM 樹 :
這就是對應的 DOM 樹,層次分明,各節點都表示相對應的元素資訊。但有一點需要注意下,橘色框都是相對應元素的文字內容,它也是 DOM 樹中的節點,型別是 Text 物件。並且,並不是一個元素的所有文字內容作為一個 Text 物件,如果文字內容被其他元素標籤分割開了,那麼這些文字內容會被分割成多份節點,都作為元素的子元素拼接在 DOM 樹中。
相容性
想想,這顆 DOM 樹是誰來建模生成的呢?很明顯,是瀏覽器吧,瀏覽器解析 HTML 文件以及 CSS 後,根據當前的檢視建模出一顆 DOM 樹出來。並提供了各種 API 介面供 JavaScript 來操縱。
那麼,不同的瀏覽器廠商實現可能就會有所不同,比如 W3C 規定了一系列操縱 DOM 的 API 介面,但瀏覽器不想全部實現,就實現了其中核心部分,或者就算實現了,具體表現也有可能有所不同。
那麼,這時就會存在一個問題了,也就是我們通過 JavaScript,然後根據 W3C 規範的 API 介面來操縱 DOM 時,可能在不同瀏覽器上有不同的變現行為。所以,這時就需要考慮相容性處理了。
但有一個更方便的解決方案,那就是使用jQuery,這是一個基於 JavaScript 的框架庫,它封裝了操縱 DOM 的各種功能,內部對不同瀏覽器進行了相容性處理,那麼我們使用的時候就可以不用再去考慮那麼相容性的處理了。
所以,下面會分別介紹 W3C 規範的標準 API 和 jQuery 的使用:
DOM API
document
document 是內建的全域性變數,在 JavaScript 可以直接通過該關鍵字使用,使用時會獲取到當前 HTML 文件對應的 Document 物件。
拿到這個物件後,就可以呼叫它的一些屬性和方法來獲取或修改我們想要的資料。
readyState | 檢視當前文件的被瀏覽器載入的狀態(載入中等) |
---|---|
body/head/title | 直接獲取文件的相關元素標籤資訊 |
getElementByXXX() | 根據id,class,tag等在文件中查詢指定元素 |
createElement(tag) | 建立指定標籤的元素節點 |
craeteTextNode(text) | 建立指定文字內容的Text物件 |
location | 返回當前文件地址的Location物件 |
API很多,需要的時候再查就行,主要清楚下,document 是 JavaScript 操縱 DOM 樹的入口,從這裡開始,可以獲取一些關於文件的後設資料方面的屬性資訊,也可以來查詢指定的文件中某個節點的元素物件。
location
Location 物件提供了細粒度的文件地址資訊,也支援導航到其他文件上。當開啟新文件在 URL 中有攜帶了一些資訊時,可以通過這個來獲取這些資訊。
protocol | 獲取或設定文件URL的協議部分 |
---|---|
host | 獲取或設定文件URL的主機和埠部分 |
href | 獲取或設定當前文件的地址 |
hostname | 獲取或設定文件URL的主機名部分 |
port | 獲取或設定文件URL的埠部分 |
pathname | 獲取或設定文件URL的路徑部分 |
search | 獲取或設定文件URL的查詢(問號串)部分 |
hash | 獲取或設定文件URL的錨(#號串)部分 |
assign(url) | 導航到指定的URL |
replace(url) | 清除當前文件並導航到新的URL |
reload() | 重新載入當前文件 |
resolveURL(url) | 將指定的相對URL解析成絕對URL |
window
window 直譯過來就是視窗,其實也就是表示文件當前所顯示的視窗物件,所以一些視窗性的功能都可以通過這個物件來呼叫。
比如:呼叫瀏覽器彈框、定時器的使用、獲取視窗資訊包括視窗寬高,螢幕寬高等等、視窗的滑動、操縱瀏覽器視窗的歷史記錄、向其他視窗傳送訊息等等。
- 獲取視窗相關資訊:
innerHeight/Width | 獲取視窗內容區域的寬高 |
---|---|
outerHeight/Width | 獲取視窗的寬高,包括邊框和選單欄等等 |
screen | 獲取描述螢幕的Screen物件 |
Screen.width/height | Screen物件獲取螢幕寬高 |
Screen.availWidth/Height | 獲取螢幕可用的寬高,去掉工具欄選單欄 |
pageX/Yoffset | 獲取視窗在水平/垂直方向已滾動過的畫素 |
document | 獲取次視窗關聯的Document物件 |
history | 訪問瀏覽器歷史 |
location | 獲取當前文件地址的詳細資訊 |
- 與視窗互動:
blur() | 讓視窗失去鍵盤焦點 |
---|---|
close() | 關閉視窗(不是所有瀏覽器都允許js關閉視窗) |
focus() | 讓視窗獲得鍵盤焦點 |
scrollBy(x, y) | 讓文件相對於當前位置進行滾動 |
scrollTo(x, y) | 滾動到指定位置 |
alert(msg) | 彈出一個對話方塊 |
confirm(msg) | 彈出一個帶有確認和取消的對話方塊 |
showModalDialog(url) | 彈出視窗,顯示指定的URL |
postMessage(msg, origin) | 給另一個文件傳送訊息 |
set/clearInterval(fun, time) | 建立/撤銷週期性的任務 |
set/clearTimeout(fun, time) | 建立/撤銷延時任務 |
HTMLElement
通過 document 獲取到 Document 物件,以此來獲取操縱 DOM 的入口,根據需要獲取所需的文件相關資訊,或者搜尋指定的 DOM 中節點的元素,此時這個節點的元素物件就是 HTMLElement 物件。
所有的標籤元素的基類物件都是 HTMLElement,這個類定義的公共的、基礎的操作元素節點的方法和屬性。
但每個標籤實際上都有具體的實現類,比如 body 對應 HTMLBodyElement,script 對應 HTMLScriptElement,具體實現類由這個標籤獨有的屬性和方法。
基類 HTMLElement 物件定義的基礎的方法、屬性包括:獲取或修改元素的指定屬性,新增或移除元素某個 class,檢視或修改該標籤包裝的內容等等。
- 元素的後設資料屬性:
classList | 獲取元素設定的class列表,返回DOMTokenList物件,可直接add,remove等操作 |
---|---|
className | 獲取元素設定的class列表,返回字串 |
disabled/hidden/id | 獲取或設定disable/hidden/id… |
attributes | 獲取元素設定的屬性值列表,返回Attr[]物件 |
innerHTML | 獲取元素標籤包裝的內容,包括文字內容及子元素 |
outerHTML | 獲取元素整個內容 |
- 節點元素操縱
get/has/removeAttribute(name) | 獲取/判斷/移除元素的某個屬性 |
---|---|
setAttribute(name, value) | 設定元素的某個屬性 |
appendChild(HTMLElement) | 為當前元素新增子元素 |
cloneNode(boolean) | 拷貝一份當前的元素,返回新的HTMElement物件,引數設定是否拷貝當前元素的子元素 |
isEqualNode(HTMLElement) | 判斷指定元素與當前是否相同,具有相同的class,相同的屬性,相同的子元素 |
isSameNode(HTMLElement) | 判斷是否是同一個元素 |
removeChild(HTMLElement) | 移除指定的子元素 |
replaceChild(HTMLElement, H.) | 替換指定的子元素 |
DOM 事件
通過上述一些方法,JavaScript 可以定位找到所需的元素,然後也可以動態的修改相關資料,但通常,這些動態修改的操作都是使用者操作了某些事件後去觸發的。
所以,即使找到了元素後,還需要將元素與一些事件進行繫結,比如點選事件等等。
有兩種方式讓元素繫結事件和處理的方法:
addEventListener
var aElems = document.getElementsByTagName("a");
for (var i = 0; i < aElems.length; i++) {
aElems[i].addEventListener("click", function () {
console.log("addEventListener:" + this);
});
}
呼叫 HTMLElement 物件的 addEventListener()
方法,第一個引數傳入需要監聽的事件名稱,第二個引數為事件觸發時的響應方法。
相對應的,還有一個 removeEventListener()
方法,同樣接收這兩個引數。
onXXX
var aElems = document.getElementsByTagName("a");
for (var i = 0; i < aElems.length; i++) {
aElems[i].onclick = function () {
console.log("onclick:" + this);
}
}
第二種方式,是在需要註冊的事件型別前面加 on 作為元素的屬性來註冊事件的監聽,這種比較常見。
所有事件型別
- document 的事件
事件型別 | 含義 |
---|---|
readystatechange | readyState屬性值發生變化時觸發,也就是文件載入的不同階段觸發 |
- window 的事件
onabort | 在文件或資源載入過程中被終止時觸發 |
---|---|
onerror | 在文件或資源載入發生錯誤時觸發 |
onhaschange | 在錨部分發生變化時觸發 |
onload | 在文件或資源載入完成時觸發 |
onresize | 在視窗縮放時觸發 |
onunload | 在文件從視窗或瀏覽器中解除安裝時觸發 |
- 滑鼠事件
click | 單擊,釋放時觸發 |
---|---|
dblclick | 雙擊,釋放時觸發 |
mousedown | 點選滑鼠鍵時觸發 |
mouseenter | 在游標移入元素或某個後代元素所佔據的螢幕區域時觸發 |
mouseleave | 在游標移出元素及所有後代元素所佔據的螢幕區域時觸發 |
mousemove | 游標在元素上移動時觸發 |
mouseout | 與mouseleave基本相同,除了當游標仍然在某個後代元素上時也會觸發 |
mouseenter | 與mouseenter基本相同,除了當游標仍然在某個後代元素上時也會觸發 |
mouseup | 當釋放滑鼠時觸發 |
滑鼠事件被觸發時,指定的處理方法都會傳入一個 MouseEvent 物件,該物件攜帶一些額外的屬性和方法供處理。
- MouseEvent
button | 標明點選的是哪個鍵,0:滑鼠主鍵,1:中鍵,2:次鍵 |
---|---|
altkey | 事件觸發時是否有點選alt鍵 |
clientX | 事件觸發時滑鼠相對於元素視口的X座標 |
clientY | 事件觸發時滑鼠相對於元素視口的Y座標 |
screenX | 事件觸發時滑鼠相對於螢幕座標系的X座標 |
screenY | 事件觸發時滑鼠相對於螢幕座標系的Y座標 |
shiftKey | 事件觸發時是否有點選shift鍵 |
ctrlKey | 事件觸發時是否有點選ctrl鍵 |
- 鍵盤焦點事件
blur | 在元素失去焦點時觸發 |
---|---|
focus | 在元素獲得焦點時觸發 |
focusin | 在元素即將獲得焦點時觸發 |
focusout | 在元素即將失去焦點時觸發 |
鍵盤焦點事件傳入的是 FocusEvent 物件。
- 鍵盤點選事件
keydown | 在使用者按下某個鍵時觸發 |
---|---|
keypress | 在使用者按下並釋放某個鍵時觸發 |
keyup | 在使用者釋放某個鍵時觸發 |
鍵盤點選事件傳入的是 KeyboardEvent 物件。
jQuery
為什麼使用 jQuery
類似於 JVM 隱藏了不同作業系統之間的差異,讓開發能夠更專注於功能的實現,而不必花費過多時間適配不同作業系統。jQuery 隱藏了不同瀏覽器之間的差異,減少開發者花費在適配不同瀏覽器之間的精力。
舉個例子:float 屬性
原生 js 的話,ie 需要通過 styleFloat 獲取物件修改,W3C 標準為 cssFloat,jQuery 統一封裝成 float,內部會自動根據不同瀏覽器的實現進行處理。
同時,它封裝了很多基本實用的功能,如 ajax,基本動畫等。
API 中文文件
http://www.css88.com/jqapi-1.9/css/
Ajax
$.ajax({
url: "https://easy-mock.com/mock/5b592c01e4e04f38c7a55958/ywb/is/version/checkVersion",
data: {"key": 122},
type: "POST",
success: function (data) {
logUtils(data.content);
var con = JSON.parse(data.content);
callback && callback(con);//通知回撥
},
error: function (e) {
logUtils(e);
}
});
CSS
- 修改 display 樣式
//第一種方式
$("div").css("display", "none");
$("span").css({display:"block", background: "#f2f"});//好用
$("span").css({"display":"block", "background": "#f2f"});//這種也可以
//第2種方式
$("div").each(function () {
this.style.display = "none";
});
$("div")[0].style.display = "none";
//第3種方式
$("div").show();//等效於display:block(inline)
$("div").hide();//等效於display:none
$("div").toggle();//取相反的值
- 讀取樣式
$("div").css("display");
class
- 新增 class
$(selector).addClass("liItem"); //為指定元素新增類className
- 移除 class
$(selector).removeClass("liItem"); //為指定元素移除類 className
$(selector).removeClass(); //不指定引數,表示移除被選中元素的所有類
- 判斷有沒有指定 class
$(selector).hasClass("liItem"); //判斷指定元素是否包含類 className
- 切換 class
$(selector).toggleClass("liItem"); //為指定元素切換類 className,該元素有類則移除,沒有指定類則新增
- 應用場景
當 js 動態修改的樣式較少時,可直接通過 .css() 實現。
當 js 動態修改的樣式比較多時,選擇 class 操作較方便,事件將需要的樣式寫在 css 中,在 js 裡直接新增或移除指定 class 實現。
如果考慮以後維護方便(把 CSS 從 js 中分離出來)的話,推薦使用類的方式來操作。
html
- 建立元素
//類似於js中: document.createElement("標籤名")
var node1 = $("<span>我是一個span元素</span>");//返回的是jQuery物件
- 新增子元素
//方式1:在.main元素的子元素末尾加入新的子元素
$(".main").append(node1);
$(".main").append("<span>我是一個span元素</span>");
//方式2:在.main元素的子元素開頭加入新的子元素
$(".main").prepend("<span>我是第一個span元素</span>");
//方式3:替換掉所有子元素內容
$(".main").html("<span>我把所有子元素都替換掉了</span>");
- 新增兄弟元素
$(".main").after("<span>我是兄弟後span元素</span>");
$(".main").before("<span>我是兄弟前span元素</span>");
- 移除 html
//移除所有子元素
$(".main").html("");
//移除自已,自然子元素也被跟著移除
$(".main").remove();
- 檢視元素內容(包括標籤)
console.log($(".main").html());//下面是元素標籤和打出的日誌
$(".main").prepend("<span>我是第<a>dsfds<span>23543</span></a>一個span元素</span>");
- 檢視元素的純文字內容
console.log($(".main").text());//下面是元素標籤和打出的日誌
$(".main").prepend("<span>我是第<a>dsfds<span>23543</span></a>一個span元素</span>");
text() 會返回當前元素內的所有文字內容,包括子孫後代元素所包裝的文字內容。
- 小結
獲取元素的內容(包括標籤)可用 html()
,建立元素時用 $ ("xxx")
,如果元素只有一個子元素,那麼獲取文字內容時可直接用 text()
,新增子元素時用 append()
。
attr
- 設定屬性
$(selector).attr("title", "生命壹號");
- 獲取屬性
$(selector).attr("title");
- 移除屬性
$(selector).removeAttr("title");
大家好,我是 dasu,歡迎關注我的公眾號(dasuAndroidTv),公眾號中有我的聯絡方式,歡迎有事沒事來嘮嗑一下,如果你覺得本篇內容有幫助到你,可以轉載但記得要關注,要標明原文哦,謝謝支援~