/* 株式会社yfc M&Aサイト 共通スクリプト - モバイルメニュー - フォーム: 入力 → 確認 → 送信(完了ページへ) - スパム対策: honeypot + 送信間隔チェック(reCAPTCHA導入は要確認: キー取得後に有効化) */ (function () { "use strict"; /* ---------- モバイルメニュー ---------- */ var toggle = document.querySelector(".menu-toggle"); var nav = document.querySelector(".gnav"); if (toggle && nav) { toggle.addEventListener("click", function () { var open = nav.classList.toggle("open"); toggle.setAttribute("aria-expanded", open ? "true" : "false"); toggle.textContent = open ? "閉じる ✕" : "メニュー ☰"; }); } /* ---------- 現在ページのナビ強調 ---------- */ var path = location.pathname.split("/").pop() || "index.html"; document.querySelectorAll(".gnav a").forEach(function (a) { if (a.getAttribute("href") === path) a.setAttribute("aria-current", "page"); }); /* ---------- フォーム(確認画面つき) ---------- */ var form = document.querySelector("form.js-contact-form"); if (!form) return; var loadedAt = Date.now(); var stepInput = document.getElementById("step-input"); var stepConfirm = document.getElementById("step-confirm"); var stepsNav = document.querySelectorAll(".form-steps li"); function setStep(n) { if (stepInput) stepInput.hidden = n !== 1; if (stepConfirm) stepConfirm.hidden = n !== 2; stepsNav.forEach(function (li, i) { li.classList.toggle("active", i === n - 1); }); window.scrollTo({ top: 0 }); } function fieldLabel(row) { var l = row.querySelector("label"); if (!l) return ""; var clone = l.cloneNode(true); clone.querySelectorAll(".req, .opt").forEach(function (s) { s.remove(); }); return clone.textContent.trim(); } function validate() { var ok = true; form.querySelectorAll(".form-row").forEach(function (row) { var field = row.querySelector("input, select, textarea"); if (!field) return; var bad = false; if (field.required) { if (field.type === "checkbox") bad = !field.checked; else bad = !field.value.trim(); } if (!bad && field.type === "email" && field.value && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(field.value)) bad = true; if (!bad && field.type === "tel" && field.value && !/^[0-9\-+() ]{8,16}$/.test(field.value)) bad = true; row.classList.toggle("has-error", bad); if (bad && ok) { field.focus(); ok = false; } if (bad) ok = false; }); return ok; } function buildConfirm() { var tbl = document.getElementById("confirm-body"); if (!tbl) return; tbl.innerHTML = ""; form.querySelectorAll(".form-row").forEach(function (row) { var field = row.querySelector("input, select, textarea"); if (!field || field.classList.contains("hp") ) return; var val; if (field.type === "checkbox") val = field.checked ? "同意する" : ""; else if (field.tagName === "SELECT") val = field.options[field.selectedIndex] ? field.options[field.selectedIndex].text : ""; else val = field.value; if (!val) val = "(未入力)"; var tr = document.createElement("tr"); var th = document.createElement("th"); th.textContent = fieldLabel(row); var td = document.createElement("td"); td.textContent = val; td.style.whiteSpace = "pre-wrap"; tr.appendChild(th); tr.appendChild(td); tbl.appendChild(tr); }); } var toConfirm = document.getElementById("btn-confirm"); if (toConfirm) { toConfirm.addEventListener("click", function () { if (!validate()) { var firstErr = form.querySelector(".form-row.has-error"); if (firstErr) firstErr.scrollIntoView({ block: "center" }); return; } buildConfirm(); setStep(2); }); } var backBtn = document.getElementById("btn-back"); if (backBtn) backBtn.addEventListener("click", function () { setStep(1); }); form.addEventListener("submit", function (e) { /* スパム対策1: honeypot(見えない項目に入力があればbot) */ var hp = form.querySelector(".hp"); if (hp && hp.value) { e.preventDefault(); return; } /* スパム対策2: 表示から5秒未満の送信は拒否 */ if (Date.now() - loadedAt < 5000) { e.preventDefault(); return; } /* 検証を通れば contact.php へ通常POST(サーバー側で通知メール送信+thanks.htmlへリダイレクト)。 サーバー側の再検証・reCAPTCHA導入は contact.php 参照。 */ var btn = form.querySelector('#step-confirm button[type="submit"]'); if (btn) { btn.disabled = true; btn.textContent = "送信中…"; } }); })();