JavaScript 語法 流程控制 Function (函數) Object (物件) 數值 布林值 字串 陣列 時間和日期 Math 物件
正規表示式 瀏覽器物件模型 BOM JS DOM HTML DOM CSS樣式 & Event

JavaScript DOM CSS (修改 CSS 樣式) & Event (事件處理)

網頁承現內容如下 :

hello world

Thank you
代碼:
<p id="f-1" style="margin: 0"> hello world </p>
<b id="f-2"> Thank you </b>
<script>
  function show_a() {
    var f_a = document.getElementById('f-1');
    f_a.style.color = 'red'; }
  function show_b() {
    document.getElementById('f-2').style.background ='#bbb'; }
  function show_c() {
    var f_c = document.getElementById('f-2');
    f_c.style.cssText = 'font-size: 20px; color: purple;'; }
  function show_a2() {
    var f_a = document.getElementById('f-1');
    f_a.innerHTML = "Welcome ! 映美集"; }
</script>
常用 CSS 屬性 將另開新視窗,列表說明

將 <p id="f-1"> 的字體顏色改成紅色 // onClick事件

將 <b id="f-2"> 的背景顏色改成灰色

將 <b> 的字體大小設為 20px、字體顏色設為紫色

將 <p> 的文字內容改為 'Welcome ! 映美集'


JavaScript DOM CSS (修改 CSS 樣式)

可以透過DOM API來操作HTML元素的CSS樣式(style)。

Element.style.cssProperty = newStyle

DOM 的 style 屬性 (對應到 HTML 元素的 style 屬性) 可以用來直接設定一個元素的樣式,
其中 cssProperty 是 HTML 元素的 CSS 屬性名稱,newStyle 則是該 CSS 屬性的值。 例如: document.getElementById('xxx').style.color= 'green';
例如:
<p id="foo"> hello world </p>
<script>
  var foo = document.getElementById('foo');  // 取得目前頁面上的 foo元素
  foo.style.color = 'green';                 // 將 <p> 的文字字體顏色改成綠色
  foo.style.background = 'gray';             // 將 <p> 的背景顏色改成灰色
</script>
如果 CSS 屬性名稱中有 - (例如 background-color),你可以用 [] 的語法,
或將屬性名稱改用駝峰式 (camel case) 的寫法:
   foo.style['background-color'] = '#f00';   // 將背景顏色改為紅色
   foo.style.marginTop = '100px';            // 將 margin-top 設為 100px

Element.style.cssText = newCSS

cssText 可以用來直接讀寫 HTML 元素的 style 屬性。
用法:
<p id="foo"> hello world </p>
<script>
  var foo = document.getElementById('foo');
  alert(foo.style.cssText);                   // 輸出 "" 空字串,因為 foo 上沒有設定 style 屬性
  foo.style.cssText = 'font-size: 20px; color: purple;';  // 將 foo 的字體大小設為 20px、字體顏色設為紫色
  alert(foo.style.cssText);                   // 輸出 font-size: 20px; color: purple;
</script>

window.getComputedStyle(element)

window.getComputedStyle 方法用來取得一個 HTML 元素目前所有的 CSS 樣式值。
那為什麼不用 DOM 的 style 屬性?因為光是 HTML 元素的 style 屬性還無法決定一個元素最終的 CSS 樣式,
還需要知道頁面中 <style> 標籤裡寫的樣式,再加上外部 CSS 樣式表 (style sheets) 裡的內容,才能得到一個元素最終的樣式,
window.getComputedStyle 即用來取得元素最終的樣式值。
用 window.getComputedStyle 方法取得某元素當前所有的 CSS 樣式值後,接著再用返回物件的 getPropertyValue 方法來取得個別的 CSS 屬性值。
語法:
var style = window.getComputedStyle(element, pseudoElement);
參數 element表示一個HTML DOM元素;pseudoElement是一個選擇性參數,用來指定 pseudo-element。
window.getComputedStyle === document.defaultView.getComputedStyle 兩個都指向同一個方法。
範例:
<style>
#elem {
    position: absolute;
    left: 100px;
    top: 200px;
    height: 100px; }
</style>

<div id="elem" style="top:50px;"> hello world </div>
<script>
  var elemA = document.getElementById('elem');
  alert(window.getComputedStyle(elemA).getPropertyValue('height'));   //顯示 100px
  alert(window.getComputedStyle(elemA).getPropertyValue('top'));      //顯示 50px

pseudo-element 的例子:
<style>
h3::after {
    content: ' rocks!';
  }
</style>

<h3> hello world </h3>
<script>
  var h3B = document.querySelector('h3');
  alert(getComputedStyle(h3B, ':after').content);   //顯示 " rocks!"
</script>

Element.currentStyle.cssProperty

在IE9以下可用Element.currentStyle屬性來取得元素目前的CSS樣式,這是一個IE專有(proprietary)的屬性。
語法:
Element.currentStyle.cssProperty
其中 cssProperty 是 HTML 元素的 CSS 屬性名稱,採駝峰式 (camel case) 的寫法。
用法:
<style>
#elem {
    position: absolute;
    left: 100px;
    top: 200px;
    height: 100px; }
</style>

<div id="elem" style="top:50px;"> hello world </div>
<script>
  var elemC = document.getElementById('elem');
  alert(elemC.currentStyle.height);      //顯示 100px
  alert(elemC.currentStyle.top);         //顯示 50px
</script>

JavaScript DOM Event (事件處理)

使用者在瀏覽網頁時會觸發很多事件 (events) 的發生,例如按下滑鼠是一種事件、按下鍵盤按鍵是一種事件、網頁或圖片完成下載時是一種事件、表單欄位值被改變是一種事件..等等。
DOM Event 定義很多種事件型態,讓你可以用 JavaScript 來監聽 (listen) 和處理 (event handling) 這些事件。
事件名稱 觸發條件
blur blur 物件失去焦點時
change 物件內容改變時
click 滑鼠點擊物件時
dblclick 滑鼠連點二下物件時
error 當圖片或文件下載產生錯誤時
focus 當物件被點擊或取得焦點時
keydown 按下鍵盤按鍵時
keypress 按下並放開鍵盤按鍵後
keyup 按下並放開鍵盤按鍵時
load 網頁或圖片完成下載時
mousedown 按下滑鼠按鍵時
mousemove 介於over跟out間的滑鼠移動行為
mouseout 滑鼠離開某物件四周時
mouseover 滑鼠進入一個元素 (包含進入該元素中的子元素) 四周時
mouseup 放開滑鼠按鍵時
resize 當視窗或框架大小被改變時
scroll 當捲軸被拉動時
select 當文字被選取時
submit 當按下送出按紐時
beforeunload 當使用者關閉 (或離開) 網頁之前
unload 當使用者關閉 (或離開) 網頁之後

DOM Level 0 - HTML Inline Attribute     「on + 事件名稱」

可以在 HTML 的事件相關屬性上綁定事件處理函式,
屬性的名稱是「on + 事件名稱」,屬性值則是任何的 JavaScript。
範例:
<html>
<head>
  <title>inline event handling example</title>
</head>
<body>
  <button onclick="triggerAlert();"> click me </button>       // 按下button按鈕,會引發 triggerAlert()事件。

 <script>
   function triggerAlert() {
      alert('Hey');                                      // 當使用者點下button按鈕會跳出 "Hey"。
   }
 </script>
</body>
</html>

this

你可以在 inline 的 function 傳入 this 當參數,表示 DOM 元素物件本身:
<html>
<head>
  <title>inline event handling example</title>
</head>
<body>
  <button onclick="triggerAlert(this);" data-name="Mike"> click me </button> // 單點button按鈕,會引發 triggerAlert()事件。
                                                                             // 傳入 this(代表此元素物件本身) 當參數
 <script>
   function triggerAlert(ele) {
      alert('Hey ' + ele.getAttribute('data-name'));                        // 當使用者點下button按鈕會跳出 "Hey Mike"。
   }
 </script>
</body>
</html>

DOM Level 0 - DOM Object Property     「on + 事件名稱」

DOM 元素 API 也有對應的屬性,可以用來綁定事件處理函式。
上面的例子可以改寫成:
<html>
<head>
  <title>traditional event handling example</title>
</head>
<body>
  <button id="foo"> click me </button>                    // 按下button按鈕,會引發 triggerAlert()事件。

 <script>
   function triggerAlert() {
      alert('Hey');                                      // 當使用者點下button按鈕會跳出 "Hey"。
   }
   var ele = document.getElementById('foo');
   ele.onclick = triggerAlert;                  // 當使用者按下 (id="foo")按鈕時,執行 triggerAlert 函數
  </script>
</body>
</html>
如果要取消綁定事件處理函數,將事件屬性值設為 null 就可以了:
ele.onclick = null;

DOM Level 2 - Element.addEventListener(eventType, listener)

addEventListener 方法可以用來綁定元素的事件處理函數,第一個參數 eventType 是事件名稱,第二個參數 listener 是事件處理函數。
例子:
<html>
<head>
  <title> addEventListener example </title>
</head>
<body>
 <script>
   function myAlert() {
      alert('Hey!');                                     
   }
   document.addEventListener('click', myAlert);                  // 當使用者用滑鼠點擊頁面時,執行 myAlert 函數
   window.addEventListener('load', function() {                  // 當網頁載入時,執行這個 callback 函數
     alert('頁面已載入!');
   });
  </script>
</body>
</html>
addEventListener 相較於 DOM Level 0 的方法是它可以對一個元素同時指定多個事件處理函數:
<html>
<head>
  <title> addEventListener example </title>
</head>
<body>
 <script>
   function myAlert1() {
      alert('Hey!');                                     
   }
   function myAlert2() {
      alert('Hello!');                                     
   }
   document.addEventListener('click', myAlert1);             // 當使用者用滑鼠點擊頁面時,執行 myAlert1 函數
   document.addEventListener('click', myAlert2);             // 當使用者用滑鼠點擊頁面時,執行 myAlert2 函數
  </script>
</body>
</html>
在上面的例子中點擊頁面 依序 會跳出 "Hey!" "Hello!"。
但要特別注意的是依不同瀏覽器的實作,執行順序可能不會等於事件處理函數指定的順序。

DOM Level 2 - Element.removeEventListener(eventType, listener)

removeEventListener 原來取消透過 addEventListener 綁定的事件處理函數,第一個參數 eventType 是事件名稱,第二個參數 listener 是先前綁定的事件處理函數。
用法:
<html>
<head>
  <title> removeEventListener example </title>
</head>
<body>
 <button id="foo"> click me </button>
 
 <script>
   function myAlert() {
      alert('Hey!');                                     
   }
   var ele = document.getElementById('foo');
   ele.addEventListener('click', myAlert);                  // 綁定 click 事件處理函數
   ele.removeEventListener('click', myAlert);               // 移除剛綁定的 click 事件處理函數
  </script>
</body>
</html>

Event Bubbling (事件氣泡) VS Event Capturing (事件捕捉)

DOM 中的事件有傳播 (event flow) 的概念,當 DOM 事件發生時,事件會先由外到內 (capturing phase)、再由內到外 (bubbling phase) 的順序來傳播。
什麼意思?例如我們看這一個 HTML DOM 結構:
<html>
<head>
  <title> event flow example </title>
</head>
<body>
  <div>
      <ul>
         <li></li>
      </ul>
  </div>
</body>
</html>
當使用者點擊 li 元素時,事件觸發的順序是:
Capturing 捕捉階段:document -> <html> -> <body> -> <div> -> <ul> -> <li>
Bubbling 氣泡階段:<li> -> <ul> -> <div> -> <body> -> <html> -> document
DOM 中的元素會按照上面的順序依序地觸發其 click 事件。
在 addEventListener 和 removeEventListener 方法中,有第三個參數布林值 useCapture 用來指定事件處理函數是要在 Capturing 階段或 Bubbling 階段被執行,false (預設) 表示 Bubbling,true 表示 Capturing。


Event Object

當事件處理函數被執行時,會傳入一個參數代表 event object。
例如:
  element.onclick = function(event) {
      // ...
  };

  // 或是
  element.addEventListener('click', function(event) {
      // ...
  });
在 IE9 以下的 DOM Level 0 或 attachEvent 方法不會傳入 event object,但有一個 global 的 window.event object 可以用來代替,
所以跨瀏覽器 (cross-browser) 的寫法可以改成:
  element.onclick = function(event) {
    event = event || window.event;
      // ...
  };
Event Object 有幾個常用的屬性 (property):
屬性 說明
type 返回事件類型,例如 "click"
target 指向觸發事件的 DOM element
currentTarget 在 event bubbling 階段中,指向目前執行的事件處理函數是綁定在哪個 DOM element 上
timeStamp 事件發生時的時間 timestamp (單位是 milliseconds 毫秒)
eventPhase 返回為一個數字,表示事件處於目前所處的傳播狀態 (event flow),有這些值:
0: None
1: capturing phase
2: target phase
3: bubbling phase

當 MouseEvent (滑鼠事件) 發生時,Event Object 有幾個常用的屬性:
屬性 說明
which 當按下滑鼠按鍵,取得是哪個按鍵,可能的值有:
0: 非按鍵
1: 左鍵
2: 中鍵或滾輪
3: 右鍵
relatedTarget 指向參與事件的相關 DOM element。用在 mouseover 事件,表示剛離開的那個 DOM element;
用在 mouseout 事件,表示剛進入的那個 DOM element
pageX 當按下滑鼠時 (或觸控螢幕時),取得距離頁面 (document) 最左上角的水平距離 (單位 pixel)
pageY 當按下滑鼠時 (或觸控螢幕時),取得距離頁面 (document) 最左上角的垂直距離 (單位 pixel)

當 KeyboardEvent (鍵盤事件) 發生時,Event Object 有幾個常用的屬性:
屬性 說明
keyCode 當 keypress 事件時,返回 character code;當 keydown 或 keyup 事件時,返回 key code
which 值同 keyCode
charCode 當 keypress 事件時,返回 character code
altKey 布林值 (boolean),用來判斷使用者是否有按 alt 鍵
ctrlKey 布林值 (boolean),用來判斷使用者是否有按 ctrl 鍵
metaKey 布林值 (boolean),用來判斷使用者是否有按 meta 鍵
shiftKey 布林值 (boolean),用來判斷使用者是否有按 shift 鍵
   KeyboardEvent 像是 keypress, keydown 和 keyup 事件。
   Character codes 是一個代表 ASCII character 的數字;Key codes 則是一個數字,代表鍵盤上的某個按鍵。
      請參閱 ASCII character 對照表。 Key codes 對照表。

event.stopPropagation()

了解事件傳播的概念後,你可能會想到,那我怎麼不要讓事件傳播下去?答案就是使用 event object 的 stopPropagation 方法。
例如:
element.addEventListener('click', function(event) {
    event.stopPropagation();
    // ...
});
IE 在 IE9 開始才有支援 stopPropagation。
在 IE9 以下你可以使用 IE 專有的 cancelBubble 屬性 event.cancelBubble = true;。

event.preventDefault()

event object 有一個 preventDefault 方法用來取消瀏覽器預設的行為。
瀏覽器預設行為舉例來說像是:
點擊一個超連結後,會載入新的頁面, 在表單輸入欄位中輸入 enter 會送出表單
例如:
element.addEventListener('click', function(event) {
    event.preventDefault();
    // ...
});
IE 在 IE9 開始才有支援 preventDefault。
在 IE9 以下你可以使用 IE 專有的 returnValue 屬性 event.returnValue = false;。

常見的事件處理範例 (Examples)

onclick event

當使用者用滑鼠點擊螢幕 (或用手點擊觸控螢幕) 時
document.body.addEventListener('click', function(event) {
    event.target.style.color = 'yellow';                   // 把字體改成黃色
});

onkeydown event

當使用者在網頁中按下鍵盤按鍵時
document.onkeydown = function(event) {
    if (event.keyCode === 89 && event.ctrlKey) {
        alert('你同時按下 "control + y"'); 
    } else if (event.which === 90 && event.ctrlKey ){
        alert('你同時按下 "control + z"'); 
    }
};

onbeforeunload event

當使用者要離開或關閉目前頁面時
window.onbeforeunload = function(event) {
    return '你確定要離開本頁面嗎?';                  // 要離開或關閉目前頁面時,返回要顯示給使用者看的提醒文字
});

因為在 DOM 事件中,各家瀏覽器的實作會略有差異 (像是 IE9 以下),推薦可以使用 jQuery 來更方便的處理 DOM 事件。