〖網頁挑戰〗 Space Tourism

閱讀時間約 13 分鐘
Space Tourism

Space Tourism

這次寫的是 Frontend Mentor 挑戰的太空旅遊介紹的網站,因為本身對太空很有興趣,高中還一度夢想成為太空人(?),所以看到這個挑戰的時候就很想作,當初作了一個星期,首頁都沒辦法完成,那時候對 flexbox、grid 的樣式寫法超不熟,用 position 也是作的很落漆,於是中間就先暫停,想說先把熟練度練高一點再來挑戰。

就這樣過了一年。

沒錯,一年再次開啟資料夾的時候,其實很害怕會不會我還是一樣,是那個首頁都作不出來的自己,然後我用三天就作完了...自己嚇到自己,還一度懷疑:真的嗎?(摸臉)

當下感受到自己的進步,真的很感動(擦淚)

這次挑戰內容是:

  • 響應式頁面
  • 指定的互動樣式及動作: hover、開關導覽列
  • 查看每個頁面中的資訊卡片,使用者能夠切換並查看另一張卡片的資訊

HTML 與 CSS

多頁式網站基本上就是 header 頁首、footer 頁尾一樣,中間內容不同,所以這裡只寫出內容的架構:

首頁

首頁

首頁

因為我是從手機版開始作,也就是 Mobile first design,再來是平板,最後才是電腦版,所以一開始的 HTML 內容順序就以手機頁面為主。

<main>
<div>
<!-- 標題 title -->
<!-- 內容 content -->
</div>

<div>
<!-- 按鈕 explore-btn -->
</div>
</main>

這裡想在電腦版的時候用 grid 來排版:

main {
display: grid;
grid-template-columns: repeat(2, 50%); /* 分成兩行 各佔 50% */
grid-template-rows: repeat(2, 1fr);/* 再分成兩列 */
}
.title {
grid-column: 1 / 2; /* SPACE 標題佔第一行 第一列 */
grid-row: 1 / 2;
}
.content {
grid-column: 1 / 2; /* 內容文字佔第一行 第二列 */
grid-row: 2 / 3;
align-self: start; /* 靠左對齊 */
}
.explore-btn {
grid-column: 2 / 3; /* 按鈕佔第二行 佔整列 */
grid-row: 1 / 3;
}


行星介紹

注意圖片的位置以及行星資料的位置變化

注意圖片的位置以及行星資料的位置變化

這裡稍微有點複雜,HTML 內容順序依然按照手機版
平板的順序沒有什麼變化,
只是 MOON 內容文字下方還有兩個行星資料:
一個是距離 OOOKM 和天數 OODAYS,原本是直向排列用 flex 變成橫向排列。
電腦版用 grid 來排版,讓行星圖片靠左;切換按鈕、行星介紹與資料靠右邊。

<article>
<div>
<!-- 行星圖片 data-img -->
</div>

<div>
<!-- 切換列表 subnav-list -->
</div>

<div>
<!-- 行星介紹 data-description​ -->
<div>
<!-- 行星資料 planet-data --> ​​
</div>​​
</div>
</article>
.planet-data {
display: flex; /* 平板改成橫向排列 */
justify-content: center;
}
article {
display: grid; /* 電腦版改成 grid 排版 */
grid-template-columns: repeat(2, 50%); /* 分成兩行 各佔 50% */
grid-template-rows: repeat(2, minmax(1px, auto)); /* 分成兩列 大小依內容 */
}


太空組員介紹

這個大叔原本在手機版上方,平板的部分跑到了下方,電腦版又跑去右邊

這個大叔原本在手機版上方,平板的部分跑到了下方,電腦版又跑去右邊

這裡看到平板的順序跟手機版幾乎相反,所以要用 column reverse 來反轉方向
電腦版就改成 grid 就可以完成排版了。

<article>
<div>
<!-- 組員圖片 data-img -->
</div>

<div>
<!-- 切換列表 subnav-list -->
</div>

<div>
<!-- 組員介紹 data-description​ -->
</div>
</article>
article {
display: flex; /* 平板使用 flex 排序 */
flex-direction: column-reverse; /* 上下反轉順序 */
}
article {
display: grid; /* 電腦版使用 grid 排版 */
grid-template-columns: 60% 40%;
grid-template-rows: repeat(2, minmax(1px, auto));
}


技術介紹

三個頁面的寫法都不會離開 flex 及 grid

三個頁面的寫法都不會離開 flex 及 grid

這跟首頁一樣簡單,在電腦版時使用 row-reverse 即可。

<div>
<!-- 器械圖片 data-img -->
</div>

<div>
<!-- 切換列表 subnav-list -->
</div>

<div>
<!-- 技術介紹​ data-description -->
</div>
article {
display: flex; /* 只要在電腦版使用 flex 排序 */
flex-direction: row-reverse; /* 左右反轉順序 */
}
.subnav-list {
flex-direction: column; /* 將切換列表方向改成直向 */
order: 1; /* 將順序排在最左邊 */
}

這邊要特別說明 order,這裡的 1 表示要將元素排在最後一個,但是因為在父元素使用了 row-reverse 左右反轉,所以原本排在最後的切換列表,反轉後變成在第一個位置。
如果今天沒有反轉順序的話,order 要寫成 -1



JavaScript 使用 JSON 資料來修改 HTML 內容

切換資料

切換資料

除了首頁以外,現在我們有三個頁面:行星、組員、技術介紹頁,
其中的切換列表讓使用者點擊後,可以切換介紹資料,
挑戰中提供了所有列表的 HTML,這樣寫就會有 11 頁..

看到就心累..

還好挑戰也提供了 JSON 檔案,所有的資料都在裡面,只要在抓資料的時候,知道使用者點擊的是哪個列表即可。

在 HTML 中的列表中寫入 data 資料

在標籤中寫入 data-* 的資料,之後在 JavaScript 用 dataset 取得資料名稱就可以了。

<div class="subnav-list">
<!-- 行星切換列表 -->
<span
class="subnav-item active-destinations"
data-group="destinations"
data-name="Moon">Moon</span>
<!-- 以下類推... -->
</div>
<div class="subnav-list">
<!-- 組員切換列表 -->
<span
class="subnav-item dot active-crew"
data-group="crew"
data-name="Douglas Hurley"></span>
<!-- 以下類推... -->
</div>
<div class="subnav-list">
<!-- 技術切換列表 -->
<span
class="subnav-item active-technology"
data-group="technology"
data-name="Launch vehicle">1</span>
<!-- 以下類推... -->
</div>


在 subnavList 上掛載監聽器 讓使用者點擊後可以取得 HTML 的 data 資料

首頁裡沒有切換列表 subnavList,所以如果在首頁時,後台就會報錯,因為它找不到 subnavList,監聽器不知道掛哪。

所以在​ subnavList 後方加上了問號 optional chaining,表示當值是 null 或 undefined 時,就不會去掛載監聽器。

const subnavList = document.querySelector('.subnav-list')
const subnavItems = document.querySelectorAll('.subnav-item')

subnavList?.addEventListener('click', (e) => {
const item = e.target.closest('.subnav-item') // 找到點擊的列表item
if (!item) return // 如果不是點在列表 item上 則退出函式

const name = item.dataset.name //​ 取得 HTML 的 data資料
const group = item.dataset.group

getData(group, name) // 調用 getData函式 取得 JSON資料

subnavItems.forEach((i) => i.classList.remove(`active-${group}`))
// 迭代列表 移除 active樣式

item.classList.add(`active-${group}`) // 將 active樣式加入點擊的 item中
})


非同步取得 JSON 資料

剛剛知道了使用者點擊的列表是哪個,所以現在要來抓資料:

const BASE_URL = './jsons/data.json'

const getData = async function (dataGroup, dataName) {
try {
const res = await fetch(BASE_URL)
if (!res.ok) throw new Error('Something went wrong')

const data = await res.json()
if (!data) throw new Error('Data not found')

const group = data[dataGroup]
// 依列表名稱找到 JSON 中的資料們
const activeData = group.filter((g) => g.name === dataName)
// 再從剛剛的資料們中 依使用者點擊的 item名稱 取得資料

// 底下:如果列表名稱等於OOO 就調用專屬的 display函式​ 更新 HTML內容
if (dataGroup === 'destinations') displayDestination(...activeData)
if (dataGroup === 'crew') displayCrew(...activeData)
if (dataGroup === 'technology') dispalyTechnology(...activeData)
} catch (err) {
console.error(err)
}
}


更新 HTML 內容文字

使用資料將 HTML 寫出來,再去更新 HTML 內容:

const dataImg = document.querySelector('.data-img')
const dataDescription = document.querySelector('.data-description')

const replaceData = function (img, content) {
dataImg.innerHTML = img
dataDescription.innerHTML = content
}


const displayDestination = function (data) {
// 將 HTML內容寫出來​
const img = `<img src="${data.images.png}" alt="${data.name}">`

const content = `
<h1 class="subtitle upper">${data.name}</h1>
<p class="content barlow purple">${data.description}</p>
<div class="planet-data upper">
<div class="distance">
<p class="subheading barlow purple">Avg. distance</p>
<p class="subcontent">${data.distance}</p>
</div>
<div class="travel">
<p class="subheading barlow purple">Est. travel time</p>
<p class="subcontent">${data.travel}</p>
</div>
</div>
`

replaceData(img, content) // 調用 replaceData函式 替換 HTML內容文字
}

這樣就完成了。



完成頁面 ▶ Space Tourism

Solution ▶ Frontend Mentor - Space Tourism

avatar-img
5會員
14內容數
本來是理科生,在被物理放棄之後成為了文科生,有時理性思考,偶爾卻會脫口出感性的字句;喜歡打字的聲音,以生活為靈感寫下過去、現在與未來。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
碎碎念 的其他內容
這次的 Frontend Mentor challenge 是新手村最後一個挑戰 ▶ Intro component with sign up form 網頁,使用 jQuery validation plugin。
開始接觸網頁開發後,發現自己缺乏實作經驗, 於是老師推了 Frontend Mentor challenge , 免費的通常是獨立頁面,花錢則是可以挑戰多頁式網站, 初學還沒學到 javascript 或 API 也沒關係, 新手也有提供 HTML/CSS 的練習。 很適合用來增加自己寫網頁的經驗,
這次的 Frontend Mentor challenge 是新手村最後一個挑戰 ▶ Intro component with sign up form 網頁,使用 jQuery validation plugin。
開始接觸網頁開發後,發現自己缺乏實作經驗, 於是老師推了 Frontend Mentor challenge , 免費的通常是獨立頁面,花錢則是可以挑戰多頁式網站, 初學還沒學到 javascript 或 API 也沒關係, 新手也有提供 HTML/CSS 的練習。 很適合用來增加自己寫網頁的經驗,
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
石頭手遊代儲網的專業服務 專業遊戲代儲團隊 石頭手遊代儲網擁有一支專業的遊戲代儲團隊,這些成員都是經驗豐富、技術優秀的遊戲玩家。 他們對各種遊戲的玩法和充值機制非常了解,能夠提供專業的遊戲代儲建議和服務。 安全可靠的交易保障 在石頭手遊代儲網,交易安全始終是首要考慮的問題。 平台採用了先進的
Thumbnail
最簡單、最易上手的賺錢網路副業!2023 年即將結束,如果你到現在還沒有任何副業,未免有點可惜!如果你還沒有在線上賺到你的第一個 1 美元,那麼現在就是開始的時候了。 如果這是你一直想做的事情,下文將討論 5 種非常容易啟動的副業,絕對可以在接下來的 7 天內賺到你的第一筆錢。
Thumbnail
最近有專案需求要在 Web 上進行一個掃描條碼辨識的動作,做了一些功課,有 Open Source 方案跟商業解決方案,整理起來分享給大家。
Thumbnail
在紀錄片《PO到死》,描繪了一個普通打工者因登山社群的影響,轉變成勇於挑戰並鼓舞他人的風雲人物。然而,隨著挑戰的失敗與壓力,似乎漸漸失衡了。我將分享對挑戰意義的反思,並如何擁抱恐懼和風險。
Thumbnail
台灣前十大熱門ETF排名,有七檔是債券型ETF,這可能跌破許多人的眼鏡,而每一檔能躍上檯面的債券ETF,都有他獨到之處。當然,最大的不一定是最好的,文末有《SK白話財經》主講人的偏好排序,幫助您了解如何依照自身現金流、收益率、配息率需求挑選。
Thumbnail
華爾街的投資大佬風格迥異,但每個人出人頭地的大師都有自己的獨門秘籍。有人張揚肆意能夠在逆市中創造一個個傲人的成績;有人低調內斂無論是在牛、熊市依然能夠屹立不倒,奠定自己在市場上的傳奇;也有人行事張揚,投資風格十分激進,卻能夠憑藉敏銳洞察力在市場中“狂壓”被“封神”
Thumbnail
天漢生活網是什麼呢?是取得生活市集網購折扣的最好用網購省錢APP! 新冠疫情影響人們生活甚巨,除了無法再像以前一樣群聚再一起聊天、吃飯,更重要的是工作和生活模式都是天翻地覆的轉變,工作改為運用更多的視訊溝通,以前很少甚至從來沒有在網路上購物的人,現在都開始在各大電商平台購物了! 網路時代是人們溝通社
Thumbnail
亞洲最具影響力的傳播權威獎項《Campaign Asia》於2020年末公布亞太區具優秀品牌溝通力的最佳代理商,愛德曼公關榮獲「亞太地區年度最佳公關企業網」大獎(Asia-Pacific PR Network of the Year)!
Thumbnail
很高興看到你終於下定決心要透過線上預約系統收單,簡化人力及工作流程,聰明管理客戶預約!當然,你在做功課時,可能會找到 SimplyBook.me 或是其他類似服務,而做為一站式線上預約系統,經營者不只能透過 SimplyBook.me 打造專屬預約網站,如果你已經有架設官網(無論是外包,或是透過 W
Thumbnail
先前 SimplyBook.me 有介紹過如何利用 API 客製功能啟用,在 WordPress 加入 SimplyBook.me 預約外掛,而今天要介紹的是更簡單的方式,來幫助商家快速的在 WordPress 加入線上預約外掛! 在官網或 WordPress / Wix 加入預約外掛的好處是?
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
石頭手遊代儲網的專業服務 專業遊戲代儲團隊 石頭手遊代儲網擁有一支專業的遊戲代儲團隊,這些成員都是經驗豐富、技術優秀的遊戲玩家。 他們對各種遊戲的玩法和充值機制非常了解,能夠提供專業的遊戲代儲建議和服務。 安全可靠的交易保障 在石頭手遊代儲網,交易安全始終是首要考慮的問題。 平台採用了先進的
Thumbnail
最簡單、最易上手的賺錢網路副業!2023 年即將結束,如果你到現在還沒有任何副業,未免有點可惜!如果你還沒有在線上賺到你的第一個 1 美元,那麼現在就是開始的時候了。 如果這是你一直想做的事情,下文將討論 5 種非常容易啟動的副業,絕對可以在接下來的 7 天內賺到你的第一筆錢。
Thumbnail
最近有專案需求要在 Web 上進行一個掃描條碼辨識的動作,做了一些功課,有 Open Source 方案跟商業解決方案,整理起來分享給大家。
Thumbnail
在紀錄片《PO到死》,描繪了一個普通打工者因登山社群的影響,轉變成勇於挑戰並鼓舞他人的風雲人物。然而,隨著挑戰的失敗與壓力,似乎漸漸失衡了。我將分享對挑戰意義的反思,並如何擁抱恐懼和風險。
Thumbnail
台灣前十大熱門ETF排名,有七檔是債券型ETF,這可能跌破許多人的眼鏡,而每一檔能躍上檯面的債券ETF,都有他獨到之處。當然,最大的不一定是最好的,文末有《SK白話財經》主講人的偏好排序,幫助您了解如何依照自身現金流、收益率、配息率需求挑選。
Thumbnail
華爾街的投資大佬風格迥異,但每個人出人頭地的大師都有自己的獨門秘籍。有人張揚肆意能夠在逆市中創造一個個傲人的成績;有人低調內斂無論是在牛、熊市依然能夠屹立不倒,奠定自己在市場上的傳奇;也有人行事張揚,投資風格十分激進,卻能夠憑藉敏銳洞察力在市場中“狂壓”被“封神”
Thumbnail
天漢生活網是什麼呢?是取得生活市集網購折扣的最好用網購省錢APP! 新冠疫情影響人們生活甚巨,除了無法再像以前一樣群聚再一起聊天、吃飯,更重要的是工作和生活模式都是天翻地覆的轉變,工作改為運用更多的視訊溝通,以前很少甚至從來沒有在網路上購物的人,現在都開始在各大電商平台購物了! 網路時代是人們溝通社
Thumbnail
亞洲最具影響力的傳播權威獎項《Campaign Asia》於2020年末公布亞太區具優秀品牌溝通力的最佳代理商,愛德曼公關榮獲「亞太地區年度最佳公關企業網」大獎(Asia-Pacific PR Network of the Year)!
Thumbnail
很高興看到你終於下定決心要透過線上預約系統收單,簡化人力及工作流程,聰明管理客戶預約!當然,你在做功課時,可能會找到 SimplyBook.me 或是其他類似服務,而做為一站式線上預約系統,經營者不只能透過 SimplyBook.me 打造專屬預約網站,如果你已經有架設官網(無論是外包,或是透過 W
Thumbnail
先前 SimplyBook.me 有介紹過如何利用 API 客製功能啟用,在 WordPress 加入 SimplyBook.me 預約外掛,而今天要介紹的是更簡單的方式,來幫助商家快速的在 WordPress 加入線上預約外掛! 在官網或 WordPress / Wix 加入預約外掛的好處是?