Implementación de un Cuestionario Dinámico con JavaScript y AlertifyJS

Informática5,57 KB

Implementación de un Quiz Interactivo con JavaScript y jQuery

A continuación se presenta y detalla el código estructurado para la creación de un cuestionario interactivo temático (Stranger Things) que gestiona la carga asíncrona de datos desde un archivo JSON mediante la Fetch API, el control de la interfaz mediante jQuery y la presentación de notificaciones modales con AlertifyJS.

1. Variables Globales e Inicialización

Se declaran las variables principales encargadas de almacenar tanto las preguntas cargadas como las selecciones realizadas por el usuario:

let preguntas = [];
let respuestasUsuario = [];

// BOTÓN COMENZAR
$(".boton-iniciar").click(function () {
    $("#pantalla-inicio").addClass("oculto");
    $("#pantalla-quiz").removeClass("oculto");
    cargarPreguntas();
});

2. Carga de Preguntas con Fetch API

La función cargarPreguntas() obtiene los datos desde un archivo externo de forma asíncrona y gestiona posibles excepciones de red:

// CARGAR JSON CON FETCH
function cargarPreguntas() {
    fetch("files/preguntasST.json")
        .then(response => response.json())
        .then(data => {
            preguntas = data.preguntas;
            mostrarPreguntas();
        })
        .catch(error => {
            console.error(error);
            alertify.error("Error al cargar las preguntas");
        });
}

3. Renderizado Dinámico de Preguntas en el DOM

La función mostrarPreguntas() itera sobre el arreglo de preguntas y sus respectivas opciones para generar el marcado HTML necesario:

// MOSTRAR PREGUNTAS
function mostrarPreguntas() {
    let html = "";
    preguntas.forEach((pregunta, indice) => {
        html += `
            <div class="bloque-pregunta">
                <p><strong>Pregunta ${indice + 1}:</strong> ${pregunta.pregunta}</p>
                <div class="opciones">`;
        
        pregunta.opciones.forEach((opcion, indiceOpcion) => {
            html += `
                    <button type="button"
                        class="boton-opcion"
                        data-pregunta="${indice}"
                        data-opcion="${indiceOpcion}">
                        ${opcion}
                    </button>`;
        });
        
        html += `
                </div>
            </div>`;
    });
    $("#todas-preguntas").html(html);
}

4. Selección de Respuestas

Se utiliza la delegación de eventos para registrar la opción escogida por el usuario, actualizando visualmente las clases CSS correspondientes:

// SELECCIONAR RESPUESTA
$(document).on("click", ".boton-opcion", function () {
    let pregunta = $(this).data("pregunta");
    let opcion = $(this).data("opcion");
    
    // QUITAR SELECCIÓN ANTERIOR
    $(`button[data-pregunta='${pregunta}']`).removeClass("seleccionada");
    
    // MARCAR NUEVA SELECCIÓN
    $(this).addClass("seleccionada");
    respuestasUsuario[pregunta] = opcion;
});

5. Validación, Corrección y Asignación de Niveles

Al pulsar el botón de envío, el sistema valida que no existan preguntas sin responder, compara las elecciones con las respuestas correctas, resalta los aciertos o fallos y calcula el nivel obtenido por el usuario:

// COMPROBAR RESPUESTAS
$(".boton-enviar").click(function () {
    // CONTAR PREGUNTAS SIN RESPONDER
    let preguntasSinResponder = 0;
    for (let i = 0; i < preguntas.length; i++) {
        if (respuestasUsuario[i] === undefined) {
            preguntasSinResponder++;
        }
    }

    // VALIDAR
    if (preguntasSinResponder > 0) {
        alertify.alert(
            "Preguntas pendientes",
            `Debes responder todas las preguntas antes de corregir el test.<br><br>
            Te faltan <b>${preguntasSinResponder}</b> pregunta(s) por responder.`
        );
        return;
    }

    let aciertos = 0;
    preguntas.forEach((pregunta, indice) => {
        let correcta = pregunta.correcta;
        let botones = $(`button[data-pregunta='${indice}']`);
        
        botones.each(function () {
            let opcion = $(this).data("opcion");
            
            // MARCAR CORRECTA
            if (opcion == correcta) {
                $(this).addClass("correcta");
            }
            
            // MARCAR INCORRECTA
            if (opcion == respuestasUsuario[indice] && opcion != correcta) {
                $(this).addClass("incorrecta");
            }
        });

        // CONTAR ACIERTOS
        if (respuestasUsuario[indice] == correcta) {
            aciertos++;
        }
    });

    // CALCULAR PORCENTAJE
    let porcentaje = Math.round((aciertos / preguntas.length) * 100);

    // EVALUAR RANGO DE PUNTUACIÓN
    let nivel = "";
    if (porcentaje === 100) {
        nivel = "🏆 NIVEL MAESTRO DEL UPSIDE DOWN";
    } else if (porcentaje >= 80) {
        nivel = "⭐ EXPERTO EN STRANGER THINGS";
    } else if (porcentaje >= 60) {
        nivel = "🔥 FAN DEDICADO";
    } else if (porcentaje >= 40) {
        nivel = "👍 CONOCEDOR";
    } else {
        nivel = "📺 NECESITAS VER MÁS";
    }

    // MOSTRAR RESULTADO
    alertify.alert(
        "Resultado Final",
        `<b>Aciertos:</b> ${aciertos}/${preguntas.length}<br>
        <b>Porcentaje:</b> ${porcentaje}%<br><br>
        <b>${nivel}</b>`
    );
});

Descargar

PDF Word HTML