1. 程式人生 > >JavaScript從入門到精通

JavaScript從入門到精通

目錄
第一課 初探JavaScript魅力-01

JavaScript是什麼

如今我們開啟一個大型的網站,都會有很多JS效果的功能和應用。對於學過CSS+HTML的同學,即使是像淘寶那樣的網站,用一兩天時間也可以將佈局寫出來。但對於一個網頁來說,除去CSS,HTML這樣描述靜態佈局的元素外,還有諸如彈窗,幻燈,編輯等很難用純粹的CSS+HTML實現的功能,而這些都是通過JavaScript來完成。

那麼JavaScript究竟是什麼呢?對比HTML+CSS這兩者只能製作觀看難以互動(雖然可以通過hover偽類進行互動但功能有限)的靜態網頁而言,我們給Javascript進行如下定義:

JavaScript是一門用於給網頁新增功能、互動的指令碼語言。

我們以百度首頁登入框為例,實際上我們開啟百度首頁的時候,登入框就已經包含在了網頁程式碼中。在我們點選登入之前,登入框css的display屬性為none;而當我們點選之後,其display屬性變為了block,從而就顯示了出來——這個過程便是由JS控制的。淘寶的幻燈效果也是同理,我們通過滑鼠移動到不同的元素來改變元素的背景顏色(background-colr)和文字顏色(color)。

這裡寫圖片描述

如上圖126郵箱十天免登陸的提示,當我們將滑鼠移動到框上時,會出現相應的文字提示,當滑鼠移開時,對應的文字提示消失。我們將模仿它寫一個滑鼠提示框。該功能的具體實現是:當滑鼠移入到框上的時候,讓該div顯示,滑鼠移出框的時候,讓該div隱藏。

到這裡,不得不補充一個JS裡非常重要的一個概念:事件。這裡我們以第一個JS事件:onclick事件為例說明。

在html中包含以下程式碼:

<input type="button" value="按鈕" />

這樣會相應生成一個按鈕,但點選無效,因為按鈕本身並沒有任何功能,因此我們要向按鈕增加onclick事件來實現功能。onclick事件所代表的含義是當元素被點選時,該事件實現。

將上方程式碼改為:

<input type="button" value="按鈕" onclick="alert('zcvzxcvzx')"/>

當我們再點選按鈕時,便會啟用onclick事件,彈出彈框。

這裡寫圖片描述

簡單來說,事件就是使用者的操作。使用者操作分為很多,對於按鈕來說有點選,以及我們待會會用到的滑鼠移入,滑鼠移出等等。將來我們會遇到更多的事件,這裡不再贅述,以後慢慢說。

回到我們的第一個JS特效中來。為了實現:滑鼠移入到checkbox的時候,讓div顯示,滑鼠移出checkbox的時候,讓div隱藏這樣的效果,我們引入兩個新的事件:onmouseover和onmouseout。如果你懂英文的話,很容易就明白,前者是指滑鼠移入元素時觸發的事件,後者是滑鼠移開元素時觸發的事件。

現在我們來分析,如何讓滑鼠移入到input的時候,讓div1顯示呢?其實就是當滑鼠移入到input上時,將其display屬性改為block。那麼,這句話應該如何用JS來寫呢?答案是這樣的:

<input type="checkbox" onmouseover="div1.style.display='block';"/>
<div id="div1">
    為了您的資訊保安。。。。
</div>

我們將div1.style.display=’block’這句話拿出來仔細分析。首先,div1是div的id,代表了選擇了該div。其次,.代表的是什麼含義呢?.類似於漢語的“的”,表示所屬關係。等號在JS裡並不是相等的意思,而是賦值(把等號右邊的東西賦給左邊)。所以這句話的意思就是div1的style(樣式)裡的display屬性賦值為block。因此,當我們將滑鼠移動到checkbox上後,便會觸發onmouserover事件,將div1顯示出來。同理,通過onmouseout事件可以在滑鼠離開時將div1隱藏。

完整的程式碼如下:

<html>
  <head>
    <meta charset="utf-8" />
    <title>無標題文件</title>
    <style>
      #div1{
        width:200px;
        height: 100px;
        background: #CCC;
        border: 1px solid #999;
        display: none; 
      }
    </style>
  </head>
  <body>
    <input type="checkbox" onmouseover="div1.style.display='block';" onmouseout="div1.style.display='none';" />
    <div id="div1">
      為了您的資訊保安。。。。
    </div>
  </body>
</html>

實現的效果如下:

這裡寫圖片描述

不相容問題

我們已經學會了寫一個最簡單的JS小程式,但它存在一些小問題。在chrome和IE瀏覽器下,它能很好地執行,但如果使用火狐瀏覽器,你會驚訝的發現程式沒有反應。在錯誤控制檯中我們可以看到,錯誤提示為“div1 is not defined”,即div1沒有被定義。

你或許會覺得奇怪,為什麼說div1沒有被定義呢?原因是在JS裡,直接使用ID進行元素選擇是不相容的(火狐或者低版本的chrome),我們應該採用更加相容的寫法:document.getElementById()

因此我們可以將上面的程式碼進行改寫:

<input type="checkbox" onmouseover="getElementById('div1').style.display='block';" onmouseout="getElementById('div1').style.display='none';" />

getElementById的意思是通過id來獲取元素,在本例中即通過getElementById獲取了div1的元素來使用,這樣在任何瀏覽器下都不會產生相容性問題了。

初識函式

提起函式大家想到的應該首先是數學裡的函式,不過JS裡的函式和數學函式的關係並不是很大。我們用一個簡單的小東西來闡述什麼是JS裡的函式。

現在我們向網頁新增一個框,其寬為200px,高也為200px,背景為紅色。同時我們希望當我們的滑鼠移動到框上時,其寬高變為300px,背景變為綠色。利用我們前面所學到的知識我們可以解決這個問題,程式碼如下:

<html>
  <head>
    <meta charset="utf-8" />
    <title>
無標題文件
    </title>
    <style>
      #div1{
        width:200px;
        height: 200px;
        background: red;
      }9
    </style>
  </head>
  <body>
    <div id="div1" onmouseover="document.getElementById('div1').style.width='300px';document.getElementById('div1').style.height='300px';document.getElementById('div1').style.background='green';"onmouseout="document.getElementById('div1').style.width='200px';document.getElementById('div1').style.height='200px';document.getElementById('div1').style.background='red';">
    </div>
  </body>
</html>

實現的效果如下:

這裡寫圖片描述

顯而易見的是,雖然完成了功能,但這樣的程式碼無論編寫還是檢視都太噁心了。還記得,我們寫css很少把這麼多的樣式寫在行間而是選擇寫在樣式表裡,JS也同樣,通常可以通過函式的方式將程式碼簡潔化。

JS的函式的最基本格式為:function+函式名+(){},()內為引數(可以不寫,暫時不用管),{}內為函式體。

因此,我們通過函式將上方的程式碼進行改造:

<html>
  <head>
    <meta charset="utf-8">
    <title>無標題文件</title>
    <style>
      #div1 {
        width:200px;
        height:200px;
        background:red;
      }
    </style>
    <script>
      function toGreen()
      {   
        document.getElementById('div1').style.width='300px';
        document.getElementById('div1').style.height='300px';
        document.getElementById('div1').style.background='green';
      }
      function toRed()
      {
        document.getElementById('div1').style.width='200px';
        document.getElementById('div1').style.height='200px';
        document.getElementById('div1').style.background='red';
      }
    </script>
  </head>
  <body>
    <div id="div1" onmouseover="toGreen()" onmouseout="toRed()">
    </div>
  </body>
</html>

將函式寫在script標籤中,然後將行內的程式碼寫在函式裡,行內只使用函式名呼叫函式,這樣比之前顯得更簡潔。

此外,在寫css的時候,我們普遍有一個小小的習慣叫重用,即相同的程式碼儘可能只寫一次。在JS裡,同樣應當遵循這樣的規則。在上面的例子中,document.getElementById(‘div1’)這一段被重複使用了多次,我們可以通過引入一個新的概念:變數將他們進行合併。

第一課 初探JavaScript魅力-02

變數

說起變數,我們不得不提起我們有一部比較古老的電視劇叫《包青天》。包青天有一把非常厲害的寶劍叫“尚方寶劍”,見到尚方寶劍有如見到皇帝。某種程度來說,變數具有類似於尚方寶劍的特性。

我們對第一課末的程式碼進行如下修改:

function toGreen()
{   
  var oDiv=document.getElementById('div1');    //變數
  oDiv.style.width='300px';
  oDiv.style.height='300px';
  oDiv.style.background='green';
}

我們用var對變數進行定義,告訴計算機我接下來要寫的是一個變數,oDiv是變數的名字,我們用oDiv這個變數把document.getElementById(‘div1’)的值存起來(我們可以簡單理解為變數是給一個東西取了個別名),那麼在這個函式裡凡是見到Div的地方便如同見到document.getElementById(‘div1’),就像尚方寶劍一樣。這樣的程式在功能上沒有發生變化,但程式碼卻大幅度進行了簡化。

函式的定義與呼叫

定義和呼叫是函式的兩個重要概念。 我們來看這麼一段簡單的JS程式碼:

function show()       
{                        //定義
    alert("abc");
}
show();            //呼叫

如果一個函式只有定義,而沒呼叫,無論如何重新整理頁面,也沒有任何效果。就像法律雖然存在,但如果沒有人犯法,法律便如同不存在一樣。而如果一個函式只有呼叫而沒有定義,那麼函式也無法執行,並且控制檯會出現函式沒有被定義的報錯。因此,想讓函式執行,函式的定義和呼叫缺一不可。

網頁換膚

很多網站都擁有網頁換膚這樣類似的方便功能,可以通過點選改變網頁的背景顏色或圖片等。

這裡寫圖片描述

上圖為hao123的網頁換膚功能,在點選換膚後整個網頁所有元素的背景顏色都發生了改變。如果採用上節課的方式,我們可能需要一個一個修改元素的背景顏色,操作量非常大,因此我們有更簡單的方法來完成這件事。

本例通過外鏈樣式表來新增css,在外鏈樣式表中準備兩套不同的面板(即兩個不同的css檔案)提供網頁變化。

css1的程式碼如下:

body{
  background:black;
}
input{
  width:200px;
  height:100px;
  background:yellow;
}

css2的程式碼如下:

body{
  background:#ccc;
}
input{
  width:100px;
  height:50px;
  background:red;
}

在HTML程式碼中,我們通過更改link的href屬性便可以載入不同的css檔案,所以其實換膚本質上就是更改外鏈的css檔案。為了達成這個目的,我們需要操作HTML裡的link標籤。同時為了選中link標籤,我們需要給link標籤加上id並在js函式裡用getElementById方法選中,這樣就可以對其href屬性進行操作了。

完整程式碼如下:

<html>
  <head>
    <meta charset="utf-8">
    <title>無標題文件</title>
    <link id="l1" rel="stylesheet" type="text/css" href="css1.css" />
    <script>
      function skin1()
      {
          var oL=document.getElementById('l1');
          oL.href='css1.css';
      }

      function skin2()
      {
          var oL=document.getElementById('l1');
          oL.href='css2.css';
      }
    </script>
  </head>
  <body>
    <input type="button" value="面板1" onclick="skin1()" />
    <input type="button" value="面板2" onclick="skin2()" />
  </body>
</html>

點選面板1和面板2就可以對網頁進行換膚啦。

這裡寫圖片描述

從這個例子裡,我們學到以下幾點:

  • 任何標籤都可以加id,例如本例的link可以,甚至連body,html也可以。
  • 任何標籤的任何屬性都可以通過JS進行修改。
  • HTML裡的屬性名和JS裡保持一致,HTML裡面怎麼寫,VALUE裡面就怎麼寫。

if判斷
if語句在JS裡用於判斷,其基本格式為

if(條件){
  語句1
}
else{
  語句2
}

其中else不是必要的。整個語句代表的含義為,如果條件成立,則執行語句1,如果條件不成立,則執行語句2。舉一個生活中最簡單的小例子,如果天氣預報有雨,我們則帶傘,如果不下雨,則不帶傘。這個例子用if語句的話描述如下:

if(預報有雨){
  帶傘
}
else{
  不帶傘
}

那麼if語句在JavaScript裡面應該怎麼應用呢?我們再舉一個網頁的小例子。

這裡寫圖片描述

Google上方選單欄的“更多”選項,當我們點選的時候,會展開一個選單欄,再次點選的時候會收回。這個非常常用的功能就是用if語句完成的。和onmouseout和onmouseover不同,雖然我們每次進行的都是點選操作,但根據選單欄展開狀態的不同,每次點選產生的效果也就不一樣。當選單欄處於顯示狀態的時候,進行點選的操作是讓選單欄隱藏;反之,當選單欄處於隱藏狀態時,進行點選的操作是讓選單欄顯示。用一句簡單的話來描述我們需要乾的事情就是:當點選的時候,如果div是顯示的,將其隱藏掉(將其display屬性改為none);反之,將其顯示出來(將其display屬性改為block)。

因此,我們可以用if語句進行表達:

if(div是顯示的){
  oDiv.style.display='none';
}
else{
  oDiv.style.display='block';  
}

完整程式碼如下:

<html>
  <head>
  <meta charset="utf-8">
  <title>無標題文件</title>
  <style>
#div1 {width:100px; height:200px; background:#CCC; display:none;}
  </style>
  <script>
    function showHide()
    {
      var oDiv=document.getElementById('div1');

      if(oDiv.style.display=='block')
      {
        oDiv.style.display='none';
      }
      else
      {
        oDiv.style.display='block';
      }
    }
  </script>
</head>

  <body>
    <input type="button" value="顯示隱藏" onclick="showHide()" />
    <div id="div1">
    </div>
  </body>
</html>

效果如下:

這裡寫圖片描述

這裡出現了一個新的符號,==(雙等號)。我們之前講過,在JS裡=代表賦值(改變),而雙等號則更接近於數學中的等號,其作用是判斷兩邊是否相等。在本例中,oDiv.style.display==’block’即代表對display的值是否為block進行判斷,如果成立則代表div1是顯示的狀態,執行if語句將其隱藏;反之不成立則代表div1是隱藏狀態,執行else語句將其顯示。

為a連結新增JS

HTML中的a連結大家應該再熟悉不過了,但是大家知道,a連結也是可以新增JS的嗎?通常情況下,我們在a標籤的href屬性裡放的值是網址,不過實際上也可以在裡面放入JS函式執行。

<a href="javascript:alert('a');">連結</a>

使用上述程式碼,點選連結同樣可以執行JS函式。冒號前的javascript可以告訴瀏覽器,我們要執行的不是網址而是JS程式碼,冒號後的則是執行內容。

這裡寫圖片描述

不過,一般來講,我們都不會真的在a標籤裡放JS程式碼,而是讓它空著:

<a href="javascript:;">連結</a>

這樣做的目的有兩個。首先,在a標籤裡面放程式碼非常不好,這一點我們學到事件的時候就會明白。其次,這種寫法比起在href屬性中使用#有一個優勢:點選後沒有反應,不會直接跳到網頁的頂部。

例外的className

在網頁換膚的時候我們講過,HTML裡的屬性名和JS裡保持一致,HTML裡面怎麼寫,VALUE裡面就怎麼寫——唯一的例外就是className。因為JS裡的class是保留字,在JS裡有其他作用,如果我們在JS裡直接使用HTML裡的class屬性,程式是不會執行的,所以JS用className代替了class。當我們想改變一個元素的class時,採用以下寫法:

<html>
  <head>
    <meta charset="utf-8">
    <title>無標題文件</title>
    <style>
      #div1 {
        width:100px;
        height:100px; border:
        1px solid black;
      }
      .box {
        background:red;
      }
    </style>
    <script>
      function toRed()
      {
        var oDiv=document.getElementById('div1');
        oDiv.className='box'; //className,而不是class
      }
    </script>
  </head>

  <body>
    <input type="button" value="變紅" onclick="toRed()" />
    <div id="div1">
    </div>
  </body>
</html>
函式傳參

上節課的時候我們已經講了什麼是函式,實際上,函式在功能上就類似於css的class一樣,將一段程式碼包裹起來使用。為了讓函式的功能更加的豐富和實用,我們需要用到的就是函式傳參。我們已經提過,JS將引數放在函式名後的圓括號內,而為了具體說明引數怎麼使用,我們舉一個小例子。
我們在HTML頁面中放入一個有顏色的div塊,並加入3個按鈕,其目的是通過點選按鈕來改變div塊的顏色。通過前面兩節課的學習,我們可以很輕鬆地寫出下面的程式碼來實現這個功能:

<html>
  <head>
    <meta charset="utf-8">
    <title>無標題文件</title>
    <style>
      #div1{
        width:200px;
        height:200px;
        background:red;
      }
    </style>
    <script>
      function toGreen()
      {
        var oDiv=document.getElementById('div1');
        oDiv.style.background='green';
      }

      function toYellow()
      {
        var oDiv=document.getElementById('div1');
        oDiv.style.background='yellow';
      }

      function toBlack()
      {
        var oDiv=document.getElementById('div1');
        oDiv.style.background='black';
      }
    </script>
  </head>
  <body>
    <input type="button" value="變綠" onclick="toGreen();" />
    <input type="button" value="變黃" onclick="toYellow();" />
    <input type="button" value="變黑" onclick="toBlack();" />
    <div id="div1">
    </div>
  </body>
</html>  

效果如下:

這裡寫圖片描述

可以看到,為了實現這一功能我們一共寫了三個函式,作用分別是讓div塊變綠、變黃、變紅。這三個函式的結構幾乎一模一樣:通過getElementById獲取到div1並賦值給oDiv,然後修改其background屬性,唯一的區別是具體的顏色值不同。所以,有沒有辦法將這三個函式進行合併呢?自然是有的,方法就是我們這節課要講的函式傳參。
這裡,我們先將前面講函式的定義和呼叫那個例子拿過來。

function show()       
{                       //定義
  alert("a");
}
show();            //呼叫

執行網頁後會固定彈出內容為“a”的視窗。這樣的功能是不是太簡單了?如果我希望它彈出的內容是我給定的內容應該怎麼做?答案便是使用引數。
引數的使用方法其實很簡單,在這個例子裡,我們在函式的()放入一個num,這個num類似於前面講的變數,名字由編寫者自定,並且函式定義的時候num自身的值是未知的。如何確定num的值呢?在呼叫函式的時候,在()內輸入的值便是num的具體值。示例如下:

function show(num)       
{               
  alert(num);
}
show(12);   

結果如下:

這裡寫圖片描述

執行程式後,彈出來的視窗值變為了12。我們修改show()裡的值,執行結果也會發生相應的變化。於是,我們就可以稱num為函式show()的引數。這個例子我們可以看出,函式引數扮演的是佔位符的角色,在定義的時候引數僅僅是佔據一個位置而沒有具體的值,其值在函式呼叫時才被傳入。
值得注意的是,對於一個函式來說,它的引數是可以有很多個的,傳入多個引數時,我們用逗號將引數隔開:

function show(a,b)       
{               
  alert(a+b);
}
show(5,12);  

結果如下:

這裡寫圖片描述

需要注意傳入的值要和引數一一對應(a=5,b=12)。
現在我們就通過傳參的方法將前面的程式碼進行合併。我們寫一個統一的函式setColor,並傳入一個color引數(用於決定將div修改為什麼顏色),保留前面三個函式的主體部分,只將顏色具體的值修改為color,color具體的值則在button裡呼叫setColor函式時再決定。 修改後的程式碼如下:

<html>
  <head>
    <meta charset="utf-8">
    <title>無標題文件</title>
    <style>
      #div1{
        width:200px;
        height:200px;
        background:red;
      }
    </style>
    <script>
      function setColor(color){
        var oDiv=document.getElementById('div1');
        oDiv.style.background=color;
      }
    </script>
  </head>
  <body>
    <input type="button" value="變綠" onclick="setColor('green');" />
    <input type="button" value="變黃" onclick="setColor('yellow');" />
    <input type="button" value="變黑" onclick="setColor('black');" />
    <div id="div1">
    </div>
  </body>
</html>

傳參的具體內容就是這些,但關於傳參,很多初學者都會有這樣的疑惑:我們如何判斷一個函式是否應該使用引數傳遞呢?一個比較簡單的判斷方法是,當我們的函式如果存在一部分內容在定義時無法確定下來,就有使用引數傳遞的必要。

改變Div的任意樣式

剛才的程式裡的函式setColor,其作用只能修改div的背景顏色。假設我們想通過一個函式,來改變一個div的各種樣式,例如寬,高,邊框等,又應該如何對我們的函式進行修改呢?
很明顯,想修改Div的任意樣式,有兩處是無法確定的,一個是具體的樣式名(name),一個是具體樣式的值(value),因此我們需要兩個引數。如果按照我們前面所講,那麼JS函式的寫法應該如下:

functionsetStyle(name,value)
{
  var oDiv=document.getElementById('div1');
  oDiv.style.name=value;
}

實際上,嘗試一下就會發現,這個函式是無法正常執行的。原因出在這種寫法下,瀏覽器並不會認為oDiv.style.name中的name和引數中的name是同一個東西,而會認為這是一個叫“name”的樣式,當然css中並沒有名為“name”的樣式,因此無法執行。
為了解決這個問題,我們必須瞭解第二種操作屬性方法。第一種操作屬性的方法就是我們已經學過的使用.字元連線,我們之前所有案例都是通過這種方法來操作屬性。而第二種操作屬性的方法,是通過[‘屬性名’]的方法來進行操作。具體的使用方法如下:

function setText()
{
  var oTxt=document.getElementById.('txt1');
  //第一種操作屬性的方法
  oTxt.value='dsfasdfasdf';
  //第二種操作屬性的方法
  oTxt['value']='dsfasdfasdf';
}

在這個小例子中,二者不存在任何區別。在平常的書寫中,由於第一種比第二種更為簡便,因此大多選用第一種寫法。而第二種寫法的好處是,[]內放置的是一個字串(關於字串的具體內容本課末會講),而字串可以通過變數來儲存,也可以通過引數傳遞具體的值。因此,前一個案例裡想通過引數改變樣式名的目的便可以通過這種方法達成。 實現程式碼如下:

<html>
  <head>
    <meta charset="utf-8">
    <title>無標題文件</title>
    <style>
      #div1{
        width:200px;
        height:200px;
        background:red;
      }
    </style>
    <script>
      function setStyle(name, value)
      {
        var oDiv=document.getElementById('div1');
        oDiv.style[name]=value;
      }
    </script>
  </head>
  <body>
    <input type="button" value="變寬" onclick="setStyle('width', '400px')" />
    <input type="button" value="變高" onclick="setStyle('height', '400px')" />
    <input type="button" value="變綠" onclick="setStyle('background', 'green')" />
    <div id="div1">
    </div>
  </body>
</html>  

效果如下:

這裡寫圖片描述

這樣,無論想改變div的什麼屬性,都可以通過傳遞引數來實現了。
順便一提,在JS裡,任何使用.字元的地方,都可以用[]代替,例如document.getElementById(‘div1’)可以修改為document[‘getElementById’](‘div1’),oDiv.style.[name]可以修改為oDiv[‘style’][name],具體如何使用視實際情況而定。

字串和變數——區別和關係

觀察前面的程式碼,可以看到有很多使用”“和”的地方,在JS裡使用引號標註的就是字串。變數和字串之間有什麼關聯或者區別呢?
說到這裡,再提及JS裡面一個與變數相對的概念:字面量(常量)。對於字面量來說,其值是固定的,我們可以清楚地知道它是多少。數字,字串都是字面量。相對來說,變數的具體值則是不確定的,如果單獨看變數本身我們是無法確定其值為多少的。
對於變數和引數來說,使用它們是不需要加引號的,而字串則必須加上引號。 對於下面一個例子:
alert(abc);
我們的本意是想將abc輸出,但由於沒有加引號,瀏覽器會認為abc是一個變數,又由於abc沒有被定義過值,所以會出現abc沒有被定義的報錯。字串和變數在我們以後的課程中會不斷地應用到,大家慢慢就會熟悉他們之間的關係和區別。