227 lines
4.7 KiB
JavaScript
227 lines
4.7 KiB
JavaScript
/*
|
|
EVENTO: DOMContentLoaded
|
|
|
|
Se ejecuta cuando el HTML termina de cargarse
|
|
|
|
Esto asegura que todos los elementos del DOM existan antes de intentar utilizarlos desde JavaScript
|
|
*/
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
|
|
/*
|
|
REFERENCIAS DEL DOM
|
|
|
|
Obtenemos:
|
|
- form -> formulario del chat
|
|
- input -> input donde escribe el usuario
|
|
- chatBox -> contenedor de mensajes
|
|
*/
|
|
|
|
const form = document.getElementById("chat-form");
|
|
const input = document.getElementById("mensaje");
|
|
const chatBox = document.getElementById("chat-box");
|
|
|
|
// Se detiene el script si no existe algún elemento
|
|
|
|
if (!form || !input || !chatBox) return;
|
|
|
|
// EVENTO SUBMIT -> se ejecuta cuando el usuario envía el formulario
|
|
|
|
form.addEventListener("submit", async (e) => {
|
|
|
|
// PREVENIR RECARGA -> Evita que el formulario recargue la página
|
|
|
|
e.preventDefault();
|
|
|
|
// OBTENER MENSAJE
|
|
|
|
const mensaje = input.value.trim();
|
|
|
|
// VALIDAR MENSAJE
|
|
|
|
if (!mensaje) return;
|
|
|
|
// MOSTRAR MENSAJE DEL USUARIO -> Se agrega inmediatamente al chat
|
|
|
|
agregarMensaje("user", mensaje);
|
|
|
|
// LIMPIAR INPUT
|
|
|
|
input.value = "";
|
|
|
|
// MOSTRAR TYPING (ESCRIBIENDO...)
|
|
|
|
mostrarTyping();
|
|
|
|
try {
|
|
|
|
/*
|
|
FETCH AJAX
|
|
|
|
Realizamos una petición POST hacia chatbot.php
|
|
*/
|
|
|
|
const response = await fetch(
|
|
window.location.origin + "/ajax/chatbot.php",
|
|
{
|
|
method: "POST",
|
|
|
|
headers: {
|
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
},
|
|
|
|
/*
|
|
BODY
|
|
|
|
encodeURIComponent():
|
|
- Escapa caracteres especiales
|
|
*/
|
|
|
|
body:
|
|
"mensaje=" + encodeURIComponent(mensaje)
|
|
}
|
|
);
|
|
|
|
// ELIMINAR TYPING
|
|
|
|
removerTyping();
|
|
|
|
// CONVERTIR RESPUESTA JSON
|
|
|
|
const data = await response.json();
|
|
|
|
// ERROR BACKEND -> success === false
|
|
|
|
if (!data.success) {
|
|
|
|
console.error(data.error);
|
|
|
|
agregarMensaje(
|
|
"bot",
|
|
"Ocurrió un error al procesar la consulta."
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
// RESPUESTA IA
|
|
|
|
agregarMensaje(
|
|
"bot",
|
|
data.respuesta
|
|
);
|
|
|
|
} catch (error) {
|
|
|
|
// ERROR FETCH / CONEXIÓN
|
|
|
|
removerTyping();
|
|
|
|
console.error(error);
|
|
|
|
agregarMensaje(
|
|
"bot",
|
|
"Error de conexión."
|
|
);
|
|
}
|
|
});
|
|
|
|
// Evita inyección HTML/XSS
|
|
|
|
function escaparHTML(texto)
|
|
{
|
|
return texto
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'");
|
|
}
|
|
|
|
// AGREGAR MENSAJE VISUAL AL CHAT -> tipo: user / bot
|
|
|
|
function agregarMensaje(tipo, texto)
|
|
{
|
|
|
|
// CREAR DIV
|
|
|
|
const div = document.createElement("div");
|
|
|
|
// CLASE CSS
|
|
|
|
div.className =
|
|
tipo === "user" ? "mensaje-user" : "mensaje-bot";
|
|
|
|
div.innerHTML = `
|
|
<div class="mensaje-contenido">
|
|
${escaparHTML(texto).replace(/\n/g, "<br>")}
|
|
</div>
|
|
`;
|
|
|
|
// INSERTAR MENSAJE
|
|
|
|
chatBox.appendChild(div);
|
|
|
|
// AUTO SCROLL
|
|
|
|
scrollBottom();
|
|
}
|
|
|
|
// MOSTRAR TYPING
|
|
|
|
function mostrarTyping()
|
|
{
|
|
const div = document.createElement("div");
|
|
|
|
div.id = "typing";
|
|
|
|
div.className = "mensaje-bot";
|
|
|
|
div.innerHTML = `
|
|
<div class="mensaje-contenido">
|
|
Escribiendo...
|
|
</div>
|
|
`;
|
|
|
|
chatBox.appendChild(div);
|
|
|
|
scrollBottom();
|
|
}
|
|
|
|
// ELIMINAR TYPING
|
|
|
|
function removerTyping()
|
|
{
|
|
const typing = document.getElementById("typing");
|
|
|
|
if (typing) {
|
|
typing.remove();
|
|
}
|
|
}
|
|
|
|
// AUTO SCROLL -> Baja automáticamente el scroll del chat
|
|
|
|
function scrollBottom()
|
|
{
|
|
chatBox.scrollTop = chatBox.scrollHeight;
|
|
}
|
|
});
|
|
|
|
/*
|
|
EVENTO: load
|
|
|
|
Se ejecuta cuando toda la página termina de cargar:
|
|
HTML + CSS + imágenes + recursos
|
|
|
|
Se usa para restaurar el scroll abajo al refrescar la página
|
|
*/
|
|
|
|
window.addEventListener("load", () => {
|
|
|
|
const chatBox = document.getElementById("chat-box");
|
|
|
|
if (chatBox) {
|
|
|
|
chatBox.scrollTop = chatBox.scrollHeight;
|
|
}
|
|
}); |