Skip to content

CJ-Yang0225/CJ-NewsApp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CJ-NewsApp

有時想看些新聞、時事,但不想被單一媒體的觀點所侷限,所以自製一個新聞的 Web App,藉由串接集成的 Taiwan News API,獲取各方新聞媒體的報導。

Client 連結

原生 Vanilla.js🤣 撰寫前端 Client App,受到 React.js 和 Vue.js 的啟發,嘗試運用框架的核心理念,自訂 Webpack 環境,打造出專屬的專案架構。一方面可強化原生控制資料、事件、畫面三者的能力,另一方面能反思框架存在的意義、想解決什麼問題呢?

Features & Technologies

首頁(index.html)

  • 使用自己簡單封裝的 XMLHttpRequest 工具,發送 AJAX GET 請求,獲取類別(top, entertainment, sports, business, health, technology, science)對應的新聞,預設每頁為 10 筆報導(會根據裝置尺寸調整)。

  • 已獲取的資料會利用記憶體快取(memory cache)並附加一個能判斷資料是否過期的 timestamp(類似 Cookie 的 Max-Age),再將這個加工過的資料儲存至 localStorage,設定 5 分鐘後過期,需要重新請求資料,以確保新聞的即時性。(程式碼 L67~L127

  • 標題區塊 Header 根據不同頁面顯示相應的訊息和連結。

  • 點擊上方導覽列 Navbar,更換新聞的類別,並即時更新 URL Search parameters(?category=technology),操控瀏覽器歷史紀錄(history.pushState)和監聽 popstate 事件。

  • 點擊新聞卡 NewsCard 開啟有獨特 name 的分頁,讓點擊相同新聞卡時跳至同樣的分頁,不會重複開啟同一則新聞;另外用滑鼠中鍵或是右鍵(context menu)的「在新分頁中開啟連結」則可重複開啟。

  • 啟用圖片 lazy loading 以及增設圖片 load 事件,首次載入完成時觸發 fade-in 動畫;若瀏覽器有啟用快取(cache)機制則用 HTMLImageElement.complete 屬性判斷載入完成的時機來觸發 fade-in 動畫。

  • 行動裝置(Mobile device)裝置可透過左滑、右滑的手勢切換新聞類別。(程式碼

  • 當滾動至底部時觸發 loadMoreNews() 載入更多新聞,如果還有資料就加入提示 PullHint「載入更多新聞中」,更新頁數並填充下 10 筆報導。

  • 可對想追蹤、收藏的新聞報導點擊書籤圖示,使用 localStorage 儲存已收藏的新聞資料陣列,實現跨頁攜帶資料,加到書籤收藏頁(collection.html)

  • 固定在左下角的部件組 Widgets,hover 後會展開內部組件,其一可進行主題模式(theme mode)的切換(預設採用使用者偏好的系統設定 prefers-color-scheme);另一點擊後回到頁面頂部。

  • 手機、平板與電腦的 RWD(Responsive Web Design)。

書籤收藏頁(collections.html)

  • 取出 localStorage 的新聞資料陣列,展示出已收藏的全部新聞報導。

  • 點擊新聞卡 NewsCard 開啟有獨特 name 的分頁,讓點擊相同新聞卡時跳至同樣的分頁,不會重複開啟同一則新聞;另外用滑鼠中鍵或是右鍵(context menu)的「在新分頁中開啟連結」則可重複開啟。

  • 可切換成管理模式進行整個 localStorage 新聞資料陣列的操作。

  • 固定在左下角的部件組 Widgets,hover 後會展開內部組件,其一可進行主題模式(theme mode)的切換(預設採用使用者偏好的系統設定 prefers-color-scheme);其二點擊後回到頁面頂部。

  • 手機、平板與電腦的 RWD(Responsive Web Design)。

實用的工具函式們(utils)

  • 使用 RegExp 注入資料到類 html 格式的自訂 .tpl 檔案。(injectTpl()

  • 幫助整理 object 的結構、URL 的參數、form data 的格式等等。(程式碼 L13~L65

  • 操作卷軸和 DOM 相關屬性、新增 Web Components。(程式碼

  • 建立事件管理用的 class、實作 debounce 和 throttle。(程式碼

Module Bundler / Dependencies

Proxy Server 連結

由於 News API 需要驗證 API Key 才能使用,為避免 API Key 在前端洩漏以及方便後續功能的擴充,所以用 Koa2 架設一個 Proxy Server,簡單路由後使用 Axios 帶上 API Key 到 Request Header 中,然後對目標 API 發送請求,最後獲得所需的新聞資料並回傳給前端。

Technologies & Features

  • 環境變數(Environment variables)

    使用 dotenv 讀取 .env 和 .env.local 的環境變數。

    • .env: 新增檔案命名為 .env,裡面放上本地開發用伺服器的 HOSTNAME 和 PORT。

      HOSTNAME=127.0.0.1
      PORT=8080
      
    • .env.local: 放上 Taiwan News API Request Header 之 X-Api-Key 要驗的 NEWS_API_KEY,可放多支 key 增加請求次數(要用 NEWS_API_KEY 開頭)。

      NEWS_API_KEY0=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      NEWS_API_KEY1=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      NEWS_API_KEY2=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      NEWS_API_KEY3=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      NEWS_API_KEY4=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      
  • Axios 使用

    • 創建 Axios 的實例(instance),設定預設的選項,方便重複使用。
    • 使用實例的 Interceptors,管理 Request 和 Response 過程發生的事情,例如處理 429 Too many requests 狀況(每支 API Key 有限制請求次數),更換成另一支 API Key。
  • 路由(routes)

    /api/api/news: 接收前端的 GET Request,調用中介層函式的 getNews

  • 控制器(controllers)

    getNews(ctx): koa2 會調用此中介層函式,放入包裝過、便於開發的 ctx 參數(HTTP reqres 等)。用於回傳新聞資料及處理例外事件。

Dependencies