零基礎入門web開發(4)——學習JavaScript

weixin_33859844發表於2017-06-24

簡介

�迄今為止,�使用HTML+CSS構建出的頁面始終缺乏“互動性”,為了能夠實現網頁和你之間的互動,瀏覽器引入了用於操作html內容的指令碼語言——JavaScript(JS),時至今日,JS在web開發界已經發展成為最火最熱的語言,因此你一定不可錯過它

目標

  • 瞭解什麼是指令碼語言,以及指令碼語言和靜態編譯語言(如C++)的區別
  • 瞭解JavaScript並嘗試使用它
  • 瞭解HTML的DOM模型
  • 瞭解事件和回撥函式

任務

  • 使用JavaScript構建具有互動功能的網頁

預期時間

  • 1-2天

有關JS

JS是當今最為火爆的WEB開發語言了,在正式開始講解知識之前我們來扯一點題外話

為什麼要學習JavaScript

  • HTML定義了網頁的內容,CSS描述了網頁的佈局和樣式,JS則定義了網頁的行為,因此為了構建完整的網頁應用,JS是必不可少的。

  • JS是目前瀏覽器上唯一通用的可操作的HTML的語言,換句話說你除了JS沒有第二個選擇。

  • 毫不誇張的說,JavaScript是構建當今web世界的支柱語言,學習JS你可以構建任何類別的應用:網頁,APP,服務端統統可以用一個語言搞定。

但是...

  • JS不是一門嚴謹的語言,有著很多致命的設計缺陷,儘管現在已經得到了一定的改進
  • JS雖然用途十分廣泛,但在除了前端以外的地方略顯吃力
  • JS的語法不嚴謹在提升了它的靈活性的同時也使得極易寫出規範性差,不可控的程式碼,因此雖然上手簡單,但是想要寫出高質量的JS程式碼並不是一件容易的事情

本節課如何講解JS

這節課裡我們不會針對JS做過多深入的講解,主要目的集中在:

  • 瞭解指令碼語言的特性
  • 使用JS構建具有互動性的網頁

如果你想深入學習JS和前端,在後期應用篇(前端)中將會詳細介紹相關的內容,本節課程的末尾處也會給出一些比較新的JS教程(千萬不要學習老版本的JS)供你自學。

瞭解JavaScript和指令碼語言

我們假定學習本課的同學都有一定的程式設計基礎,想必絕大多數人接觸的都是像C,C++以及Java這一類比較傳統的靜態編譯語言。JS則是90年代開始流行的幾大指令碼語言之一,由於指令碼語言和編譯語言存在較大的差別,所以下面的JS基礎教學中將會同時展開說明一下指令碼語言和編譯語言的差別

執行JS

JS是執行在瀏覽器上的語言(儘管現在它已經可以執行在其他環境中了),因此你需要在瀏覽器裡才能執行JS程式碼,我們可以通過html檔案引入JS,主要有以下兩種方式:

1.在html中使用<script>標籤

<script>標籤可以插在<head>或者<body>標籤中,內部的內容就是js程式碼。

例項

<!DOCTYPE html>
<html>
<body>
<h1>我的 Web 頁面</h1>
<p id="demo">一個段落</p>
<button type="button" onclick="myFunction()">嘗試一下</button>
<script>
function myFunction()
{
    document.getElementById("demo").innerHTML="我的第一個 JavaScript 函式";
}
</script>
</body>
</html>

2.外鏈引入

.css檔案一樣,js也可以通過外部來引入,方式是使用<script>標籤的src屬性來引入外部的js檔案

例項

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>JS Demo</title>
    <script src="./4-1.js"></script>
    <!--使用外鏈引入js-->
</head>
<body>
    <button id="b1" onclick="alertB1()">Click Me</button>
</body>
</html>

對於較大的專案一般推薦使用引入外鏈的方式

預備:瞭解JS輸出內容的方式

一個程式要和你互動,至少應該能夠輸出內容(比如C++裡的cout),為了能夠順利進行下面的教學和演示,你至少要先學會讓JS輸出內容給你...

JS基於瀏覽器執行,因此主要藉助瀏覽器來進行輸出

有兩個除錯階段最常用的輸出方式

alert()函式

呼叫alert()函式將會彈出一個視窗並將傳入的引數列印出來。

例項(寫在body中並開啟頁面試試!)

<script>
    alert("Hey You!!");
</script>

alert()可以列印絕大多數的資料型別,包括陣列和物件在內

console.log()函式

這個函式會把接受的變數以及詳細的型別列印到瀏覽器的控制檯中(回顧第一講的瀏覽器開發者工具,選擇它的CONSOLE選項卡就能看到控制檯),此外,控制檯中也會輸出一些有關的輔助資訊(比如警告,錯誤等)。

例項(同樣寫在body中)

<script>
        var obj = {
            name: "mark",
            sex: "male"
        };
        console.log(obj);
</script>

開啟頁面後檢視控制檯,就可以看到結果了

6382481-668d16c2147b528f.jpg

變數的定義與資料型別

指令碼語言中的變數有以下幾個特點:

  • 沒有型別(int,string,char...),任何一個變數都可以儲存任何型別的資料
  • 無需提前宣告就可以直接使用

語法示範:

  • 宣告變數使用var關鍵字,可以儲存任意型別的資料
var myInt = 123; // 整數
var myDecimal = 12.1; // 浮點數
var myStirng = "Hello JS"; // 字串
var myArray = [1,"hello",12.3,{name:"lux"}]; // 陣列(可以存放任意型別,任意數量的值)
var myObject = {name:"lux",sex:"male",age:"18"} // 物件,就是鍵值對
var myFunction = function(){ return "this is a funciton" } // 函式也可以是變數,是不是很神奇
  • 變數可以隨意轉換型別,也可以不用宣告就直接用
var myVar = 123;
myVar = "Hello Var"; // 自由轉換型別

myAnotherVar = 1; // 不用var宣告直接也可以使用變數,不過不推薦

你應該特別留意陣列和物件兩種型別,它們的作用方式和靜態語言存在很大的不同,下面給出較為詳細的教程:

注*:暫時(在本節課中),你不必太深入的瞭解這些資料型別

流程控制

流程控制無非是老生常談的選擇順序迴圈,這一塊JS的語法基本和C/C++一致,因此不過多贅述,點選下面的連結檢視詳細內容:

函式

函式將在JS中被重新定義。JS是一門函數語言程式設計的語言,這意味著函式是“第一等公民”。

最大的特徵有以下幾點:

  • 函式可以當做變數
  • 函式可以當做另一個函式的引數或者返回值

(暫時只列出這麼多,後面會有專門的章節來講解函數語言程式設計)

基本定義

js中的函式一定要用function關鍵字宣告,另外由於變數沒有型別,所以函式也不用指定引數的型別和返回值的型別,一個典型的函式大概長下面這樣:

funciton 函式名(引數1,引數2...) {
    函式程式碼
    return 返回值
}

函式可以沒有名稱,這樣的函式被稱為匿名函式,它可以儲存到變數

用變數儲存函式

演示一個用變數呼叫匿名函式的例子


var addMe = function(var1,var2){
    return var1+var2;
};

var a = 1,b = 2;

console.log(addMe(a,b)); //利用變數來呼叫,輸出為3

將函式當做值來傳遞

最常用的情景是把函式當做引數來傳遞,這樣做可以極大的擴充函式的功能,可以參考下面這個例項

// 定義兩個匿名函式

    var sayHello = function(name) {
        console.log("hello, "+name);
    };

    var sayHi = function(name) {
        console.log("hi, "+name)
    };

    var arr = ['mark','ann','ouxu','molybdenum','ruby'];

    // 一個用於對arr陣列進行操作的函式,第一個引數是要操作的陣列,第二個引數是需要對陣列中的元素所應用的函式

    function operateArr(paramArr,func) {
        for (var i=0;i<5;i++) {
            func(arr[i]);
        }
    }
    
    // 傳入不同的函式來執行

    operateArr(arr,sayHello);

    operateArr(arr,sayHi);

執行的結果如下:

6382481-4134d0f2ad6bf793.jpg

我們把sayHi和sayHello兩個函式稱為回撥函式,這個概念十分有用,我們下面要講的事件機制中大量應用了回撥函式(不過看上去沒有這麼複雜)

有關函式的作用域,以及函數語言程式設計的問題會在後面的篇幅中進一步講解,現在你需要了解的是函式在js中擁有非常高的地位,後面要講到的有關實現互動的內容基本都是靠各種各樣的函式來實現的。

總之,先把函式當成你編寫js程式碼的最小結構塊吧!

程式碼的執行

指令碼語言和編譯語言不同,不需要編譯成可執行的二進位制檔案之後執行,它是解釋執行的。

實際上它工作的原理是由JS執行器讀取JS檔案後,一行一行程式碼的讀取並執行,不會產生任何中間檔案,程式執行的過程,就是由執行器讀取程式碼檔案的過程,脫離了執行器(也叫直譯器或者程式碼引擎)程式碼就和純文字沒有任何區別了。

一個典型的情況是,即便你的指令碼中存在錯誤,只要執行的過程中沒有執行到錯誤所在的地方,它都還能正常執行。

使用JS來和使用者互動

DOM節點

JS是通過HTML的DOM模型來控制HTML內容的,首先我們來了解一下什麼是DOM。

DOM是Document Object Model的縮寫,也就是文件物件模型。HTML的DOM就是整個頁面元素的邏輯結構,包含了元素和元素之間的層級關係,你可以簡單把它理解成一顆元素樹,就像下面這樣:

6382481-60b912d064d78dad.jpg

所有的HTML都可以整理成這樣的一棵DOM節點樹。JS可以對DOM節點進行各種操作:查詢,獲取,修改屬性,內容,響應事件....

在JS中我們通常使用document物件來獲取整個頁面的DOM

JS獲取頁面元素的手段

下面介紹的函式都是document物件提供的方法,你可以像document.getElementById("main")這樣使用。

HTML的內容參考上一節的基礎HTML(3-1.html)

根據id查詢(最有用)

還記得我們上節課中講到的元素的id屬性嗎,它是一個元素的唯一識別符號,用它來獲取元素再合適不過了。

使用getElementById()方法。

你可以使用一個變數來儲存查詢到的DOM節點物件:

var x = document.getElementById("card1");
// 獲取id為card1的dom元素

根據類名(class)來查詢

使用getElementsByClassName()方法,請注意方法名中Element為複數形式,這是因為同一class可能有多個元素,這時候此方法返回的是該class所有的元素的集合

一個簡單的使用示範:請注意如果你是在body中書寫js程式碼,一定要把這段程式碼放在你能獲取的DOM節點後面,否則由於頁面的解析是從上到下的,在你執行程式碼時將無法得到想要的DOM節點。

<body>
    
    <div class="card" id="card1">
        <p>this is card 1</p>
    </div>
    <div class="card" id="card2">
        <p>this is card 2</p>
    </div>

    <script>
       
        var cards = document.getElementsByClassName('card');

        var cardCount = cards.length; // 獲取card類有多少個元素

        for (var i=0;i<cardCount;i++) {
            console.log(cards[i]); // 使用索引就可以取出每一個元素的物件了
        }
    </script>

</body>

根據標籤名來查詢

使用getElementsByTagName()方法,該方法返回的同樣是集合,由於同名標籤在整個頁面中非常多,所以這個方法經常用於巢狀取出某個DOM節點內的指定標籤

檢視下面的示範並注意理解巢狀式的查詢:

var x=document.getElementById("card1"); // x是card1
var y=x.getElementsByTagName("p"); // y是card1裡的p標籤

操作DOM

當你獲取了DOM節點之後,就可以對它做很多事情:讀取、操作DOM的屬性、內容和樣式...

下面會演示一些十分常用的DOM操作

改變HTML內容

你可以使用document.write()直接在script標籤,也就是程式碼執行的位置直接寫入內容:

<body>
    <div>
        <script>
            document.write("<p>這是一段由JavaScript建立的文字</p>");
        </script>
    </div>
</body>

更為常見的做法是,通過上面所述的方法獲取DOM節點後,使用innerHTML屬性來訪問和修改對應節點的內容

<body>
    <h1 id="header">這是老標題內容...</h1>
    <script>
        var header =document.getElementById("header");
        header.innerHTML = "這是新標題內容..."; // 修改h1標籤裡的文字
    </script>
</body>

改變元素的樣式

可以使用DOM物件的style屬性來訪問和修改對應元素的樣式,你可以發現js中DOM物件的屬性和對應html的元素的屬性存在著對應的關係

<body>
    <p id="para1" style="color:red">其實我是藍色文字</p>
    <p id="para2" style="font-size:2px">我的字很大</p>
    <script>
        document.getElementById("para1").style.color = 'blue';
        document.getElementById("para2").style.fontSize = '30px';
    </script>
</body>

事件和回撥函式

現在我們已經可以通過JS控制HTML的各種內容了,但是整個頁面仍然缺乏互動性:所有的指令碼都是預先寫好,在網頁開啟時就自動呼叫了的,有沒有辦法讓使用者在瀏覽網頁的時候主動觸發指令碼並執行呢?

這時候我們需要引入事件程式設計的概念,事件就是在操作頁面過程可能發生的諸多動作,比如:點選一個按鈕,拖動一個元素,將游標移動到某個元素上...你可以把這些事件理解成開關或者觸發器,我們一般會繫結函式到某個事件上,當事件被觸發的時候,該函式就會被自動呼叫,我們也把這種函式成為事件的回撥函式

來看一個經典的例子:通過點選一個按鈕來彈出一個警告框

<body>
    <script>
        function alertSth(){
            alert("你點我幹啥");
        } // 定義回撥函式
    </script>
    <button onclick="alertSth()">點我試試</button>
    <!--通過onclick屬性把alertSth()函式繫結到該按鈕的點選事件上-->
</body>

HTML中存在非常多的事件,不同類別的元素擁有的事件也不盡相同,限於篇幅這裡就不一一展開了,點選下面的連結深入瞭解一下事件機制吧

有了事件的存在,結合之前JS操作DOM節點的強大功能,我們就擁有了構建高可互動性網頁的基石了。

小結

JavaScript是一門神奇的指令碼語言,它十分簡單易學,也十分好玩(在不深入瞭解的前提下),目前IT界正在不斷的修改和完善JavaScript語言,並嘗試統一它的標準。

決定學習JS的同學們,至少應該學習ES6版本的新JS,下面給出兩個大牛寫的JS教程:

JS由於起初設計的不嚴謹,導致了一些非常迷亂的現象(最著名的是那張JS的真值表),你學習的過程中也可能會多多少少遇到一些坑,記得編寫js程式碼時保持態度的嚴謹,可以儘可能的避免一些錯誤的產生。

本節課是前端認知篇的最後一篇,HTML+CSS+JS三者的組合已經足夠你構建任意型別的網頁頁面,下一課中我們將會對這幾節課做一個整理總結,並給出一個挑戰例項供你練習。

相關文章