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>
    input, textarea {
      width: 95%;
      padding: 12px;
      margin-top: 6px;
      border: 1px solid #ccc;
      border-radius: 6px;
      font-size: 14px;
    }
    textarea { resize: vertical; min-height: 320px; }

    .input-area, .row, .actions {
      margin-bottom: 1rem;
    }
    .row {
      display: grid;
      width: 97%;
      grid-template-columns: 1fr 1fr;
      gap: 12px;
    }
    .actions {
      display: flex;
      gap: 12px;
      flex-wrap: wrap;
    }
    button, a.btn {
      padding: 10px 16px;
      border-radius: 8px;
      border: 0;
      text-decoration: none;
      font-weight: bold;
      cursor: pointer;
      background: #1a73e8;
      color: #fff;
    }
    button.secondary {
      background: #6b7280;
    }
    .note {
      font-size: 0.9em;
      color: #555;
    }

    code.preview {
      display: block;
      padding: 10px;
      background: #0b1020;
      color: #e1e7ff;
      border-radius: 10px;
      overflow: auto;
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
      font-size: 12px;
    }
  </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" style="width:800px;">

<h1 class="hyoudai" style="margin-bottom:0;">mailtoでメールを作成</h1>
      <p class="note">フォームに入力して「メールを開く」を押すと、既定のメールアプリが起動します。</p>

      <form id="f">
        <label>宛先 To(カンマ区切りで複数可)
          <input name="to" type="text" placeholder="to1@example.com, to2@example.com" required>
        </label>

        <div class="row">
          <label>CC
            <input name="cc" type="text" placeholder="cc1@example.com, cc2@example.com">
          </label>
          <label>BCC
            <input name="bcc" type="text" placeholder="bcc1@example.com, bcc2@example.com">
          </label>
        </div>

        <label>件名 Subject
          <input name="subject" type="text" placeholder="件名を入力" required>
        </label>

        <label>本文 Body(Shift+Enterで改行)
          <textarea name="body" placeholder="本文を入力">
◯◯株式会社
 ◯◯ 様

 いつもお世話になっております。
 〇〇の件でご連絡差し上げます。

 ・ポイント1
 ・ポイント2

 ご確認のほどよろしくお願いいたします。

---------------------
会社名 山田 太郎
mail: taro@example.com
TEL: 00-0000-0000
---------------------</textarea>
        </label>

        <div class="row">
          <label>返信先 Reply-To(対応メーラーのみ)
            <input name="replyTo" type="email" placeholder="reply@example.com">
          </label>
          <label>Gmailタブで開く
            <input name="openGmail" type="checkbox"> Gmailで開く
          </label>
        </div>

        <div class="actions">
          <a id="openBtn" href="#" class="btn" target="_self">メールを開く</a>
          <button id="copyBtn" type="button" class="secondary">リンクをコピー</button>
        </div>

        <div class="note">生成されたリンク(確認用)</div>
        <code id="preview" class="preview"></code>
      </form>
</div>
</div>
</div>

<script>
  const f = document.getElementById('f');
  const openBtn = document.getElementById('openBtn');
  const copyBtn = document.getElementById('copyBtn');
  const preview = document.getElementById('preview');

  window.addEventListener('DOMContentLoaded', () => {
    f.to.value = "test@example.com";
    f.cc.value = "cc@example.com";
    f.bcc.value = "bcc@example.com";
    f.subject.value = "〇〇の件";
    update();
  });

  function buildMailto(params) {
    const { to, cc, bcc, subject, body, replyTo, openGmail } = params;

    const trimList = (s) => (s || '').split(',').map(v => v.trim()).filter(Boolean).join(',');
    const toList = trimList(to);
    const qs = new URLSearchParams();
    if (subject) qs.set('subject', subject);
    if (body) qs.set('body', body.replace(/\r?\n/g, '\r\n'));
    if (cc) qs.set('cc', trimList(cc));
    if (bcc) qs.set('bcc', trimList(bcc));
    if (replyTo) qs.set('reply-to', replyTo);

    if (openGmail) {
      const gqs = new URLSearchParams();
      if (toList) gqs.set('to', toList);
      if (cc) gqs.set('cc', trimList(cc));
      if (bcc) gqs.set('bcc', trimList(bcc));
      if (subject) gqs.set('su', subject);
      if (body) gqs.set('body', body);
      if (replyTo) gqs.set('replyto', replyTo);
      return 'https://mail.google.com/mail/?view=cm&fs=1&' + gqs.toString();
    }

    const base = 'mailto:' + (toList || '');
    const q = qs.toString();
    return q ? base + '?' + q : base;
  }

  function update() {
    const data = Object.fromEntries(new FormData(f).entries());
    data.openGmail = f.openGmail.checked; // ✅ ここでBoolean化
    const url = buildMailto(data);
    openBtn.href = url;
    preview.textContent = url;
  }

  f.addEventListener('input', update);
  update();

  copyBtn.addEventListener('click', async () => {
    try {
      await navigator.clipboard.writeText(openBtn.href);
      copyBtn.textContent = 'コピーしました';
      setTimeout(() => copyBtn.textContent = 'リンクをコピー', 1500);
    } catch (e) {
      alert('コピーできませんでした: ' + e);
    }
  });
</script>
<script src="../load_header.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>mailtoでメールを作成</title>
  <style>
    :root { --gap: 12px; }
    * { box-sizing: border-box; }
    body { font-family: system-ui, -apple-system, Segoe UI, Roboto, "Noto Sans JP", sans-serif; margin: 0; padding: 24px; background: #f7f7f8; }
    .wrap { max-width: 720px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 16px; box-shadow: 0 6px 20px rgba(0,0,0,.06); }
    h1 { margin: 0 0 12px; font-size: 20px; }
    p.desc { margin: 0 0 16px; color: #555; font-size: 14px; }
    label { display:block; font-size: 12px; color:#333; margin-top: var(--gap); }
    input, textarea { width: 100%; padding: 12px; margin-top: 6px; border: 1px solid #e3e3e8; border-radius: 10px; font-size: 14px; }
    textarea { resize: vertical; min-height: 260px; }
    .row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); }
    .actions { display:flex; gap: var(--gap); align-items:center; margin-top: var(--gap); flex-wrap: wrap; }
    button, a.btn { padding: 12px 16px; border-radius: 999px; border: 0; text-decoration: none; font-weight: 700; cursor: pointer; background: #1a73e8; color: #fff; display:inline-block; }
    button.secondary, a.secondary { background: #6b7280; }
    .status { font-size: 12px; color:#666; margin-top: 8px; }
    code.preview { display:block; padding: 10px; background:#0b1020; color:#e1e7ff; border-radius: 10px; overflow:auto; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 12px; }
  </style>
</head>
<body>
  <div class="wrap">
    <h1>mailtoでメールを作成</h1>
    <p class="desc">フォームに入力して「メールを開く」を押すと、既定のメールアプリが起動し、内容が自動で挿入されます(送信はユーザー操作)。</p>

    <form id="f">
      <label>宛先 To(カンマ区切りで複数可)
        <input name="to" type="text" placeholder="to1@example.com, to2@example.com" required>
      </label>

      <div class="row">
        <label>CC
          <input name="cc" type="text" placeholder="cc1@example.com, cc2@example.com">
        </label>
        <label>BCC
          <input name="bcc" type="text" placeholder="bcc1@example.com, bcc2@example.com">
        </label>
      </div>

      <label>件名 Subject
        <input name="subject" type="text" placeholder="件名を入力" required>
      </label>

      <label>本文 Body(Shift+Enterで改行)
        <textarea name="body" placeholder="本文を入力(署名などもOK)">
◯◯株式会社
 ◯◯ 様
 
 いつもお世話になっております。
 〇〇の件でご連絡差し上げます。

 ・ポイント1
 ・ポイント2

 ご確認のほどよろしくお願いいたします。

---------------------
会社名 山田 太郎
mail: taro@example.com
TEL: 00-0000-0000
---------------------</textarea>
      </label>


      <div class="row">
        <label>返信先 Reply-To(対応メーラーのみ)
          <input name="replyTo" type="email" placeholder="reply@example.com">
        </label>
        <label>既定メーラーが無い環境向け(Gmailで開く)
          <input name="openGmail" type="checkbox"> Gmailタブで開く
        </label>
      </div>

      <div class="actions">
        <a id="openBtn" href="#" class="btn" target="_self">メールを開く</a>
        <button id="copyBtn" type="button" class="secondary">リンクをコピー</button>
      </div>
      <div class="status">生成されたリンク(確認用)</div>
      <code id="preview" class="preview"></code>
    </form>

    <details style="margin-top:14px;">
      <summary>使い方のヒント</summary>
      <ul>
        <li>本文の改行は自動エンコードされます(\n → %0D%0A)。</li>
        <li>日本語・絵文字もURLエンコードされます。長すぎる本文は一部の環境で開けない場合があります。</li>
        <li>複数宛先はカンマ区切り。スペースは自動トリムされます。</li>
        <li>一部のメーラーは <code>reply-to</code> のクエリに対応していません(Gmail/Outlook Webは可)。</li>
      </ul>
    </details>
  </div>

  <script>
window.addEventListener('DOMContentLoaded', () => {
  f.to.value = "test@example.com";  // 宛先
  f.cc.value = "cc@example.com";       // CC
  f.bcc.value = "bcc@example.com";     // BCC
  f.subject.value = "〇〇の件";  // 件名初期値
  update(); // リンク再生成
});

    const f = document.getElementById('f');
    const openBtn = document.getElementById('openBtn');
    const copyBtn = document.getElementById('copyBtn');
    const preview = document.getElementById('preview');

    function buildMailto(params){
      const { to, cc, bcc, subject, body, replyTo, openGmail } = params;

      const enc = (s) => encodeURIComponent(s || '');
      const trimList = (s) => (s || '').split(',').map(v => v.trim()).filter(Boolean).join(',');

      const toList = trimList(to);
      const qs = new URLSearchParams();
      if (subject) qs.set('subject', subject);

      // 改行は \r\n でエンコード
      if (body) qs.set('body', body.replace(/\r?\n/g, '\r\n'));
      if (cc) qs.set('cc', trimList(cc));
      if (bcc) qs.set('bcc', trimList(bcc));
      if (replyTo) qs.set('reply-to', replyTo);

      if (openGmail) {
        // Gmail compose URL
        const gqs = new URLSearchParams();
        if (toList) gqs.set('to', toList);
        if (cc) gqs.set('cc', trimList(cc));
        if (bcc) gqs.set('bcc', trimList(bcc));
        if (subject) gqs.set('su', subject);
        if (body) gqs.set('body', body);
        if (replyTo) gqs.set('replyto', replyTo);
        return 'https://mail.google.com/mail/?view=cm&fs=1&' + gqs.toString();
      }

      const base = 'mailto:' + (toList || '');
      const q = qs.toString();
      return q ? base + '?' + q : base;
    }

    function update(){
      const data = Object.fromEntries(new FormData(f).entries());
      const url = buildMailto(data);
      openBtn.href = url;
      preview.textContent = url;
    }

    f.addEventListener('input', update);
    update();

    copyBtn.addEventListener('click', async () => {
      try {
        await navigator.clipboard.writeText(openBtn.href);
        copyBtn.textContent = 'コピーしました';
        setTimeout(() => copyBtn.textContent = 'リンクをコピー', 1500);
      } catch (e) {
        alert('コピーできませんでした: ' + e);
      }
    });
  </script>
</body>
</html>
よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

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

目次