從 1 開始的多頁式網站

更新於 發佈於 閱讀時間約 14 分鐘
多頁式網站

多頁式網站


從上次作完喵喵健身教練網頁後,覺得自己以前作的個人簡歷網站實在是太醜了,而且當初為了搶快,直接套用 Bootstrap 版型,根本不用寫 JavaScript(燦笑)

所以這次決定把網站重寫,就算是從 1 開始吧,1-10 分作到 8 分就好,不然完美主義真的會搞死自己,那道光很快就來了(?)

HTML 架構

多頁式網站多半是 header 跟 footer 會是一樣的,這樣使用者在瀏覽時,不會一下要去左側找導覽列、一下又去上方點選導覽列,所以只要替換中間的 main 內容就好。

<header>

<main>

<footer>

首頁的內容

接著就是 main 的內容了,首頁我想讓使用者直接看到我的作品集,並且用卡片形式:包含照片、標題、使用的工具、描述、 gitHub repo 的連結,而這些資料會寫成 JSON 檔案,最後用 JavaScript 把資料轉換成 DOM 節點,讓瀏覽器渲染。

<main>
<div class="card">
</main>

關於我的內容

關於我是最簡單的,只要放一張照片、簡歷、社群媒體的連結即可。

<main>
<section class="profile-section">
<div class="profile-avatar">
<div class="profile-content">
</section>

<section class="contact-section">
<a class="instagram">
</section>
</main>

經歷與技能的內容

經歷就用條列式的方式,技能除了條列出來外,還要有百分比表示 level,看起來比較能知道技能的程度。

<main>
<section class="experience">
<h2 class="title">
<ul class="job">
</section>

<section class="skills">
<h2 class="title">
<ul class="skill-list">
</section>

<section class="other-activities">
<h2 class="title">
<ul class="activities-list">
</section>
</main>

我真棒(雙手交叉拍拍自己肩膀)。



CSS 樣式

導覽列推出式動畫

導覽列往下推擠

導覽列往下推擠

導覽列覆蓋在元素上方

導覽列覆蓋在元素上方


上一次是作淡出淡入動畫,這樣導覽列可以想像成 photoshop 的圖層,順序會蓋在頁面上面,當淡出時,不會推擠到下方的圖層。(左圖)

這次想改成在同一個圖層上,導覽列下拉時,會把其他元素往下推擠。(上圖)

這裡依舊使用 animation 與 keyframes 來做出效果,關鍵影格在初始設定高度 height 及透明度 opacity 為 0,動畫結束時將透明度 opacity 為 1,將高度設定為導覽列的高度..要怎麼知道?用 google DevTools 去看就可以了,這部分也是未來可以優化的地方

反之,如果是要將導覽列收起,就設定相反的數值即可。

@keyframes pushin {
0% {
height: 0;
opacity: 0;
}
100% {
height: 170px;
opacity: 1;
}
}

再來將 animation 設定效果呈現的秒數。

.push-in {
animation: pushin 0.4s;
}

最後去 JavaScript 掛載事件監聽器,用來觸發設定好的效果。

const toggler = document.querySelector('.toggler')
const collapse = document.querySelector('#navbarCollapse')
let isShow = false // 先設定導覽列是隱藏的

toggler.addEventListener('click', function (e) {
const btn = e.target.closest('.toggler-icon')
if (!btn) return
toggleNavigation()
})

const toggleNavigation = function () {
if (isShow) {
// 當導覽列正在顯示時 加入 push-out 並移除 push-in 動畫
collapse.classList.add('push-out')
collapse.classList.remove('push-in')
collapse.style.height = '0' // 高度設定回 0
} else {
// 當導覽列是隱藏時 加入 push-in 並移除 push-out 動畫
collapse.classList.add('push-in')
collapse.classList.remove('push-out')
collapse.style.height = '100%' // 高度設定 100%
}
isShow = !isShow // 動作結束時 將 isShow 狀態反轉
}

技能百分比圖示

百分比樣式

百分比樣式

HTML 中將條列式的技能列出,除了技能名稱外,另外包一個 span 標籤在裡面,用來設定百分比樣式。

<li class="skill-item">
<span>技能名稱</span>

<span class="level-percentage"> <!-- 設定百分比樣式 -->
<span class="percentage""></span>
</span>
</li>

css 部分,先將 skill-item 設定為 grid,讓兩個子元素:技能名稱、百分比樣式可以排排站,為什麼不用 flex 的原因是,在排列的時候兩個子元素會一直緊緊相依,視覺上就沒有對齊的感覺。(下圖)

flex 與 grid 差異

flex 與 grid 差異


.skill-item {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 1fr;
margin: 0.5rem;
align-items: center;
}

.skill-item span {
flex-basis: 20%;
}


flex 就像是把兩個東西都放在同一層格子中,如果要跟上一層格子對齊,需要耐心調整,並且只要寬度不同時,就有可能無法對齊。

grid 則是把兩個東西各自放在一層兩格的櫃子,上下要對齊時,只要把東西同時置中或靠左靠右,而不用去考慮到另一個東西的位置,調整就不會太吃力。


再來設定百分比,在 HTML 中,我把百分比寫成一個父元素 level-percentage 跟一個子元素 percentage,父元素用來寫外框,也就是百分比的黑色部分,子元素則是用來寫技能的百分比%樣式。

.level-percentage {
position: relative; /* 父元素的位置設定 relative 讓子元素可以依賴父元素的位置*/
z-index: 10;
display: inline-block;
width: 100%; /* 寬度就是那格 grid 格子的寬度 */
height: 0.8rem;
border: 2px solid #434343;
border-radius: 10px;
background-color: #434343;
}

.percentage {
position: absolute; /* 讓子元素可以依賴父元素的位置去做調整 */
z-index: 20; /* 子元素的 z 軸位置較高 才能蓋在父元素上方 */
left: 0;
top: 50%; /* 垂直置中 */
transform: translateY(-50%); /* 垂直置中 */
/* width: ; 寬度之後用 JavaScript 來設定*/
height: 0.6rem;
border-radius: inherit;
background-color: #eeeeee;
}

這裡就完成了,接著就要用 JavaScript 來抓資料。



JavaScript 抓 JSON 資料

抓資料渲染畫面

抓資料渲染畫面

不想把 HTML 寫的太長,所以想把資料寫成 JSON 檔案,未來資料有更動時,就不用逐一調整,還有可能調錯的風險存在。

這次先把作品集跟技能的資料寫成 JSON 檔案:

{
"portfolios": [
{
"title": "作品標題",
"skills": ["使用技能1", "技能2", "技能3"],
"content_zh": "中文介紹",
"content_en": "英文介紹",
"live_url": "發佈的網址",
"image_url": "圖片路徑",
"repo_url": "git 倉庫網址",
"copyright": "版權聲明"
}
]
}

再來就是抓資料,因為 JSON 檔中有幾個 key name 包含下底線,所以先把它們轉成駝峰式寫法,例如:repo_url 改成 repoUrl,就不會在使用資料時,還要回去看名稱是哪種寫法。

const renameKeys = function (obj) {
const keyValues = Object.keys(obj).map((key) => {
const index = key.indexOf('_') // 取得下底線在名稱中的位置
const newKey =index > 1 // 如果下底線不在第一個字母時
? `${key.slice(0, index)}${key
.slice(index + 1)[0]
.toUpperCase()}${key.slice(index + 2)}` // 移除下底線後將後方的字母改成大寫
: key // 反之 下底線在第一個字母時就不用轉換
return { [newKey]: obj[key] }
})
return Object.assign({}, ...keyValues) // 返回新的物件
}

接著使用 fetch 取得資料:

const displaySection = async function (url, callback) {
try {
// ​依 url 取得資料 如果沒有取得資料 就丟出錯誤
const res = await fetch(url)
if (!res.ok) throw new Error('Something went wrong!')

// 將資料解析 如果沒有資料 就丟出錯誤
const data = await res.json()
if (!data) throw new Error('Data not found')

// 將解析的資料傳入函式
callback(data)
} catch (err) {
console.error(err) // 如果有錯誤 就顯示在主控台
}
}

把 callback function 另外寫,將資料改寫成 HTML 模板後,置入 DOM tree:

const portfolioMarkup = function (data) {
const { portfolios } = data // 解構 portfolios
portfolios.forEach(function (portfolio) {
const port = renameKeys(portfolio) // 轉換 key 的名稱

// 寫成 HTML 模板​
const html = `
<div class="card">
<div class="card-img">
<img src="${port.imageUrl}" class="block" alt="${port.title}">
</div>

<div class="card-body">
<p class="card-title">${port.title}</p>
<p class="card-description">${port.contentZh}</p>
</div>

<div class="card-footer">
<p class="card-copyright">${port.copyright}</p>
</div>
</div>
`
// 置入 DOM
portfolioContainer?.insertAdjacentHTML('beforeend', html)
})
}

再來就是調用 displaySection 函式就完成了。



網頁在此:我的個人簡歷。希望大家給我愛心(???)

avatar-img
5會員
14內容數
本來是理科生,在被物理放棄之後成為了文科生,有時理性思考,偶爾卻會脫口出感性的字句;喜歡打字的聲音,以生活為靈感寫下過去、現在與未來。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
碎碎念 的其他內容
一切都從思考作品集要怎麼準備開始,所謂的 one 是起頭難(?),在動手寫 code 之前,總覺得自己做不到,一直在自己煩惱,直到前輩們說:開始做看看吧,一頁式網站也好,不開始做永遠不知道自己哪些知識需要補強。 於是決定先幫我的繆思女神做一個網站,讓她可以介紹自己的工作,再放社群連結
前言: 雖然前面有些定義還沒有完整的解釋,但還是後面再說吧, 誰想一直看理論啊(摔本子)
前言: 前一篇講了 JS 的定義,這裡來談談能用它來做什麼, 希望能限制在 500 字以內(這是我看文章的極限,超過字數就會開始分心(?))
前言: 一直想要把自己的學習筆記整理整理,至少在寫下筆記的時候,也能釐清觀念。 結果拖延到現在,終於要提筆了,不知道能堅持多久(???)。
使用 React 做出一個便條紙的頁面,可以紀錄自己的想法後丟上去。並且讓使用者即使重新整理頁面,也不會遺失資料。
C2 開始終於使用到 visual studio code, 這個階段學到 JavaScript 核心概念、DOM 操作、API 串接、MVC 架構, 每天都在 coding,每週都在追進度, 用壓縮到極致的時間寫完作業, 但跟著課程內容寫程式碼,真的有學到嗎? 有,吧。 畢竟在寫最後的電影清單
一切都從思考作品集要怎麼準備開始,所謂的 one 是起頭難(?),在動手寫 code 之前,總覺得自己做不到,一直在自己煩惱,直到前輩們說:開始做看看吧,一頁式網站也好,不開始做永遠不知道自己哪些知識需要補強。 於是決定先幫我的繆思女神做一個網站,讓她可以介紹自己的工作,再放社群連結
前言: 雖然前面有些定義還沒有完整的解釋,但還是後面再說吧, 誰想一直看理論啊(摔本子)
前言: 前一篇講了 JS 的定義,這裡來談談能用它來做什麼, 希望能限制在 500 字以內(這是我看文章的極限,超過字數就會開始分心(?))
前言: 一直想要把自己的學習筆記整理整理,至少在寫下筆記的時候,也能釐清觀念。 結果拖延到現在,終於要提筆了,不知道能堅持多久(???)。
使用 React 做出一個便條紙的頁面,可以紀錄自己的想法後丟上去。並且讓使用者即使重新整理頁面,也不會遺失資料。
C2 開始終於使用到 visual studio code, 這個階段學到 JavaScript 核心概念、DOM 操作、API 串接、MVC 架構, 每天都在 coding,每週都在追進度, 用壓縮到極致的時間寫完作業, 但跟著課程內容寫程式碼,真的有學到嗎? 有,吧。 畢竟在寫最後的電影清單
你可能也想看
Google News 追蹤
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
不要問我為什麼要重寫自我介紹,因為我也不知道!可能是設計工作有點乏味了,想要透過寫作來找點樂趣。
Thumbnail
第一次發文 |・ω・`)(試探 這個【創作進度】的區塊,預計會是類似週記的東西。
Thumbnail
大家好,好久沒更新,最近教學論命繁忙,這邊有所耽擱,真的抱歉。 最近也有跟設計師在討論要架官網,時間真的是不夠用了,因此方格子這邊我會先暫停一下,架好官網之後會將文章轉移到官網,至於會不會有收費文章,這邊我還再思考當中。 如果想看我最新的貼文,可以轉到我的社群上面去。目前是每周二晚上八點發放貼文
Thumbnail
去年3月搬完家之後,除了想跟想環境熟悉之外,我也想重新認識自己。於是我開始著手整理在疫情期間,隨手寫的童年,回當時的IG限動找感覺。每天起床先對著電腦冥想2小時,再出門工作⋯ 忘記這樣的日子多久了,我開始不再是對著電腦冥想,而是開始打字,打打刪刪⋯電腦的垃圾桶堆滿了我的胡言亂語。 七個月之後,我
Thumbnail
我其實去年就有想弄好個人網站的想法,所以前後找了很多網站希望能夠作為一個發表作品跟心情的場所。可惜很多找到的網站不是只能發圖就是只能發文,或是操作不易,對我來說都不是很好用。現在才來到方格子這裡,這裡的發文主頁清新簡潔也能顯示圖片,操作也簡單,也能夠只更新圖片或是文字,對我來說是比較好用的網站。
Thumbnail
我放棄自架網站的選擇,轉而選擇方格子的原因。同時設定今年的目標,要把自己經營地像企業一樣,設定好年目標、規劃好計畫,提出2024年的三大重點:「整理」、「付出」、「成長」。
Thumbnail
本文章介紹了建立網頁的整個流程,包括設置 Templates, Views, Urls 等步驟。透過這些步驟,大家便能創建一個新的網頁,並成功測試。
IG重新整理了一下,試著做圖文,這篇談分享。
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
不要問我為什麼要重寫自我介紹,因為我也不知道!可能是設計工作有點乏味了,想要透過寫作來找點樂趣。
Thumbnail
第一次發文 |・ω・`)(試探 這個【創作進度】的區塊,預計會是類似週記的東西。
Thumbnail
大家好,好久沒更新,最近教學論命繁忙,這邊有所耽擱,真的抱歉。 最近也有跟設計師在討論要架官網,時間真的是不夠用了,因此方格子這邊我會先暫停一下,架好官網之後會將文章轉移到官網,至於會不會有收費文章,這邊我還再思考當中。 如果想看我最新的貼文,可以轉到我的社群上面去。目前是每周二晚上八點發放貼文
Thumbnail
去年3月搬完家之後,除了想跟想環境熟悉之外,我也想重新認識自己。於是我開始著手整理在疫情期間,隨手寫的童年,回當時的IG限動找感覺。每天起床先對著電腦冥想2小時,再出門工作⋯ 忘記這樣的日子多久了,我開始不再是對著電腦冥想,而是開始打字,打打刪刪⋯電腦的垃圾桶堆滿了我的胡言亂語。 七個月之後,我
Thumbnail
我其實去年就有想弄好個人網站的想法,所以前後找了很多網站希望能夠作為一個發表作品跟心情的場所。可惜很多找到的網站不是只能發圖就是只能發文,或是操作不易,對我來說都不是很好用。現在才來到方格子這裡,這裡的發文主頁清新簡潔也能顯示圖片,操作也簡單,也能夠只更新圖片或是文字,對我來說是比較好用的網站。
Thumbnail
我放棄自架網站的選擇,轉而選擇方格子的原因。同時設定今年的目標,要把自己經營地像企業一樣,設定好年目標、規劃好計畫,提出2024年的三大重點:「整理」、「付出」、「成長」。
Thumbnail
本文章介紹了建立網頁的整個流程,包括設置 Templates, Views, Urls 等步驟。透過這些步驟,大家便能創建一個新的網頁,並成功測試。
IG重新整理了一下,試著做圖文,這篇談分享。