refactor: move video data to external JSON file and implement data loading
Restructure video data storage by moving hardcoded arrays to an external JSON file. Implement async data loading functions in both script.js and video.js to fetch data from the new JSON file. This improves maintainability and makes it easier to update video content without modifying source code.
This commit is contained in:
504
js/script.js
504
js/script.js
@@ -1,493 +1,19 @@
|
||||
let videos = [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "透明なパレット (self cover)",
|
||||
"channel": "Aqu3ra",
|
||||
"views": "576,197",
|
||||
"uploadDate": "1 months ago",
|
||||
"duration": "3:03",
|
||||
"thumbnail": "img/cover/music-01.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"title": "【歌ってみた】Duvet / covered by ヰ世界情緒",
|
||||
"channel": "ヰ世界情緒 -Isekaijoucho-",
|
||||
"views": "721,627",
|
||||
"uploadDate": "5 days ago",
|
||||
"duration": "3:32",
|
||||
"thumbnail": "img/cover/music-02.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"title": "ヨルシカ 『 晴る 』 -文化祭2025-",
|
||||
"channel": "countben",
|
||||
"views": "142,561",
|
||||
"uploadDate": "2 months ago",
|
||||
"duration": "4:46",
|
||||
"thumbnail": "img/cover/music-03.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"title": "【Silent Witch沈默魔女的秘密】OST 主題曲「沈黙の魔女」bgm|Kitkit Lu COVER",
|
||||
"channel": "KitKit Lu",
|
||||
"views": "1,856,264",
|
||||
"uploadDate": "5 months ago",
|
||||
"duration": "2:39",
|
||||
"thumbnail": "img/cover/music-04.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"title": "I Can't Wait feat. GUMI",
|
||||
"channel": "d0tc0mmie",
|
||||
"views": "315,293",
|
||||
"uploadDate": "1 month ago",
|
||||
"duration": "1:35",
|
||||
"thumbnail": "img/cover/music-05.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"title": "MiSiDE: ZERO Update – Full Gameplay + Ending (Showcase)",
|
||||
"channel": "RUSH PLAY",
|
||||
"views": "900,156",
|
||||
"uploadDate": "4 weeks ago",
|
||||
"duration": "24:39",
|
||||
"thumbnail": "img/cover/game-06.jpg",
|
||||
"category": "game",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"title": "Minecraftの効果音でサイエンス",
|
||||
"channel": "gmailアカウント",
|
||||
"views": "651,192",
|
||||
"uploadDate": "11 months ago",
|
||||
"duration": "1:05",
|
||||
"thumbnail": "img/cover/game-07.jpg",
|
||||
"category": "game",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"title": "osu! NEEDS to Take Notes... (00PARTS World's 1st Clear)",
|
||||
"channel": "bmc",
|
||||
"views": "892,163",
|
||||
"uploadDate": "1 month ago",
|
||||
"duration": "8:21",
|
||||
"thumbnail": "img/cover/game-08.jpg",
|
||||
"category": "game",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"title": "ヨルシカ - 春泥棒(OFFICIAL VIDEO)",
|
||||
"channel": "ヨルシカ / n-buna Official",
|
||||
"views": "123,456,789",
|
||||
"uploadDate": "5 years ago",
|
||||
"duration": "4:17",
|
||||
"thumbnail": "img/cover/music-09.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"title": "YOASOBI「アイドル」Official Music Video",
|
||||
"channel": "YOASOBI Official",
|
||||
"views": "456,789,123",
|
||||
"uploadDate": "2 years ago",
|
||||
"duration": "3:33",
|
||||
"thumbnail": "img/cover/music-10.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"title": "花譜 - 不可解",
|
||||
"channel": "花譜 -KAF-",
|
||||
"views": "12,345,678",
|
||||
"uploadDate": "3 years ago",
|
||||
"duration": "4:05",
|
||||
"thumbnail": "img/cover/music-11.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"title": "ZUTOMAYO - STUDY ME",
|
||||
"channel": "ZUTOMAYO",
|
||||
"views": "23,456,789",
|
||||
"uploadDate": "1 year ago",
|
||||
"duration": "3:45",
|
||||
"thumbnail": "img/cover/music-12.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"title": "Eve - 廻廻奇譚",
|
||||
"channel": "Eve",
|
||||
"views": "89,123,456",
|
||||
"uploadDate": "4 years ago",
|
||||
"duration": "3:55",
|
||||
"thumbnail": "img/cover/music-13.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"title": "ClariS - コネクト",
|
||||
"channel": "ClariS Official",
|
||||
"views": "45,678,901",
|
||||
"uploadDate": "10 years ago",
|
||||
"duration": "4:30",
|
||||
"thumbnail": "img/cover/music-14.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"title": "米津玄師 Kenshi Yonezu - Lemon",
|
||||
"channel": "Kenshi Yonezu 米津玄師",
|
||||
"views": "96,539,145",
|
||||
"uploadDate": "7 years ago",
|
||||
"duration": "4:35",
|
||||
"thumbnail": "img/cover/music-15.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"title": "【初音ミク】 夜明けと蛍 【オリジナル】",
|
||||
"channel": "ヨルシカ / n-buna Official",
|
||||
"views": "27,749,534",
|
||||
"uploadDate": "8 years ago",
|
||||
"duration": "5:10",
|
||||
"thumbnail": "img/cover/music-16.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"title": "Empty old City - Buffer",
|
||||
"channel": "Empty old city",
|
||||
"views": "838,946",
|
||||
"uploadDate": "1 year ago",
|
||||
"duration": "3:18",
|
||||
"thumbnail": "img/cover/music-17.jpg",
|
||||
"category": "music",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"title": "I built Git for Minecraft for a hackathon and won",
|
||||
"channel": "MathRayyan",
|
||||
"views": "288,346",
|
||||
"uploadDate": "12 days ago",
|
||||
"duration": "5:13",
|
||||
"thumbnail": "img/cover/game-18.jpg",
|
||||
"category": "game",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"title": "怎麼讓遊戲越來越真?PBR貼圖是怎麼做到的?",
|
||||
"channel": "孫拓海Taku",
|
||||
"views": "25,364",
|
||||
"uploadDate": "3 weeks ago",
|
||||
"duration": "13:14",
|
||||
"thumbnail": "img/cover/game-19.jpg",
|
||||
"category": "game",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"title": "「空あくあ!」當さくな說出這句台詞時 全場都淚崩了....【結城さくな】【Vtuber中文/翻譯/精華】",
|
||||
"channel": "Dar烤肉!",
|
||||
"views": "116,498",
|
||||
"uploadDate": "7 days ago",
|
||||
"duration": "8:35",
|
||||
"thumbnail": "img/cover/game-20.jpg",
|
||||
"category": "game",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"title": "「明日方舟:终末地性能分析:二游画质巅峰?榨干手机!",
|
||||
"channel": "极客湾Geekerwan",
|
||||
"views": "51,649",
|
||||
"uploadDate": "10 days ago",
|
||||
"duration": "22:13",
|
||||
"thumbnail": "img/cover/tech-21.jpg",
|
||||
"category": "tech",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"title": "What GPU is the BEST for Linux Gaming?",
|
||||
"channel": "Linus Tech Tips",
|
||||
"views": "96,751",
|
||||
"uploadDate": "7 days ago",
|
||||
"duration": "10:55",
|
||||
"thumbnail": "img/cover/tech-22.jpg",
|
||||
"category": "tech",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"title": "How Hard Is It to Build Your First PC?",
|
||||
"channel": "PLACITECH",
|
||||
"views": "4,351",
|
||||
"uploadDate": "2 months ago",
|
||||
"duration": "12:47",
|
||||
"thumbnail": "img/cover/tech-23.jpg",
|
||||
"category": "tech",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"title": "回顾我们最中意的 2025 年产品发布 - 谷歌开发者新闻(年终特辑)",
|
||||
"channel": "Google for Developers",
|
||||
"views": "3,475",
|
||||
"uploadDate": "1 month ago",
|
||||
"duration": "6:39",
|
||||
"thumbnail": "img/cover/tech-24.jpg",
|
||||
"category": "tech",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"title": "Commodore 128 Alternate Universe",
|
||||
"channel": "The 8-Bit Guy",
|
||||
"views": "17,498",
|
||||
"uploadDate": "4 months ago",
|
||||
"duration": "8:35",
|
||||
"thumbnail": "img/cover/tech-25.jpg",
|
||||
"category": "tech",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"title": "\"The Roller Coaster\" - Behind the Scenes - Time Lapse & Commentary",
|
||||
"channel": "AlanBeckerTutorials",
|
||||
"views": "193,762",
|
||||
"uploadDate": "7 years ago",
|
||||
"duration": "14:52",
|
||||
"thumbnail": "img/cover/art-26.jpg",
|
||||
"category": "art",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"title": "Animation vs. Game Design",
|
||||
"channel": "Alan Backer",
|
||||
"views": "694,264",
|
||||
"uploadDate": "2 months ago",
|
||||
"duration": "3:12",
|
||||
"thumbnail": "img/cover/art-27.jpg",
|
||||
"category": "art",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"title": "The Far Lands - Animation vs. Minecraft Shorts Ep 38",
|
||||
"channel": "Alan Backer",
|
||||
"views": "975,192",
|
||||
"uploadDate": "1 month ago",
|
||||
"duration": "9:10",
|
||||
"thumbnail": "img/cover/art-28.jpg",
|
||||
"category": "art",
|
||||
"type": "video"
|
||||
},
|
||||
{
|
||||
"id": 29,
|
||||
"title": "【Official MV】ray 超かぐや姫!Version/かぐや (cv.夏吉ゆうこ) & 月見ヤチヨ (cv.早見沙織) from #超かぐや姫 !【新作アニメーション】",
|
||||
"channel": "",
|
||||
"views": "78,192",
|
||||
"uploadDate": "5 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/music-29.jpg",
|
||||
"category": "music",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 30,
|
||||
"title": "ドッペルゲンガー feat.初音ミク#vocaloid #初音ミク",
|
||||
"channel": "",
|
||||
"views": "2,359",
|
||||
"uploadDate": "3 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/music-30.jpg",
|
||||
"category": "music",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"title": "Melt CPK! Remix — English Subtitled Version",
|
||||
"channel": "",
|
||||
"views": "2,264",
|
||||
"uploadDate": "3 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/music-31.jpg",
|
||||
"category": "music",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
"title": "【Suite History】花譜×#KTちゃん「ギミギミ逃避行feat. #KTちゃん(Prod. peko)」 #花譜 #KTちゃん #組曲 #shorts",
|
||||
"channel": "",
|
||||
"views": "5,430",
|
||||
"uploadDate": "2 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/music-32.jpg",
|
||||
"category": "music",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"title": "ヨルシカ - プレイシック #ヨルシカ #プレイシック #二人称 #yorushika #playsick #secondperson",
|
||||
"channel": "",
|
||||
"views": "39,254",
|
||||
"uploadDate": "10 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/music-33.jpg",
|
||||
"category": "music",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"title": "#ヨルシカ #live #前世 #yorushika",
|
||||
"channel": "",
|
||||
"views": "36,181",
|
||||
"uploadDate": "1 month ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/music-34.jpg",
|
||||
"category": "music",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 35,
|
||||
"title": "【歌ってみた】蜜月アン・ドゥ・トロワ covered by ヰ世界情緒 #shorts",
|
||||
"channel": "",
|
||||
"views": "2,163",
|
||||
"uploadDate": "6 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/music-35.jpg",
|
||||
"category": "music",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 36,
|
||||
"title": "Thank you 2025🩵Have a wonderful new year! #YOASOBI_2025",
|
||||
"channel": "",
|
||||
"views": "36,165",
|
||||
"uploadDate": "20 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/music-36.jpg",
|
||||
"category": "music",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 37,
|
||||
"title": "初めてラブソングを書きました。新曲「ハートマーク feat.川谷絵音」#礼衣 #ハートマーク",
|
||||
"channel": "",
|
||||
"views": "2,609",
|
||||
"uploadDate": "3 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/music-37.jpg",
|
||||
"category": "music",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
"title": "Would you play this at the school talent show for $500? #osu #osugame",
|
||||
"channel": "",
|
||||
"views": "133,658",
|
||||
"uploadDate": "2 months ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/game-38.jpg",
|
||||
"category": "game",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 39,
|
||||
"title": "May your holidays be filled with great vibes, full combos, and lots of epic tracks! 🎵",
|
||||
"channel": "",
|
||||
"views": "1,658",
|
||||
"uploadDate": "1 months ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/game-39.jpg",
|
||||
"category": "game",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 40,
|
||||
"title": "PANDORA PARADOXXX RE:MASTER alternative spin method #maimai #maimaiでらっくす #maimai_dx",
|
||||
"channel": "",
|
||||
"views": "25,365",
|
||||
"uploadDate": "12 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/game-40.jpg",
|
||||
"category": "game",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 41,
|
||||
"title": "Arch Linux VS Debian in 1 Min #linux #arch #debian",
|
||||
"channel": "",
|
||||
"views": "3,565",
|
||||
"uploadDate": "11 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/tech-41.jpg",
|
||||
"category": "tech",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 42,
|
||||
"title": "#linux #homelab #opensource #tech #debian",
|
||||
"channel": "",
|
||||
"views": "7,925",
|
||||
"uploadDate": "10 days ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/tech-42.jpg",
|
||||
"category": "tech",
|
||||
"type": "short"
|
||||
},
|
||||
{
|
||||
"id": 43,
|
||||
"title": "The one key keyboard #tech",
|
||||
"channel": "",
|
||||
"views": "4,571",
|
||||
"uploadDate": "1 month ago",
|
||||
"duration": "",
|
||||
"thumbnail": "img/cover/tech-43.jpg",
|
||||
"category": "tech",
|
||||
"type": "short"
|
||||
},
|
||||
];
|
||||
let videos = [];
|
||||
let currentCategory = 'All';
|
||||
|
||||
// DOM elements
|
||||
const searchInput = document.querySelector('.search-input');
|
||||
const searchBtn = document.querySelector('.search-btn');
|
||||
const searchResults = document.querySelector('.search-results');
|
||||
const searchResultsContent = document.querySelector('.search-results-content');
|
||||
const videoGrid = document.querySelector('.video-grid');
|
||||
const shortsGrid = document.querySelector('.shorts-grid');
|
||||
const categoryBtns = document.querySelectorAll('.category-btn');
|
||||
const subscriptionsList = document.querySelector('.subscriptions-list');
|
||||
let searchInput, searchBtn, searchResults, searchResultsContent, videoGrid, shortsGrid, categoryBtns, subscriptionsList;
|
||||
|
||||
async function init() {
|
||||
searchInput = document.querySelector('.search-input');
|
||||
searchBtn = document.querySelector('.search-btn');
|
||||
searchResults = document.querySelector('.search-results');
|
||||
searchResultsContent = document.querySelector('.search-results-content');
|
||||
videoGrid = document.querySelector('.video-grid');
|
||||
shortsGrid = document.querySelector('.shorts-grid');
|
||||
categoryBtns = document.querySelectorAll('.category-btn');
|
||||
subscriptionsList = document.querySelector('.subscriptions-list');
|
||||
|
||||
await loadVideos();
|
||||
// 只有在存在相应元素时才执行
|
||||
if (videoGrid && shortsGrid) {
|
||||
renderVideos();
|
||||
}
|
||||
@@ -498,7 +24,13 @@ async function init() {
|
||||
}
|
||||
|
||||
async function loadVideos() {
|
||||
return Promise.resolve(); // Already defined in global scope
|
||||
try {
|
||||
const response = await fetch('src/video.json');
|
||||
const data = await response.json();
|
||||
videos = data.videos;
|
||||
} catch (error) {
|
||||
console.error('Failed to load videos:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function renderVideos() {
|
||||
|
||||
Reference in New Issue
Block a user