Carpeta js
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user