這兩個禮拜再重新看過javascript,並做了一個台北市旅遊景點導覽的網頁,使用了政府資料開放平臺的DATA,紀錄這次使用到的功能及心得。
實作內容
這次用了HTML、CSS、JavaScript這些前端基本語言,
來實作一個台北市的旅遊景點資料站,資料來源是政府資料開放平臺,
樣式的部分還是簡單的HTML跟CSS刻,主軸放在Javascript上,
紀錄這次在JavaScript上遇到跟重新學習理解到的東西。
querySelector & querySelectorAll
元素選擇器!
還記得以前最常使用的就是要找ID時用document.getElementById(),
當要找Class的時候要用getElementsByClassName()。
而這次學習了使用querySelector()
以及querySelectorAll()
這兩個函式:
共通點是都可以用css的規則來作為選擇,例如ID用#
,ClassName用.
來操作,
例如:1
2
3
4<div id="divID">AAA</div>
<div class="divClass">BBB</div>
<div class="divClass">CCC</div>
<div data-no="1">DDD</div>
要取得AAA的資料可以透過querySelector('#divID')
要取得BBB的資料可以透過querySelector('.divClass')
要取得DDD的資料可以透過querySelector('div[data-no="1"]')
但是若有重複的className透過querySelector('.divClass')
只會取到第一筆BBB
的值,
所以就要用querySelectorAll('.divClass')
來取得所有className是.divClass
元素,
但特別要注意的的是,透過querySelectorAll()
取得的值會被放入陣列中,
所以例如寫了:var data = document.querySelectorAll('.divClass').textContent;
會得到['BBB','CCC']
這樣的內容,要取出BBB
就是data[0]
!
學到這裡時,真心覺得jQuery的$('')
真的很方便啊XD!
addEventListener
綁定事件,使用方法是element.addEventListner(事件, 執行內容, useCapture)
事件
指的是要偵測的事件,例如點擊click
,內容變換change
、鍵盤動作keyCode
執行內容
指的是要執行的項目,可以直接指定function或直接寫在裡面
例如:document.body.addEventListner('click', SomeFunction, true);
document.body.addEventListner('click', function(e) { console.log(e) }, false);
要注意的是當使用第一種方法直接呼叫別的function時,不能傳參數,
若要傳參數只能在包一層function,例如:document.body.addEventListner('click', function(e) { SomeFunction(param) }, false);
useCapture
目前沒有使用情境,老實說並不是很了解的參數,
但他是一個true/false
的設定值,預設是false
。
當設定為true
時,會從指定元素的最外層元素開始往內層執行,
反之設定為false
則從指定元素開始往外層執行,舉例:
1 | <div class="father"> |
當設定document.querySelector('.child').addEventListener('click',function() { console.log('C') }), ture)
document.querySelector('.father').addEventListener('click',function() { console.log('F') }), ture)
會先印出F(外層),若設定為false時會先印出C(內層)
若father設定false
,child設定成ture
,則會先印C
,反之則先印F
function(e){}
這次使用了很多fuction的狀態偵測,
例如前兩個querySelectorAll
跟addEventListner
組合時就會用到:1
2
3
4
5
6
7
8
9
10
11/**
* 景點資料按鈕功能綁定
*/
function setReadMoreButton() {
var readMoreButton = document.querySelectorAll('.button--readMore');
for (var i = 0; i < readMoreButton.length; i++) {
readMoreButton[i].addEventListener('click', function(e) {
showViewData(e.srcElement.getAttribute('data-viewNo'));
}, false);
}
}
透過e.srcElement
來取得觸發事件的元素,進一步取得要操作的值。
XMLHttpRequest
為了要獲取JSON內容來使前端動態組成景點內容,
使用XHR(XMLHttpRequest)來做:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/**
* 取得台北市行政區資料
* 透過AJAX取得JSON資料
*/
var areaData = ''; //全部的行政區資料(全域變數)
function getAreaData() {
//建立一個新的XMLHttpRequest
var xhr = new XMLHttpRequest();
//設定這個xhr來get放在data資料夾底下的json檔案
xhr.open('get', 'data/viewZip.json', true);
//傳送這個xhr的請求
xhr.send(null);
//當取得xhr回應後,執行這個function
xhr.onload = function() {
//檢查狀態碼,若非200連線OK則顯示錯誤訊息
if (xhr.status == 200) {
areaData = JSON.parse(xhr.responseText);
createAreaSelect(); //建立行政區下拉選單
getViewData(); //取得景點資料
}else {
document.querySelector('.box-area').innerHTML = '<h2>取得資料時發生錯誤,請檢查網路狀態並重新整理:)</h2>';
}
}
}
window.history
AJAX動態組成的資料在使用者眼裡看起來像是換了一頁,
但實際上網頁本身並沒有切換頁面,只是”替換“了內容,
所以自然瀏覽器也不會去紀錄上一頁、下一頁的資料,
導致切了很多內容後,想回到上一頁卻離開了這個網站。
為了解決這個問題,就要自己產生紀錄!
從window.history
中可以得知每次對頁面的切換都會有紀錄,
可以透過history.pushState(object, title, url)
來增加紀錄。
參數分別是(要寫進紀錄的值、標題、網址),其中第二個參數目前是沒作用的。
並可用window.onpopstate
來偵測瀏覽器的上、下頁行為
以這個實作的範例來說,我的想法跟流程是這樣:
進入網頁時,先寫入當時的行政區與頁碼到history.state中,
並同時在localStorage寫入相同值,當使用者點擊上、下頁時,
將寫入的值取出並透過這組值來重組頁面資料,達到切頁的效果。
localStorage寫入值的用途為當重新整理時,要撈到重整前的值來重組畫面,
故當程式呼叫到寫入瀏覽紀錄時也要寫、動作切上下頁時也要寫入。
1 | /** |
1 | /** |
CSS
小小紀錄一下這次CSS遇到的狀況:
使用BEM命名規則
各種變數跟樣式命名真的是我很弱的一部份,
除了英文很破沒幾個單字可以拿來命名之外,
就是沒有一個規範可以去遵循,後來從前端電子報中看到這個BEM這個關鍵字,
這種命名方式是遵循Black__Element–Modifier
這樣的方式去命名的,
雖然看起來很長很亂,但其實對健忘的我來說很好找到對應元素,不過block in block的處理及modifier的定義我沒有很充分理解,第一次使用,會再找機會參考別人的做法。
select變更樣式
HTML的原生select修改樣式成背景透明後,在手機上的小箭頭居然會不見!background-color: rgba(255, 255, 255, 0)
原本想說使用圖片來替代,後來因為解析度的關係(箭頭會看起來糊糊的),
在select旁邊寫了一個svg的小箭頭來換頂替。1
2
3<svg class="content__select--arrow">
<polygon fill="#42ab9e" points="5,10 0,0 10,0"></polygon>
</svg>
且為了安全起見,也還是把select的圖標隱藏了-webkit-appearance: none;
然後這個我根本沒有在管瀏覽器兼容性啦XD!
總結
寫程式這條路一直到現在都還是自學的狀態,
前端的HTML/CSS/JavaScript,後端JAVA/PHP,
就是自己一直查一直找,很多東西能做出來,但總覺得底氣不足…
這就造成了很多時候基本功不足,也不能了解問題發生的原因,
常常遇到了問題就去google找答案,而解法百百款,總有些看不懂的好解答。
這次找了幾門線上課,打算按部就班的來重打基礎,
從JavaScript開始(六角學院)、(克服JS的奇怪部分),
開始看了之後有很多”啊哈,原來如此“的感覺,
六角學院的老師的講解很清楚,觀念都有清楚帶到,
克服JS的奇怪部分還沒看完,不過他說話的速度滿不錯的也可當練習英文聽力..XD
目前想把javascript搞清楚,
然後嘗試學習後端node.js的部分..再來看前端的各種框架囧
雖然所學所會的於目前工作上沒用到幾個,
但還是要持續加強自己的能力,我想總有一天會用上的…