在這篇文章中,我們將探討如何使用Edge Delivery Services 和 Document Authoring的強大功能,從位於 DA 的試算表建立項目動態清單。
將連結清單堆疊到頁面上,與策展一些實際可用的東西,兩者之間有很大的差異。這個專案一開始是",我們只需要一個 URL 和說明的清單," ,但很快就變成要解決一些實際的問題:保持內容的可維護性、避免 DOM 的臃腫、讓過濾感覺快速,但又不會過度工程化。
這就是 Reference List 區塊;Adobe Edge Delivery Services (EDS) 的資料驅動、可過濾的卡片網格,可從試算表支援的 JSON feed 擷取內容,支援類別和標籤過濾,並透過精巧的動畫逐步載入結果。我們特別製作了這個 頁面 來驅動這個 Edge Delivery Services 參考頁 ,各位應該已經把它加入書籤了!
讓試算表驅動一切
該區塊完全由資料驅動。它會取得由 EDS 工作表產生的 JSON 檔案,網址是/en/reference-links.json 。我們決定使用多頁紙的格式;一頁紙用來顯示參考項目,另一頁紙用來顯示類別:
{
"data": {
"data": [
{
"url": "https://developer.adobe.com/",
"image-url": "https://example.com/thumb.png",
"title": "Adobe Developer Documentation",
"description": "Official docs for building on Adobe platforms.",
"tag": "Documentation|Official",
"category": "Development"
}
]
},
"categories": {
"data": [{ "Category": "Development", "Description": "Dev tools and references" }]
}
}
標籤在單元格內使用管道 (Tag1 | Tag2),使撰寫簡單且可預測。
當您建立此區塊時,您無疑會想要先做一些測試,然後再將它推出。如果您只有 DA 內已填充的清單,在本機測試時很可能會遇到一些跨來源資源分享 (CORS) 問題。要解決這個問題,只需建立您自己的 JSON 檔案,其中包含一些滿足 DA 表單相同要求的測試項目,並啟用本機 JSON 使用。
const USE_LOCAL_JSON = false;
const LOCAL_JSON_PATH = '/tools/json/reference-list.json';
const LIVE_JSON_URL = '/en/reference-links.json';
打造不會破損的卡片
每個參考項目都會成為具有此 DOM 結構的卡片:
.reference-card
└── a.reference-link
├── div.reference-image-wrapper (optional)
│ └── img.reference-image
└── div.reference-content
├── h3.reference-title
├── p.reference-description (optional)
└── div.reference-tags
└── span.reference-tag (one per tag)
當建立一個區塊時,其中一個最重要的考量就是作者使用它的便利性。為此,我們必須確保清單能夠處理不同數量的資訊,而且功能仍然相同。有些有描述、標籤,或兩者都沒有。規則是只呈現存在的東西,但不要讓版面取決於任何一件作品是否存在。幾個具體的決定:
-
圖片是可選的,image-url 欄位 (回退到圖片) 只有在非空的情況下才會渲染
-
圖片使用 loading="lazy" ,因此螢幕外的縮圖不會阻擋初始呈現
-
所有連結都使用 rel="noopener noreferrer" ,以防止外部 URL 的 tab-napping
- 現代瀏覽器通常會自動執行此動作,但安全第一!
過濾清單而不重建世界
在考慮如何篩選時,事情有時候會變得混亂,尤其是在每次互動時重新渲染。為了避免這種情況,我們確保從一開始就設定每張卡片的屬性,如此一來,它就變成更多的可視性切換。
card.setAttribute('data-category', ref.category);
card.setAttribute('data-tags', JSON.stringify(cardTags));
我們也新增了 updateReferenceDisplay 功能,在每次互動時重新評估可見度:
const categoryMatch = selectedCategory === 'all' || cardCategory === selectedCategory;
const tagMatch = cardTags.length === 0 || cardTags.some((tag) => activeTags.has(tag));
標籤匹配使用OR 邏輯,任何選取的標籤都會使卡片合格。活躍標籤位於一個 Set 中,因此新增/移除及會員檢查都是 O(1)。一個微妙的邊緣情況:未標記的項目。讓它們總是能通過標籤過濾器,意味著它們從來不會意外消失。
CSS 的表現超乎預期
雖然這並不是一篇關於造型的部落格,但如果我沒有提到我們在造型方面的一些決定,那就太失禮了。尤其是關於"spotlight" 卡牌懸浮時的效果。
.reference-grid:has(.reference-card:hover) .reference-card:not(:hover) {
transform: scale(0.9);
opacity: 0.6;
}
淡入動畫採用相同的方法,因此 JS 和樣式之間沒有協調開銷:
.reference-card { opacity: 0; }
.reference-card.fade-in {
opacity: 1;
animation: fade-in-up 0.5s ease-out forwards;
}
@keyframes fade-in-up {
from { transform: translateY(20px); }
to { transform: translateY(0); }
}
最終想法
這個專案是一個很好的例子,說明深思熟慮的架構如何將常見的模式變成真正可擴充的東西。透過將責任推給結構化資料,並讓前端專注於有效的呈現和狀態管理,Reference List 區塊避免了臃腫的 DOM 和昂貴的重新呈現等常見問題。
真正的價值不僅在於過濾或呈現,而是在於系統本身。作者可以獲得一種可預測、低摩擦的方式來管理內容,而實作則保持高效能且易於擴充。這是一種隨著內容成長而維持的模式,而不是每次都需要重新檢視。
關於作者
喜歡你聽到的嗎?對適合您的產品有疑問?我們很樂意與您討論!聯絡我們