バックアップとして。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>テンプレートHTMLダウンロード</title>
<link rel="stylesheet" href="../style.css">
<style>
/* トースト通知 */
#toast {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background-color: #333;
color: white;
padding: 12px 24px;
border-radius: 4px;
opacity: 0;
pointer-events: none;
transition: opacity 0.4s ease;
z-index: 9999;
}
#toast.show {
opacity: 1;
}
</style>
</head>
<body>
<div id="header-placeholder"></div>
<div class="page-wrapper">
<aside id="sidebar">
<!-- Sidebar content will be injected here by JS -->
</aside>
<div class="content-wrapper">
<div class="main">
<h1 class="hyoudai" style="margin-bottom:20px;">テンプレートHTMLをダウンロード</h1>
<div class="input-area">
<label for="filename">保存するファイル名(例: my_template.html)</label>
<input type="text" id="filename" value="template.html" />
</div>
<div class="actions">
<button id="btn-download">通常ダウンロード</button>
<button id="btn-fsa">フォルダを選んで保存(対応ブラウザのみ)</button>
</div>
<p class="note">
※ フォルダ保存はChrome・Edgeなど一部ブラウザのみ対応<br>
※ 不正なファイル名文字(\/:*?"<>|)は自動的に置き換えられます
</p>
<!-- トースト要素 -->
<div id="toast"></div>
<script>
// HTMLテンプレート文字列
function generateHtmlTemplate() {
return `<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>◯◯◯◯◯</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div id="header-placeholder"></div>
<div class="page-wrapper">
<aside id="sidebar">
<!-- Sidebar content will be injected here by JS -->
</aside>
<div class="content-wrapper">
<div class="main">
<pre>
<h1 class="hyoudai">◯◯◯◯◯</h1>
</pre>
</div>
</div>
</div>
<script src="../load_header.js"><\/script>
</body>
</html>`;
}
function sanitizeFileName(name) {
return name.replace(/[\\/:*?"<>|]/g, "_").trim() || "template.html";
}
function saveWithDownload(filename, content) {
const blob = new Blob([content], { type: "text/html" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
showToast("通常ダウンロードしました");
}
async function saveWithFSA(filename, content) {
if (!window.showSaveFilePicker) {
showToast("非対応ブラウザです(Chrome/Edgeをご利用ください)");
return;
}
try {
const handle = await showSaveFilePicker({
suggestedName: filename,
types: [{
description: "HTMLファイル",
accept: { "text/html": [".html", ".htm"] }
}]
});
const writable = await handle.createWritable();
await writable.write(new Blob([content], { type: "text/html" }));
await writable.close();
showToast("フォルダ保存が完了しました");
} catch (err) {
if (err.name !== "AbortError") {
console.error("保存エラー:", err);
showToast("保存に失敗しました");
}
}
}
function showToast(message) {
const toast = document.getElementById("toast");
toast.textContent = message;
toast.classList.add("show");
setTimeout(() => {
toast.classList.remove("show");
}, 3000);
}
// イベント設定
document.getElementById("btn-download").addEventListener("click", () => {
const nameInput = document.getElementById("filename").value;
const filename = sanitizeFileName(nameInput);
const html = generateHtmlTemplate();
saveWithDownload(filename, html);
});
document.getElementById("btn-fsa").addEventListener("click", async () => {
const nameInput = document.getElementById("filename").value;
const filename = sanitizeFileName(nameInput);
const html = generateHtmlTemplate();
await saveWithFSA(filename, html);
});
</script>
</div>
</div>
</div>
<script src="../load_header.js"></script>
</body>
</html>
コメント