support_uwuzu_net/js/script.js

201 lines
6.4 KiB
JavaScript

// エラー表示
function showError(text) {
const errorMsgElement = document.querySelector("#errorMsg");
const errorElement = document.querySelector("#error");
if (errorMsgElement) {
errorMsgElement.textContent = text;
}
if (errorElement) {
errorElement.style.display = "block";
setTimeout(() => {
errorElement.style.display = "none";
}, 5000);
}
}
document.addEventListener("DOMContentLoaded", async () => {
try {
// contents.json読み込み
const response = await fetch("/contents.json");
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
const articlesData = data.articles;
if (!Array.isArray(articlesData)) {
throw new Error("記事データが不正な形式です");
}
// #contents読み込み
const contentsContainer = document.querySelector("#contents");
if (!contentsContainer) {
throw new Error("#contentsが見つかりません");
}
contentsContainer.innerHTML = "";
// 記事一覧作成
articlesData.forEach(article => {
// ID取得
const articleElement = document.createElement("div");
articleElement.className = "items";
articleElement.id = article.id;
// 日付取得
const dateElement = document.createElement("div");
dateElement.className = "date";
dateElement.textContent = String(article.date);
// タイトル取得
const titleElement = document.createElement("h1");
titleElement.textContent = String(article.title);
// 説明取得
const descriptionElement = document.createElement("p");
descriptionElement.textContent = String(article.description);
// 親要素に追加
articleElement.appendChild(dateElement);
articleElement.appendChild(titleElement);
articleElement.appendChild(descriptionElement);
contentsContainer.appendChild(articleElement);
});
// URLパラメータから記事IDを取得
const urlParams = new URLSearchParams(window.location.search);
const articleId = urlParams.get("articles");
if (articleId) {
const article = articlesData.find(a => a && a.id === articleId);
if (article) {
showArticle(article);
} else {
showError("記事が存在しませんでした");
}
}
// 記事移動
contentsContainer.addEventListener("click", (e) => {
const itemElement = e.target.closest(".items");
if (itemElement && itemElement.id) {
const id = itemElement.id;
const article = articlesData.find(a => a && a.id === id);
if (article) {
showArticle(article);
try {
history.pushState({ articleId: id }, article.title, `?articles=${id}`);
} catch (error) {
console.warn("History API操作に失敗しました:", error);
}
} else {
showError("記事が存在しませんでした");
}
}
});
// 検索
const searchBox = document.querySelector("#searchbox");
if (searchBox) {
searchBox.addEventListener("input", (e) => {
const searchText = (e.target.value || '').toLowerCase();
const items = document.querySelectorAll("#contents .items");
items.forEach(item => {
const titleElement = item.querySelector("h1");
const descriptionElement = item.querySelector("p");
if (titleElement && descriptionElement) {
const title = (titleElement.textContent || '').toLowerCase();
const description = (descriptionElement.textContent || '').toLowerCase();
if (title.includes(searchText) || description.includes(searchText)) {
item.style.display = "block";
} else {
item.style.display = "none";
}
}
});
});
}
// 記事表示
async function showArticle(article) {
// #docs・#top取得
const docsElement = document.querySelector("#docs");
const topElement = document.querySelector("#top");
// データ存在確認
if (docsElement && topElement && article && article.title && article.date) {
// 記事div作成
const articleDiv = document.createElement("div");
articleDiv.className = "article";
// タイトル取得
const titleElement = document.createElement("h1");
titleElement.textContent = String(article.title);
// 日付取得
const dateElement = document.createElement("div");
dateElement.className = "date";
dateElement.textContent = String(article.date);
// 内容
const contentElement = document.createElement("div");
contentElement.className = "content";
// 記事内容
try {
// mdファイル読み込み
const response = await fetch(`/articles/${article.id}.md`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.text();
// パース
const content = data || '';
if (typeof marked !== 'undefined' && typeof marked.parse === 'function') {
contentElement.innerHTML = marked.parse(content);
} else {
contentElement.textContent = content;
}
} catch (error) {
console.error("Markdownパースエラー:", error);
contentElement.textContent = response || '';
}
// 親要素に追加
articleDiv.appendChild(titleElement);
articleDiv.appendChild(dateElement);
articleDiv.appendChild(contentElement);
// 記事表示
docsElement.innerHTML = "";
docsElement.appendChild(articleDiv);
docsElement.style.display = "block";
// 記事一覧非表示
const articleList = document.querySelectorAll(".articlelist");
for (let i = 0; i < articleList.length; i++) {
articleList[i].style.display = "none";
}
}
}
} catch (error) {
console.error("データの読み込みに失敗しました:", error);
showError("データの読み込みに失敗しました");
}
});