`;
formDiv.appendChild(formContent);
chatMessages.appendChild(formDiv);
// フォームのバリデーション機能を追加
setupFormValidation();
// スクロールを最下部に
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// フォームバリデーション機能
function setupFormValidation() {
const form = document.getElementById('UserItemForm');
const emailInput = document.getElementById('Usermail');
if (form) {
form.addEventListener('submit', function(e) {
let isValid = true;
// メールアドレスのバリデーション
if (!emailInput.value || !validateEmail(emailInput.value)) {
emailInput.style.border = '1px solid red';
isValid = false;
} else {
emailInput.style.border = '1px solid #ccc';
}
if (!isValid) {
e.preventDefault();
}
});
}
}
// メールアドレスバリデーション関数
function validateEmail(email) {
const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
}
const chatMessages = document.getElementById('chatMessages');
let typingIndicator;
// タイピングインジケータをすべて削除する関数
function removeAllTypingIndicators() {
const oldTypingIndicators = document.querySelectorAll('.typing');
oldTypingIndicators.forEach(indicator => {
indicator.remove();
});
}
// タイピングインジケータを表示する関数
function showTypingIndicator() {
const newTypingIndicator = window.typingIndicator.cloneNode(true);
chatMessages.appendChild(newTypingIndicator);
newTypingIndicator.style.display = 'block';
chatMessages.scrollTop = chatMessages.scrollHeight;
return newTypingIndicator;
}
// チャットを表示する関数
function displayChat(scene) {
// シーン開始時に古いタイピングインジケータをクリーンアップ
removeAllTypingIndicators();
const messages = chatData[scene].messages;
let currentIndex = 0;
function displayNextMessage() {
if (currentIndex >= messages.length) return;
const message = messages[currentIndex];
// タイピングインジケータを正しい位置に配置して表示
const currentTyping = showTypingIndicator();
chatMessages.scrollTop = chatMessages.scrollHeight;
// 指定された時間後にメッセージを表示
let typingTime = currentIndex === 0 ? 1000 : (currentIndex === 1 ? 1000 : 3000);
setTimeout(() => {
// タイピングインジケータを非表示
removeAllTypingIndicators();
// メッセージ要素を作成
const messageDiv = document.createElement('div');
messageDiv.classList.add('message', message.type);
const contentDiv = document.createElement('div');
contentDiv.classList.add('message-content');
contentDiv.innerHTML = message.content;
messageDiv.appendChild(contentDiv);
chatMessages.appendChild(messageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
// 選択肢ボタンがあれば表示
if (message.options) {
// ボタン要素を作成
const buttonsDiv = document.createElement('div');
buttonsDiv.classList.add('option-buttons');
message.options.forEach((option) => {
const button = document.createElement('button');
button.classList.add('option-button');
button.textContent = option.text;
button.onclick = () => {
// ボタンを無効化して選択されたもの以外を非表示にする
message.options.forEach((opt, idx) => {
const btns = document.querySelectorAll('.option-button');
btns.forEach((btn, btnIdx) => {
if (btnIdx === idx && btn.textContent === option.text) {
// 選択されたボタンは無効化するだけ
btn.disabled = true;
btn.style.backgroundColor = '#e6f7ef';
} else {
// 選択されなかったボタンは非表示
btn.style.display = 'none';
}
});
});
// ユーザーの選択を表示
const userMessageDiv = document.createElement('div');
userMessageDiv.classList.add('message', 'user');
const userContentDiv = document.createElement('div');
userContentDiv.classList.add('message-content');
userContentDiv.textContent = option.text;
userMessageDiv.appendChild(userContentDiv);
chatMessages.appendChild(userMessageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
// タイピングインジケータを表示してから次のシーンに進む
// 既存のタイピングを削除して新しいものを追加
removeAllTypingIndicators();
const userResponseTyping = showTypingIndicator();
chatMessages.scrollTop = chatMessages.scrollHeight;
// 少し待ってから次のシーンに進む
setTimeout(() => {
displayChat(option.next);
}, 2000); // タイピングを2秒間表示
};
buttonsDiv.appendChild(button);
});
// ボタンをメッセージの後に追加
messageDiv.appendChild(buttonsDiv);
// アニメーション効果のため少し遅らせて表示
setTimeout(() => {
buttonsDiv.classList.add('visible');
chatMessages.scrollTop = chatMessages.scrollHeight;
}, 100);
}
// 最終メッセージの場合、バナーとフォームを表示
if (message.final) {
setTimeout(() => {
showBannerAndForm();
}, 1000);
}
// 次のメッセージへ
currentIndex++;
if (currentIndex < messages.length) {
setTimeout(displayNextMessage, message.delay);
}
}, typingTime); // 「・・・」表示時間は状況に応じて変化
}
// 最初のメッセージを表示
displayNextMessage();
}
// ページ読み込み後にチャットを開始
window.onload = function() {
// タイピングインジケータを作成
const typingDiv = document.createElement('div');
typingDiv.id = 'typing';
typingDiv.className = 'typing';
const typingAnimation = document.createElement('div');
typingAnimation.className = 'typing-animation';
for (let i = 0; i < 3; i++) {
const span = document.createElement('span');
typingAnimation.appendChild(span);
}
typingDiv.appendChild(typingAnimation);
// グローバル変数に代入
window.typingIndicator = typingDiv;
// タイピングインジケータを初期化
typingIndicator = typingDiv.cloneNode(true);
// チャット開始
displayChat('start');
};