Introduction to Responsive Web Development with HTML and CSS - U7 - Adding interaction
---
To complete our project, we will add some interaction details, such as CSS transitions or a punctual use of JavaScript to improve responsive navigation.
===
### Email link
目前的課程不會用到表單 (form),因為牽涉到 server side 的程式設計,比較複雜
#### 使用 `mailto:` 利用 email protocol 叫出 email app 來寄送 Email
```
<!-- html -->
</a>
```
#### 使用 `tel:` 利用電話 protocol 叫出電話 app 撥電話
```
<!-- html -->
<a href="tel:+34666666666">
Telephone: 666 666 666
</a>
```
===
### Transitions in CSS
#### transition 屬性
語法: `transition:duration property delay`
transition: [持續期間] [轉變屬性] [延遲時間]
```
/* CSS */
a{
color:blue;
}
a:hover{
color: hotpink;
}
```
如上 CSS 當我們設定 hover 狀態後,把滑鼠移到連結 (link) 上方時,可以看到狀態 (state) 轉變,連結顏色變色,我們可以用 transition 這個屬性 (property) 另外設定狀態轉變效果,
舉個例子:
```
/* CSS */
a{ /* 顏色轉變,持續時間 1 秒鐘*/
transition: 1s color;
}
```
![transition.gif](https://raw.githubusercontent.com/Cssmiley/trello_joplin_calendar_blog/main/uPic/e50cee3c15394c4f868bbc317373c8cd.gif)
如下面例子, 也可以做背景顏色的 transition, 這裡加了延遲效果試試, 雖然這特效不常用, 一般會希望馬上看到特效
```
/* CSS */
div{
background-color: red;
/* 轉變。 過程 轉變類型 延遲*/
transition: 1s background-color 2s;
}
div:hover{
background-color: blue;
}
```
![transition_color.gif](https://raw.githubusercontent.com/Cssmiley/trello_joplin_calendar_blog/main/uPic/140d5d8cb33141fa8c778147c41c4cb2.gif)
常見的 transition 特效也出現在圖片, 如下面例子, 平時是半透明圖片 (opcity:0.5), 當滑鼠移到圖片 (hover狀態) 時才變成不透明圖片 (opacity:1)
```
/* CSS */
img{
opacity: 0.5;
transition: 0.5s opacity;
}
img:hover{
opacity: 1;
}
```
![transition_img.gif](https://raw.githubusercontent.com/Cssmiley/trello_joplin_calendar_blog/main/uPic/7e025097f42942e99fddf9659e465138.gif)
也可以利用transition做出下面的 捲軸展開 ( deply ) 特效
一樣是(hover狀態) 時才做屬性轉變
平時是 div 收合,利用最大高度限制(max-height: 30px)和溢出隱藏 (overflow:hidden)達成 ; 當滑鼠移到 div 上時 (hover狀態) 時,就變成展開 ,利用增加最大高度(maxheight:400px)的屬性轉變來達成
```
/* CSS */
div{
max-height: 30px;
overflow: hidden;/* 讓 content 不超過 container*/
transition: 0.5s max-height;
}
div:hover{
max-height: 400px;
}
```
![transition_curtain.gif](https://raw.githubusercontent.com/Cssmiley/trello_joplin_calendar_blog/main/uPic/1ac48482e1054273a925b0da505d7074.gif)
##### 注意:只有具有中間態 (intermediate) 的屬性可以 transition,不是所有的屬性都是可轉變的 ( transitionable )
ex. display 屬性就不行, display:none 和 display:block 之間沒有中間態;寬度 width ( 10px 漸漸變成 20px ), 顏色 color ( color 是數字型數值 numerical value 所以可以 ), 透明度 opacity 之類有中間態的屬性就可以做 transition 轉變
===
### Link a JavaScript file
這裡老師說不會在初階課程深入 javascript , 因為牽涉到一般程式語言 javascript 和 標記導向語言 mark-oriented languages 的 HTML 和 CSS 差異太大不易消化,要在之後課程介紹,但是讓我們稍微接觸熟悉 JS
在 HTML 中使用 `<script>` 標籤帶進 javascript 的檔案
```
<!-- html -->
<script src="javascript.js"></script>
```
使用時注意,如果把 `<script>` 標籤跟前面用到的 CSS 檔一樣放在 head 下方, 仍然可以讀取,只是這樣做會造成**還沒讀完 javascript 時,不會讀 html 頁面**, 因此, **建議把 `<script>` 標籤放在 body 最下面** 讓 html頁面先讀完再來讀 javascript
```
<!-- html -->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
...
...
...
<script src="javascript.js"></script>
</body>
</html>
```
===
### Navigation with JavaScript added
#### 要讓 javascript 作用,需要做到
- html 內 `<script>` 標籤包入 javascript 的 `.js` 檔
- javascript 檔內的 javascript 語法
- 在 CSS 內添加一些對應的 styles
這裡我們修改一下之前的[Introduction to Responsive Web Development with HTML and CSS - U6 - Responsive techniques](:/7330190c08784a3da29014d9024a25de) 的 Responsive navigation 完成的 Menu 特效網頁
改成 點擊 Menu 出現下拉選單
![Menu_unfold.gif](https://raw.githubusercontent.com/Cssmiley/trello_joplin_calendar_blog/main/uPic/1289f75d8d014d48960c4147780d804f.gif)
@ javascript 在這堂初階課先不用理解,只需要知道下面 /* */ 註解說明用來做什麼功能
```
/* javascript */
var launcher = "#link-menu";
var unfoldable = "#menu";
var unfoldClass = "menu-unfold";
function nav(){
var launch = document.querySelector(launcher);
/* 滑鼠 click 並呼叫另一個 function unfoldMenu()*/
launch.addEventListener("click", unfoldMenu, false);
}
function unfoldMenu(e){
e.preventDefault();
var unfo = document.querySelector(unfoldable);
/* add 或 remove menu-unfold class */
unfo.classList.toggle(unfoldClass);
}
/* 當 function 被啟動時 在 <html>標籤(在html檔內) 增加 js class,這代表 Javascript 正在 working */
document.querySelector("html").classList.add("js");
nav();
```
@ CSS 內需要增加給 javascript 對照的 style 樣式, 解說寫在註釋 /* */ 內如下:
```
/* CSS */
/*media queries 作用於頁面小於 600px 的視窗模式時*/
@media screen and (max-width: 600px){
/* .js class 開頭代表這段 style 樣式只有帶入 Javascript 時才 work */
.js .navigation{
max-height: 0;
overflow: hidden;
/* transition 會發生在 state change 時,也就是滑鼠 pass 一個 element 時(點擊元件),或是發生在 添加一個 new class 到 element 時(Javascript 增添 class 到元件,如下面的`.js .navigation.menu-unfold`) */
transition: max-height .5s;
position: absolute;
top: 43px;
left: 30px;
right: 30px;
background-color: #2D211F;
}
.js .navigation a{
padding: 5px 10px;
color: #FFF;
border-top: 1px solid rgba(255, 255, 255, .s);
}
/* 透過 Javascript, 當 menu-unfold class 被加到 navigation class時, max-height 變成 200px */
.js .navigation.menu-unfold{
max-height: 200px;
}
}
/*頁面大於 601px 時*/
/* 為了不和上面的 max-width:600px 發生collosion 這裏的min-width:600px 要改成 min-width:601px */
@media screen and (min-width: 601px){
/* 隱藏 Menu 按鈕*/
.launcher-menu{
display: none;
}
/* 導覽列移到 body 上方 30px 處 */
.navigation{
position: absolute;
top:-30px;
}
/* body這邊空出空間給移到上面的導覽列 */
body{
margin-top: 60px;
}
/* 導覽列列表排成一排相隔一段距離(15px)*/
.navigation li{
display: inline-block;
margin-right: 15px;
}
}
```
[navigation_responsive.html](:/27ce2f42410044bab1280e52cb3edd76)
[javascript.js](:/9bfa7c0f978a4c409c7f1e52e9603608)
[navigationstyles.css](:/e1135b12294d4c4e8e59dce54c829f74)
===
### TASKS
#### Add transition to the links.
Try the transition property in the links, changing the effect of: hover gradually.
#### Add JavaScript to the navigation.
(Optional) Try to play responsive navigation with JavaScript that we have seen.
##### 作業這裡要用剛學到的 javascript 來玩 響應式導覽 responsive navigation, 目前的 javascript 只使用到按下按鈕,做出動作,作業是要利用現在學到的部分來玩響應式設計,所以一樣 javascript只做按下按鈕,利用 media queries 在不同視窗大小產生動作變化
這邊就拿之前的 [Introduction to Responsive Web Development with HTML and CSS - U6 - Responsive techniques](:/7330190c08784a3da29014d9024a25de) 最後面的響應式Task作業來改,當按下按鈕後,頁面才變成響應式的變化,也就是:
- 最小畫面單欄按下按鈕只跳出menu
![Menu_unfold_small.gif](https://raw.githubusercontent.com/Cssmiley/trello_joplin_calendar_blog/main/uPic/adfd6e1c2e024c17a9fd82f32fdde54b.gif)
- 大於600px,按下按鈕變成雙欄式頁面並跳出menu
![Menu_unfold_600px.gif](https://raw.githubusercontent.com/Cssmiley/trello_joplin_calendar_blog/main/uPic/159ca1249f934945a0838f894250e213.gif)
- 大於800px,按下按鈕變成四欄式頁面並跳出menu
![Menu_unfold_800px.gif](https://raw.githubusercontent.com/Cssmiley/trello_joplin_calendar_blog/main/uPic/3ed3ca4ec3df4ea8912af6d083a96cfa.gif)
記得,要讓 javascript 作用,需要做到:
- **HTML** 內 `<script>` 標籤包入 javascript 的 `.js` 檔
- **Javascript** 檔內的 javascript 語法
- 在 **CSS** 內添加一些對應的 styles
==>
###### - HTML 的部分
只需要注意把 `<script>` 包入`.js`檔標籤放到 html 最後 ( **確保html先執行才執行 js script**) ,以及 `CSS` 和 `Javascript` 有對應到樣式和動作的元件即可
<details open>
<summary> **確保html先執行才執行 js script** </summary>
參考網頁:
[".addEventListener is not a function" why does this error occur?](https://stackoverflow.com/questions/32027935/addeventlistener-is-not-a-function-why-does-this-error-occur)
javascript 的程式沒什麼問題,卻得到 `.addEventListener is not a function` 的錯誤,原因是出在 `<script>` 放在html檔的`<body>`上方, 當 html element 元件還沒讀到, script 內對應的元件自然就無法作用,所以老師才說這`<script>`習慣放在`html檔`的`<body>`最後面
> The problem with your code is that the your script is executed prior to the html element being available. Because of the that var comment is an empty array.
>
> So you should move your script after the html element is available.
</details>
###### - Javascript的部分
那`javascript`也需要先稍微理解一下老師用的簡單 javascript (一邊實作修修改改一邊看結果理解學習) ,這裏老師的 javascript 動作重點有三個:
1. 把 `js` class 附加到 `html`後面
2. 監聽滑鼠點擊事件
3. 滑鼠點擊後,需要執行的動作
說明如下:
1. 把 `js` class 附加到 `html`後面, document.querySelector("html").classList.add("js");
```
/* javascript */
/* 當 function 被啟動時 在 <html>標籤(在html檔內) 增加 js class,這代表 Javascript 正在 working */
document.querySelector("html").classList.add("js");
```
參考網頁: [JavaScript 基礎知識-querySelector](https://ithelp.ithome.com.tw/articles/10211605)
[JavaScript 基礎知識-querySelectorAll](https://ithelp.ithome.com.tw/articles/10211614)
<details open>
<summary>querySelector 和 querySelectorAll 是什麼</summary>
> ## 說明 querySelector( )
> 使用 `document.getElementById()` 的方式可以選取 `id` 元素渲染到網頁,但如果今天我想選取的不只是`id`元素,還有 `class` 元素或者標籤
>
> 這時候可以使用到 ` .querySelector()` 的方式,他就不僅僅只局限於 `id` 元素,只是在使用` .querySelector()` 的時候, 選取氣的方式要像 `css` 的方式一樣
> 當選取 `id`元素時:
> ```
> document.querySelector('#title');
> ```
>
> 當選取`class`元素時:
> ```
> document.querySelector('.title');
> ```
> 都要有相對應的`#`或者`.`
>
> ## 說明 querySelectorAll( )
> 上面提到 querySelector( ) 可以選取元素, 但是來看看下面的情況
> ![地雷_CSS和JS作用到單一class而不是所有同名稱class.png](https://raw.githubusercontent.com/Cssmiley/trello_joplin_calendar_blog/main/uPic/e3416c19b4e34ffb8b75c1556078ea94.png)
> 如果 `HTML` 的架構如下:
>
> ```
> <h2 class="title"> </h2>
> <h2 class="title"> </h2>
> <h2 class="title"> </h2>
> <h2 class="title"> </h2>
> ```
> 這時如果使用
> ```
> document.querySelector('.title');
> ```
> 那就只有第一個 `.title` 會被選取到, 其他的 `.title' 類並沒有被選取
> 這時候可以使用 `.querySelectorAll( )` , 這個不但可以把同樣的元素選取起來以外, 還會以陣列的方式被傳回
> 如果以上面的 `HTML` 架構
> ```
> document.querySelectorAll('.title');
> ```
> 這時候會把所有 `.title` 類別選取起來, 並存放於一個陣列, 用讀取陣列的方式我們可以針對每一個項目再做想要的動作,例如更改文字:
> ```
> var el = document.querySelectorAll('.title');
> el[0].textContent = '123';
> el[1].textContent = '456';
> el[2].textContent = '789';
> el[3].textContent = '1234567';
> ```
> 或是對陣列內的全部同類別的元素一次修改, 記得適用 `for` 迴圈, 因為是陣列的方式選取:
> ```
> var el = document.querySelectorAll('.title');
> for(var i=0; i<el.length; i++){
> el[i].textContent = '更改';
> }
> ```
> 這時候所有 `.title` 類別的文字都會一起改變
> 大家可以試試看 `.querySelector( )` 跟 `.querySelectorAll( )` 的差別
</details>
所以這一段 `document.querySelector('html')` 可以先理解是選取到`html`
參考網頁: [classList是什麼](https://codertw.com/%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC/27430/)
<details open>
<summary>classList是什麼</summary>
> 頁面 DOM 裡的每個節點上都有一個 `classList` 物件, 程式設計師可以使用裡面的方法新增程式設計師可以使用裡面的方法新增、刪除、修改節點上的 `CSS` 類,甚至可以判斷某個節點是否被賦予某個 `CSS` 類
> ## 新增類 (add)
> 為 `<div>` 元素新增類:
> ```
> document.getElementById("myDIV").classList.add("mystyle");
> ```
> 新增多個類:
> ```
> document.getElementById("myDIV").classList.add("mystyle", "anotherClass", "thirdClass");
> ```
>
> ## 移除類 (remove)
> 使用 remove 方法,可以刪除單個`CSS`類
> ```
> document.getElementById("myDIV").classList.remove("mystyle");
> ```
> 移除多個類:
> ```
> document.getElementById("myDIV").classList.remove("mystyle", "anotherClass", "thirdClass");
> ```
> ## 切換類 (toggle)
> 這個方法的作用就是像開關一樣, 當 myDIV 元素上沒有這個 `CSS` 類時, 他就新增這個 `CSS` 類; 而如果 myDIV 元素已經有這個 `CSS` 類,就刪除:
> ```
> document.getElementById("myDIV").classList.toggle("newClassName");
> myDiv.classList.toggle('myCssClass'); //現在是增加
> myDIV.classList.toggle('myCssClass'); //現在是刪除
> ```
> ## 是否存在類 (contains)
> 檢查是否含有某個 `CSS` 類
> ```
> var x = document.getElementById("myDIV").classList.contains("mystyle");
> ```
> 結果是得到 true 或 false
</details>
那麼這段 `document.querySelector("html").classList.add("js");` 可以理解為在`html`後新增 `js` 類
代表 javascript 作用中
2. 監聽滑鼠點擊事件 , function nav( )
```
/* javascript */
/* 對照 html 檔,最上方的 menu 按鈕的 id 是`#link-menu` 如下:
<a href="#menu" class="launcher-menu" id="link-menu">Menu</a> */
var launcher = "#link-menu";
/* 用來監聽滑鼠點擊的 nav() 函式,點擊後呼叫另一個 unfoldMenu() 函式*/
function nav(){
var launch = document.querySelector(launcher);
/* 監聽滑鼠點擊 click 事件,並呼叫另一個 function (下面的 unfoldMenu) */
launch.addEventListener("click", unfoldMenu, false);
}
```
這邊的 menu 按鈕,透過 addEventListener("click", unfoldMenu, false), 在滑鼠點擊後呼叫 function unfold Menu( )
3. 滑鼠點擊後,需要執行的動作, function unfoldMenu( )
```
/* javascript */
/* 對照 html 檔,下方導覽列 navigation 類的 id 是`#menu` 如下:
<div id="menu" class="navigation"> */
var unfoldable = "#menu";
/* 作為 javascript 動作,按下按鈕後要開關(toggle)的附加上去 class 自定為 menu-unfold */
var unfoldClass = "menu-unfold";
/* 函式執行後,會在指定的節點的 classList 開啟或關閉(toggle) CSS類 menu-unfold*/
function unfoldMenu(e){
e.preventDefault();
var unfo = document.querySelector(unfoldable);
/* add 或 remove menu-unfold class */
unfo.classList.toggle(unfoldClass);
}
```
這邊的 function unfoldMenu( ), 負責執行開關動作, 把 menu-unfold 這個 `CSS` 類附加或卸除
上面原本老師的 javascript 只有對 `#menu` (也就是html裡的 navigation導覽列 )做開關(toggle)動作
這邊作業就增加了也對 `.exercise` 的四個 html 裡的 `<div>`區塊作開關 (toggle) 動作,記得選取同樣類別的多個元件要用querySelectorAll( )
```
/* javascript */
/* 對照 html 檔,中段四個 <div> 的類別class是`.exercise` 如下:
<div class="exercise"> */
var unfold_div = ".exercise"
/* 函式執行後,會在指定的節點的 classList 開啟或關閉(toggle) CSS類 menu-unfold*/
function unfoldMenu(e){
e.preventDefault();
var unfodiv = document.querySelectorAll(unfold_div);
/* add 或 remove menu-unfold class */
for (var i=0; i<unfodiv.length; i++){
unfodiv[i].classList.toggle(unfoldClass);
}
}
```
###### - CSS部分
使用 media queries([Introduction to Responsive Web Development with HTML and CSS - U6 - Responsive techniques](:/7330190c08784a3da29014d9024a25de)) 處理不同視窗大小,分成三部分:
1. 最小螢幕, 單欄式頁面不需要改動
2. 視窗大於 600px, 點擊按鈕變成雙欄式頁面
3. 視窗大於 800px, 點擊按鈕變成四欄式頁面
說明如下:
1. 最小螢幕, 單欄式頁面不需要改動
```
/* CSS */
/* 最小螢幕時, javascript作用 按下menu按鈕後,四個 exercise類的<div> 開關menu-unfold類別後的變化,這裏不用更動,所以留空白不動作(也可以不用寫這一段,javascript仍會在 .exercise 掛上沒有作用的menu-unfold)*/
.js .exercise.menu-unfold{
}
```
單欄式頁面不需要改動,所以這裏可以不用寫,只是為了可讀性留一個空白的.js .exercise.menu-unfold{ }
2. 視窗大於 600px, 點擊按鈕變成雙欄式頁面
```
/* CSS */
/* 啟用javascript,按下menu按鈕後,導覽列開關menu-unfold類別的變化*/
.js .navigation.menu-unfold{
max-width: 400px;
position: absolute;
top: 0px;
left: 60px;
right: 30px;
}
/* 啟用javascript,按下menu按鈕後,導覽列開關menu-unfold類別的變化*/
.js .exercise.menu-unfold{
width: 50%;
border-radius:55px;
background-color: #F4F4D9;
float: left;
font-size: 20px;
border-style: double;
}
```
原本就有的 `.js .navigation.menu-unfold{...}` 是老師原本的按鈕展開後的 `CSS` 樣式
這邊新增加 `.exercise`的 `.js .exercise.menu-unfold{...} ` 的 `CSS` 樣式,是延續之前的 [Introduction to Responsive Web Development with HTML and CSS - U6 - Responsive techniques](:/7330190c08784a3da29014d9024a25de) 的 Responsive navigation作業內容,改成雙欄式的 ``<div>`` 排列, 所以重點在 `width: 50%` 好容納兩欄
3. 視窗大於 800px, 點擊按鈕變成四欄式頁面
```
/* CSS */
/* 啟用javascript,按下menu按鈕後,導覽列開關menu-unfold類別的變化*/
.js .exercise.menu-unfold{
width: 25%;
float: left;
font-size: 24px;
background-color: #D9F4F4;
}
```
這邊新增加 .exercise 的 .js .exercise.menu-unfold{...} 的 CSS 樣式, 一樣是延續之前的 Introduction to Responsive Web Development with HTML and CSS - U6 - Responsive techniques 的 Responsive navigation作業內容,改成四欄式的 <div> 排列, 所以重點在 width: 25% 好容納四欄
##### 完整的 HTML, CSS, Javascript 檔
@ HTML
```
<!-- html -->
<!DOCTYPE html>
<html>
<head>
<title>U7 - Adding Interaction_Task</title>
<meta charset="utf-8">
<link rel="stylesheet" href="css/task2styles.css">
</head>
<body>
<!-- <script> 放在這裡會造成 html元件 還沒出現, script 不起作用,所以要搬到最下面,確保所有 html 元件都讀完了才執行 script-->
<!-- <script src="task2javascript.js"></script> -->
<a href="#menu" class="launcher-menu" id="link-menu">Menu</a>
<div class="exercise">
<h3>Excercise 1</h3>
<p>-**第一層 戰或逃(直覺反應)**------------ 習慣反射篩子
和人對話時,直覺反應和反駁,只是淺薄的思考就回覆,用的是慣性思考,直覺的把人事物聽到的東西和**未加思索**的判斷劃上等號,並**急於解釋**時停留在對話時的主題,或者別人所指控的內容,受當時的**狀態和情緒**影響,很容易失真引起自己對自己的誤解和他人對自己的誤解,也會發生直接把看到聽到的東西想成自己預期的(ex.沒有聽清楚,回想的時候聽錯 ==> 你不喜歡為什麼不早說->喜憨兒)
</p>
</div>
<div class="exercise">
<h3>Excercise 2</h3>
<p>**第二層 深度思考(停下來仔細一想)**-----------實際處理機器
暫離對話環境.獨處的時候,重新思索質疑的部分和令人焦慮的內容,像是把議題從第一層抓下來重新深度處理,考慮前後文和事件,從情緒化的回應時指把注意力放在單一個點和句子,擴展到更深更廣的角度去爬梳和釐清,這時就不在只是自衛或勝負,而是試著更完整的理解事情的原貌,並找到可解決的方案
- 做足功課,主動搜尋第一手資料,可靠來源,例如學術論文.專業書籍.消化並且形成更多維立體的觀點,實作驗證,反覆影響第一層第二層行程的解讀和感受
</p>
</div>
<div class="exercise">
<h3>Excercise 3</h3>
<p>對話時的句子,像是拋下來的球,有些直接反應的就泡回去一句話,有些則是不重要可以 DROP ,有些則是暫時沒有想法,KEEP 在上面,當思考或是對話時,這些球像是圖論裡的節點,把意圖轉換成一個接近的句子,接近但不能代表完整意思或容易引起誤解,當環境是public,其他人對這顆球做出反應 grab & throw,這顆球就像發炎一樣,正在引起自己的關注,焦點都放在上面,其他節點脈絡都縮到後面,對他人或事物的感受形成後,在這一層做直覺的反應
當開始思索質疑或令自己焦慮的問題時,好像把球抓下來,進行深度思考, consider 進行加工處理,得到更完整的解讀的球,改變對人事物的看法,也許足夠完整以及時間夠久以後會改變原先第一層的感受上直覺反應的部分,他人的 grab & throw 當然也會對這裡的球進行回應
</p>
</div>
<div class="exercise">
<h3>Excercise 4</h3>
<p>對話時的情境:
- **情緒對打**,在第一層對著彼此發炎的球互戳,情緒互相衝撞.拿刀互砍,反應時間短,來不及思考
- 其中一方在第二層考慮到對方.自己,選擇比較好的心態溝通
- 都在第二層second thoughts,互相考慮.體諒,同理對方並找到共識
</p>
</div>
<div id="menu" class="navigation">
<ul>
<li>
<a href="#">Profile</a>
</li>
<li>
<a href="#">Service</a>
</li>
<li>
<a href="#">Contact</a>
</li>
<li>
<a href="#">Blog</a>
</li>
</ul>
</div>
<script src="task2javascript.js"></script>
</body>
</html>
```
@ CSS
```
/* CSS */
*{
box-sizing: border-box;
}
.exercise{
width: 100%;
height: 16em;
padding: 20px;
float: none;
overflow:auto;
background-color: antiquewhite;
/*
border-style: dotted;
border-radius:55px;
*/
}
.navigation a{
display: block;
text-decoration: none;
color: #2D211F;
border-bottom: 1px solid #2D211F;
}
.launcher-menu{
text-decoration: none;
color: #FFF;
padding: 6px 10px;
background-color: #2D211F;
border-radius: 3px;
}
/* 最小螢幕時, javascript作用 按下menu按鈕後,導覽列 navigation 開關menu-unfold類別後的變化*/
.js .navigation.menu-unfold{
position: absolute;
top: 43px;
left: 30px;
right: 30px;
background-color: #2D211F;
}
/* 最小螢幕時, javascript作用 按下menu按鈕後,四個 exercise類的<div> 開關menu-unfold類別後的變化,這裏不用更動,所以留空白不動作(也可以不用寫這一段,javascript仍會在 .exercise 掛上沒有作用的menu-unfold)*/
.js .exercise.menu-unfold{
}
/* 螢幕大於600px時的視窗(screen)模式下的 CSS 樣式*/
@media screen and (min-width: 600px){
.js .exercise{
width: 100%;
border-radius: 10px;
background-color: antiquewhite;
transition: width,background-color,border-radius 1.5s;
height: 16em;
padding: 20px;
float: none;
overflow:auto;
border-style: dashed;
}
/* 啟用javascript,按下menu按鈕後,導覽列開關menu-unfold類別的變化*/
.js .exercise.menu-unfold{
width: 50%;
border-radius:55px;
background-color: #F4F4D9;
float: left;
font-size: 20px;
border-style: double;
}
/* Menu 按鈕位置和開啟的導覽列同樣高度*/
.launcher-menu{
display: inline-block;
position: absolute;
top: 43px;
left: 10px;
float:left;
}
.js .navigation{
max-width: 0;
overflow: hidden;
transition: max-width .5s;
position: absolute;
top: 43px;
left: 30px;
right: 30px;
background-color: #2D211F;
}
.js .navigation a{
padding: 5px 10px;
color: #FFF;
border-top: 1px solid rgba(255, 255, 255, .s);
}
/* 啟用javascript,按下menu按鈕後,導覽列開關menu-unfold類別的變化*/
.js .navigation.menu-unfold{
max-width: 400px;
position: absolute;
top: 0px;
left: 60px;
right: 30px;
}
/* 導覽列移到 body 上方 30px 處 */
/*
.js .navigation{
position: absolute;
top:-30px;
}
*/
/* body這邊空出空間給移到上面的導覽列 */
.js body{
margin-top: 60px;
}
/* 導覽列列表排成一排相隔一段距離(15px)*/
.js .navigation li{
display: inline-block;
margin-right: 15px;
box-shadow:10px 10px black;
}
}
/* 螢幕大於800px時的視窗(screen)模式下的 CSS 樣式*/
@media screen and (min-width: 800px){
/* 啟用javascript,按下menu按鈕後,導覽列開關menu-unfold類別的變化*/
.js .exercise.menu-unfold{
width: 25%;
float: left;
font-size: 24px;
background-color: #D9F4F4;
}
}
a:visited{
color: blue;
text-decoration: none;
}
a:hover{
text-decoration: underline;
}
a:active{
color: orange;
}
a:focus{
background-color: lightgray;
}
```
@ javascript
```
/* javascript */
/* 對照 html 檔,最上方的 menu 按鈕的 id 是`#link-menu` 如下:
<a href="#menu" class="launcher-menu" id="link-menu">Menu</a> */
var launcher = "#link-menu";
/* 對照 html 檔,下方導覽列 navigation 類的 id 是`#menu` 如下:
<div id="menu" class="navigation"> */
var unfoldable = "#menu";
/* 對照 html 檔,中段四個 <div> 的類別class是`.exercise` 如下:
<div class="exercise"> */
var unfold_div = ".exercise"
/* 作為 javascript 動作,按下按鈕後要開關(toggle)的附加上去 class 自定為 menu-unfold */
var unfoldClass = "menu-unfold";
/* 用來監聽滑鼠點擊的 nav() 函式,點擊後呼叫另一個 unfoldMenu() 函式*/
function nav(){
var launch = document.querySelector(launcher);
/* 監聽滑鼠點擊 click 事件,並呼叫另一個 function (下面的 unfoldMenu) */
launch.addEventListener("click", unfoldMenu, false);
}
/* 函式執行後,會在指定的節點的 classList 開啟或關閉(toggle) CSS類 menu-unfold*/
function unfoldMenu(e){
e.preventDefault();
var unfo = document.querySelector(unfoldable);
/* add 或 remove menu-unfold class */
unfo.classList.toggle(unfoldClass);
var unfodiv = document.querySelectorAll(unfold_div);
/* add 或 remove menu-unfold class */
for (var i=0; i<unfodiv.length; i++){
unfodiv[i].classList.toggle(unfoldClass);
}
}
/* 當 function 被啟動時 在 <html>標籤(在html檔內) 增加 js class,這代表 Javascript 正在 working */
document.querySelector("html").classList.add("js");
/* 呼叫 nav() 函式 */
nav();
```
[task2.html](:/e9d94b7a074d433882fe30d41bbe1bb0)
[task2styles.css](:/f4476d2a0f0a4b7495567b33e83dd209)
[task2javascript.js](:/bea130a063514e2b91dbb2a54c43bb3e)
#### ADDITIONAL RESOURCES
Webs and interesting books
- CSS properties reference in Mozilla Developer Network (Spanish, incomplete): https://developer.mozilla.org/es/docs / Web / CSS / Reference_CSS
- CSS property reference in Mozilla Developer Network (English, more developed): https://developer.mozilla.org/ en-US / docs / Web / CSS / Reference
- A good book to continue learning HTML and CSS (English): http://htmlandcssbook.com/
A good book to learn JavaScript in depth (English): http://javascriptbook.com/