MENU

マニュアルで使用する「メモを送る」ページ

<!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" />
  <style>
    /* 既存CSSに影響を与えない程度の軽いスタイル */
    .memo-box { display: grid; gap: .75rem; margin-top: 1rem;}
    .memo-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
    .memo-textarea { width: 100%; min-height: 300px; }
    .memo-filename { width: min(420px, 100%);  }
    .memo-note { font-size: .9em; color: #666;}
  </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:0;">メモを送るページ</h1>

 <a data-path="◯◯◯◯◯" class="openfolder">メモフォルダ</a>

        <!-- ▼ ここから追加:メモ入力と保存機能 -->
        <section class="memo-box" aria-label="メモ入力">
          <label for="memo-text" class="memo-note">メモ(HTMLとして保存されます)</label>
          <textarea id="memo-text" class="memo-textarea" placeholder="ここにメモを入力…" style=" border:solid 1px;"></textarea>

          <div class="memo-actions">
            <label for="memo-filename">ファイル名:</label>
            <input id="memo-filename" class="memo-filename" type="text" />
            <button id="btn-save-file" type="button">HTMLとして保存(通常ダウンロード)</button>
            <button id="btn-save-fsa" type="button" title="Chrome/Edgeなど対応ブラウザで使用可">フォルダを指定して保存(対応ブラウザ)</button>
          </div>
          <p class="memo-note">
            ※ 通常ダウンロードは保存先を自動指定できません。<br />
            ※ 「フォルダを指定して保存」はブラウザのファイル保存ダイアログから、ネットワークパス を選択できます(Chrome/Edge などの対応ブラウザ)。
          </p>
        </section>
        <!-- ▲ 追加ここまで -->

      </div>
    </div>
  </div>
  <script src="../load_header.js"></script>
  <script>
    // 既定のファイル名を日付から生成
    function defaultFileName() {
      const pad = (n) => String(n).padStart(2, '0');
      const d = new Date();
      const y = d.getFullYear();
      const m = pad(d.getMonth() + 1);
      const day = pad(d.getDate());
      const hh = pad(d.getHours());
      const mm = pad(d.getMinutes());
      return `memo_${y}${m}${day}_${hh}${mm}.html`;
    }

    function buildHtmlDocument(memo) {
      const escapedTitle = document.title || 'メモ';
      // ごく簡単なHTMLテンプレート。必要に応じて編集してください。
      return `<!DOCTYPE html>\n<html lang="ja">\n<head>\n<meta charset="UTF-8">\n<meta name="viewport" content="width=device-width, initial-scale=1.0">\n<title>${escapedTitle} - メモ</title>\n</head>\n<body>\n<main>\n<article>\n<pre style="white-space: pre-wrap; font-family: inherit;">${memo.replace(/</g, '&lt;').replace(/>/g, '&gt;')}</pre>\n</article>\n</main>\n</body>\n</html>`;
    }

    function saveByDownload(filename, htmlString) {
      const blob = new Blob([htmlString], { 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);
    }

    async function saveWithFileSystemAccess(filename, htmlString) {
      if (!('showSaveFilePicker' in window)) {
        alert('このブラウザは「フォルダを指定して保存」に対応していません。通常ダウンロードをご利用ください。');
        return;
      }
      try {
        const handle = await window.showSaveFilePicker({
          suggestedName: filename,
          types: [
            {
              description: 'HTML ファイル',
              accept: { 'text/html': ['.html', '.htm'] },
            },
          ],
        });
        const writable = await handle.createWritable();
        await writable.write(new Blob([htmlString], { type: 'text/html' }));
        await writable.close();
        alert('保存しました。保存場所をエクスプローラーで確認できます。');
      } catch (err) {
        if (err && err.name === 'AbortError') return; // キャンセル
        console.error(err);
        alert('保存に失敗しました。権限や保存先を確認してください。');
      }
    }

    // 初期化
    (function init() {
      const $filename = document.getElementById('memo-filename');
      const $textarea = document.getElementById('memo-text');
      const $btnSaveFile = document.getElementById('btn-save-file');
      const $btnSaveFsa = document.getElementById('btn-save-fsa');

      $filename.value = defaultFileName();

      $btnSaveFile.addEventListener('click', () => {
        const memo = $textarea.value || '';
        const html = buildHtmlDocument(memo);
        const name = ($filename.value || defaultFileName()).replace(/[\\/:*?"<>|]/g, '_');
        saveByDownload(name, html);
      });

      $btnSaveFsa.addEventListener('click', async () => {
        const memo = $textarea.value || '';
        const html = buildHtmlDocument(memo);
        const name = ($filename.value || defaultFileName()).replace(/[\\/:*?"<>|]/g, '_');
        await saveWithFileSystemAccess(name, html);
      });
    })();
  </script>
</body>
</html>
よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

目次