blog的製作總結
瑣碎的話
這兩天剛寫完所有頁面與功能,回頭再看看,有意思的一點是,每次寫代碼都像是輪迴的過程。
我上學那會兒經常會遇到一些生活、學習上的看似棘手的問題,那時我總是在舉步維艱時強迫自己認爲能找到出路。久而久之,自己也產生了這樣一種思維模式,事情總是可以找到答案的。
爲了能跳槽找到自己喜歡的計算機工作,這一段時間內主要在學習時間前端知識,寫了幾個自己覺得挺有趣的頁面,在這個過程中,我又感覺到寫代碼也與之前解決問題的模式相似,每一次完成一個完整的東西,都形成了一種特定思維模式的一小部分,也許這就是寫代碼的樂趣。
爲什麼寫
寫個人博客,主要是因爲很多幼稚的想法難以登堂入室,不如自建網站暢所欲言。次要原因是自己喜歡造輪造車,認爲純手工纔有樂趣,也是鍛鍊。而且不用像技術博客那樣刻板,總是以源碼的形式呈現,我覺得技術始終是一個工具,自己用開心就好,就像這個博客,我使用批處理去生成html,雖然很過時,但是我覺得很有趣。
博客的結構
架設博客初始,我計劃的是採用hexo框架,後來我粗略計算了一下,使用hexo要先用npm下載程序,寫博客,然後在命令行用hexo發佈。如果我使用git push,只需有一個網頁就可以。於是決定自己寫靜態博客,自己發佈,自己git push。
發表新文章
因爲我習慣用Typora這個markDown格式軟件寫文字,恰好其又有導出html功能。我的構想是,用這個軟件寫好一篇博文,導出成html文件,將html文件放到具體的文件夾內,編寫一個nodejs模塊,檢測到新文件的產生,自動生成一個博文頁面。
在寫好前端頁面後,我發現,用nodejs去監控實在是太麻煩了,我想了想,決定用最原始的辦法,使用windows自帶的功能批處理去完成新文章頁面的生成。
:: 根據最新文檔,自動生成html
chcp 65001
@echo off
set memo=%1
if {%1}=={} set memo=文章忘寫概述標題了
FOR /F %%I IN ('DIR /B /OD /TC list-img') DO set img=%%I
FOR /F %%I IN ('DIR /B /OD /TC blog') DO set file=%%I
(
echo=
echo ^<!-----------------item-----------------^>
echo=
echo ^<div class='divider'^>^</div^>
echo=
echo ^<a href='javascript:makeRequest^("./blog/%file%",1^)'^>
echo ^<div class='item'^>
echo=
echo ^<div class='left-box'^>
echo ^<div class='item-img'^>
echo ^<img src='list-img/%img%'^>
echo ^</div^>
echo ^</div^>
echo=
echo ^<div class='right-box'^>
echo ^<div class='item-title'^>
FOR /F "tokens=2 delims=</h1>" %%I IN ('findstr /i /r "<body><h1>.*</h1>" .\blog\%file%') DO echo %%I
echo ^</div^>
echo ^<div class='item-date'^>
echo %date:~0,4%-%date:~5,2%-%date:~9,2%
echo ^</div^>
echo ^<div class='item-summary'^>
echo %memo%
echo ^</div^>
echo ^</div^>
echo=
echo ^</div^>
echo ^</a^>
)>>list.html
這個批處理的主要作用是,當我將生成的html放到blog文件夾內,執行批處理,查詢到blog文件夾內最新的一個文件,讀取文件名、<body><h1>
和</h1>
之間的標題、當日的時間,追加寫入到list.html(這是所有博文的列表頁面)。這樣一來,每次寫好博文,生成html,執行批處理後,就在首頁的列表加入了最新的博文,完成了導航。
前端
前端頁面採用的是ajax整站無刷新訪問,主要有兩個技術細節:
pushState + onpopstate的應用
採用ajax訪問是沒有歷史記錄的,這意味着無法通過前進、後退按鈕來導航頁面。以前的解決方法是修改讀取location.href
的#,因爲錨點的變化會產生歷史記錄。HTML5的方法是pushState,這是改變歷史記錄與location.href
的API,而onpopstate是監控歷史記錄改變的API,二者配合,就可以使得ajax操作與普通頁面訪問的行爲模式一樣,不影響體驗。
而且這兩個API使用非常簡單,都只有一行代碼。
ajaxRequest(url){
ajax(url);
history.pushState(null, null, url);
}
window.onpopstate = function(event) {
makeRequest(location.pathname);
};
頁面切換間的動畫
在點擊任意一個頁面後,之前的頁面進行一段隱去的效果,然後新的頁面讀取完成時,再進行顯示的效果。
動畫都很簡單,當ajax讀取完成後,在新頁面的CSS樣式里加上一個含animation的class,比如:
document.getElementById('list').classList.add ('animation','fadeInUp');
.animation {
animation-duration: 0.25s;
transition-timing-function: ease-in;
animation-fill-mode: both;
}
.fadeInUp {
animation-name: fadeInUp;
}
@keyframes fadeInUp {
0% {
opacity: 0;
transform: translate3d(0, 100%, 0);
}
100% {
opacity: 1;
transform: none;
}
}
這樣新頁面載入完成時,就會先由透明度opacity:0
漸變爲1
,同時從頁面下方飛入到自己的位置。
同理,離開頁面時的漸隱效果也是加入animation的樣式,需要注意的是,要用js的setTimeout
加一個頁面的延時,這個時長與漸隱動畫的時長相同,用來完成整個漸隱效果後,再執行新頁面的載入。
遇到的問題
前進、後退時滾動條的位置問題
由於不同頁面間的訪問是整體連貫的動畫效果,在使用後退或前進按鈕導航頁面時,會出現滾動條猛的定位在一個不同的位置,導致頁面平滑滾動失效。上網查了一翻,是因爲瀏覽器的history
會記錄每個頁面滾動條的位置信息,而且html5新的API,pushState與replaceState都無法操作位置信息。多次嘗試後,使用如下代碼,屏蔽history
的自動滾動。
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
批處理中文亂碼
批處理按理來講需要以ANSI格式存儲,這樣在CMD內才能正確顯示中文,但這樣去讀取utf8編碼的網頁會出現中文亂碼。百般嘗試,最終將bat文件與CMD的文字編碼都改爲utf8格式。這樣既能讀取utf8的內容,同時也能生成含有中文的網頁。
需要注意的一點是,Unix與windows/dos格式的文件會因爲回車符號的不同導致批處理運行時出錯,一定要看清編碼格式,這樣就不會出現中文亂碼了。
總結
寫代碼總是會遇到各種意外的想不通的問題,一般情況下都是細小的不經意的錯誤導致的,只要認真排查,一定可以找到癥結所在。