前言 : 寫程式關注的面向到底是甚麼 ?
- 介面 : 如何改變介面
- 事件 : 如何監聽事件並做出反應
- 資料 : 如何跟伺服器交換資料/如何將資料在瀏覽器中保存下來
結論 : 任何程式都是這三樣。
JavaScript 與瀏覽器的溝通
執行 JavaScript 的一百種方式
js 可以在哪裡執行 ? 答:node.js、瀏覽器
怎麼在瀏覽器上執行 js ?
可以在 html 放 <script> js 程式碼 </script>
,script 標籤放在不同的位置,會有些許不同。實作中會傾向將 js 程式碼引入進 html,而非直接在 html 加一堆 js code。
./ 表示相對路徑,同一個資料夾底下的 index.js。
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="./style.css">
<link rel="stylesheet" href="https://necolas.github.io/normalize.css/8.0.1/normalize.css"/>
<script src="./index.js"></script>
</head>
<body>
</body>
</html>
alert("yo yo yo")
node.js 與瀏覽器跑 js 的差別 ?
JS 的語法是相同,但某些地方瀏覽器不支援,但 node.js 支援,反之亦同。(原因:因為兩個執行環境不同)。
RMK:瀏覽器的執行環境能做的事情相對較少,node.js 較自由。
DOM 是什麼?
Document Object Model:將 document 轉換成 object。 document 是指在 html 寫的那些東西。目的:讓 JS 可以改 html 的介面。
我們可以將 html 的標記轉換成階層關係。轉換後類似物件,例如 : 我可以取到 body 這個物件,我可以取到它底下所有東西。
雖然改的是 JS,但瀏覽器會幫助我們改動畫面實際的東西。所以,dom 是 js 與 html 的橋樑,或者更進一步說 dom 是 js 與瀏覽器之間的橋樑,
結論
: JavaScript 是如何操作畫面的?是透過一個叫做 DOM(Document Object Model)的東西。簡單來說就是瀏覽器把畫面上那些 HTML 元素都轉成物件,並且提供給你一個 API 來操作它們。
如何選到想要的元素:getElement
瀏覽器提供很多方法讓我們選元素,以下我們將一一介紹。
(RMK:這些 function 都是放在 document 內, document 是瀏覽器提供的特殊物件,它將很多 function 都在放上面。)
一、getElementsByTagName
TagName = 標籤名稱。
發現印出的東西是空的,空陣列。
0: div
HTMLCollection(0) 可以先將 HTMLCollection 想像成特殊形態的陣列
length: 0
(原因:程式是由上而下跑,所以瀏覽器解析也是由上而下一段一段解析,故script 放置的位置會影響執行結果,因此在下方的代碼中當它解析 script 時,它尚未跑到 div 這段,所以這個時候電腦根本不知道 body 內是甚麼。)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="./style.css">
<link rel="stylesheet" href="https://necolas.github.io/normalize.css/8.0.1/normalize.css"/>
<script src="./index.js"></script>
</head>
<body>
<div>
hello world!
</div>
</body>
</html>
const elements = document.getElementsByTagName('div')
console.log(elements)
這也是為甚麼實務上,大家習慣將 script 放在</body>
上,因為當我在這裡時,我看的到上面所有的資訊。
HTMLCollection [div]
0: div
length: 1
<body>
<div>
hello world!
</div>
<script src="./index.js"></script>
</body>
HTMLCollection(2) [div, div]
0: div
1: div
length: 2
<body>
<div>
hello world!
</div>
<div>
ha ha ha ~
</div>
<script src="./index.js"></script>
</body>
結論
:可以藉由 getElementsByTagName 來抓到屬於這個 tag 的元素。
二、getElementsByClassName
HTMLCollection(2) [div.block, div.block]
0: div.block
1: div.block
length: 2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="./style.css">
<link rel="stylesheet" href="https://necolas.github.io/normalize.css/8.0.1/normalize.css"/>
</head>
<body>
<div class='block'>
hello world!
</div>
<div class='block'>
ha ha ha ~
</div>
<script src="./index.js"></script>
</body>
</html>
const elements = document.getElementsByClassName('block')
console.log(elements)
結論
:可以藉由 getElementsByClassName 來抓到指定 ClassName 的東西。
三、getElementById
注意:因為 ID 只會有一個,所以這邊的 Element 不用加 s
// 會直接印出這個元素
<div id="block">
hello world!
</div>
<body>
<div id='block'>
hello world!
</div>
<div>
ha ha ha ~
</div>
<script src="./index.js"></script>
</body>
const elements = document.getElementById('block')
console.log(elements)
四、querySelector
querySelector 後面接的是 css 的選擇器。只會回傳匹配到的第一個元素。
const elements = document.querySelector('#block')
const elements = document.querySelector('div')
const elements = document.querySelector('.block2')
const elements = document.querySelector('div a')
const elements = document.querySelector('div>a')
<body>
<div id='block'>
hello world!
</div>
<div class='block2'>
ha ha ha ~
<a>hello</a>
</div>
<script src="./index.js"></script>
</body>
儘管我有兩個 div 它也只會回傳第一個 div。所以如果想選到所有的 div 可以怎麼做 ? A:使用 querySelectorAll。
五、querySelectorAll
NodeList(2) [div#block, div.block2] 很像陣列,但不是陣列
0: div#block
1: div.block2
length: 2
const elements = document.querySelectorAll('div')
改變元素的 CSS
用 element.style 後面接你要改的東西就可以了。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id='block'>
hello world!
</div>
<script src="./index.js"></script>
</body>
</html>
const elements = document.querySelector('#block')
element.style.background = 'red'
element.style.padding = '20px'
. 後面不能接 dash。所以有兩種方式:
第一種:[""],用字串包起來。
第二種:駝峰式
element.style['padding-top'] = '20px'
element.style.paddingTop = '20px'
程式碼很亂,改六個 style 就寫六次
const element = document.querySelector('#block')
console.log(element)
element.style.background = 'red'
element.style.width = '100px'
element.style.margin = 'auto'
element.style.border = '10px solid green'
element.style.padding = '4px'
element.style['text-align'] = 'center'
實作上,為了好維運。會先寫一個 class,再將 element 加上 class name。就可將 style 寫到 class 內,而不用寫到程式碼內。
改變元素的 Class
改變 class 再讓 class 去負責處理不同的內容會是比較好的方法。
如何讓 js 動態把 class 加上去 ? A : element.classList.add('class名稱')
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.active {
background: red;
}
</style>
</head>
<body>
<div id='block'>
hello world!
</div>
<script src="./index.js"></script>
</body>
</html>
const element = document.querySelector('#block')
element.classList.add('active')
多個可以分次寫
const element = document.querySelector('#block')
element.classList.add('active')
element.classList.add('active2')
如何將 class name 移除 ? A:element.classList.remove('class 名稱')
<body>
<div id='block' class='main'>
hello world!
</div>
<script src="./index.js"></script>
</body>
const element = document.querySelector('#block')
element.classList.remove('main')
開變關,關變開 element.classList.toggle('class 名稱') => 本來沒有會新增上去,本來有會移除。舉例來說,按鈕按下去會怎樣 ? 本來沒有按下去按了之後會變樣子/本來是按下去的,點了會變回原本的樣子。
與監聽事件一起合用,可以先試著玩一下,手動增加每一行這個會發生甚麼事
element.classList.toggle('main')
改變內容:inner、outer 的 HTML 與 text
一、innerText 改變文字內容
印出標籤內文字,不會將標籤一起顯示出來。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.active {
background: red;
}
</style>
</head>
<body>
<div id='block'>
hello world!
<a>yo yo~</a>
</div>
<script src="./index.js"></script>
</body>
</html>
const element = document.querySelector('#block > a')
console.log(element.innerText)
通常不太會對 block 改它的 inner-text 會直接抓 a 改
顯示:hello world! have a good day.
const element = document.querySelector('#block > a')
element.innerText ='have a good day.'
console.log(element.innerText)
二、innerHTML 把標籤中的東西拿出
顯示結果:
hello world!
<a>yo yo~</a>
const element = document.querySelector('#block')
console.log(element.innerHTML)
三、outerHTML 標籤以內的東西拿出
把自己也抓出來。
顯示結果:
<div id="block">
hello world!
<a>yo yo~</a>
</div>
const element = document.querySelector('#block')
console.log(element.outerHTML)
所以當我改,我可以改所有東西。
const element = document.querySelector('#block a')
element.outerHTML ='<h1>hi</h1>'
console.log(element.outerHTML)
最常使用 innerText, innerHTML
插入與刪除元素:appendChild 與 removeChild
一、removeChild
要刪除元素,需要知道它的 parent 是誰。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.active {
background: red;
}
</style>
</head>
<body>
<div id='block'>
hello world!
<a>yo yo~</a>
</div>
<script src="./index.js"></script>
</body>
</html>
const element = document.querySelector('#block')
element.removeChild(document.querySelector('a'))
如果我選錯東西會怎麼辦 ? 我會選到開頭的 a 但它並不是那個 child => 它會無法 remove。
<body>
<a>111</a>
<div id='block'>
hello world!
<a>yo yo~</a>
</div>
<script src="./index.js"></script>
</body>
二、appendChild
新增 element
const element = document.querySelector('#block')
const item = document.createElement('div')
item.innerText="123"
element.appendChild(item)
新增文字
const element = document.querySelector('#block')
const item = document.createTextNode('angela')
element.appendChild(item)
如何拿到旁邊元素、上面的上面的元素、如何插入到最前面,都有其它的 api,google 4 你的好朋友~ 操作是類似,只是要查找有哪些資源可以使用。