Bienvenido a la Comunidad de Treehouse

¿Quieres colaborar en errores de código? ¿Tienes errores que necesitan comentarios? ¿Buscas un par de ojos adicionales en tu último proyecto? aquí.

¿Buscas aprender algo nuevo?

Treehouse ofrece una prueba gratuita de siete días para estudiantes nuevos. Obtén acceso a miles de horas de contenido y únete a miles de

Inicia tu prueba gratuita

JavaScript Arrays en JavaScript Arrays Multidimensionales Mejorar el cuestionario - Una solución

Andrew Whatmore
sello-máscara
.a{fill-rule:evenodd;}techdegree
Andrew Whatmore
JavaScript Full Stack Estudiante de Techdegree 11,380 Puntos

Solución usando .textContent en lugar de .innerHTML

.textContent

Esta solución usa textContent para añadir contenido a la página en lugar de innerHTML ya que es más seguro. ¿Es esta la forma más eficiente de hacerlo?

Otros cambios:

  • usa el singular 'pregunta' si una pregunta fue correcta, y plural si no.
  • usa un div contenedor 'padre' para todo el contenido añadido
  • el bucle a través del array no ocurre si está vacío.
  • si cero preguntas se añaden correcta o incorrectamente, añade 'Ninguno' bajo el encabezado correspondiente.
  • usa una función para crear los elementos de encabezado, así como una para la lista de preguntas. Llama a la primera dentro de la segunda. Esto significa que no tenemos que repetir el código para crear y añadir los elementos de encabezado.
  • tanto la respuesta proporcionada por el usuario, como la respuesta en el array, se convierten a mayúsculas para hacer las respuestas insensibles a mayúsculas/minúsculas tanto para el usuario como para cualquier desarrollador que añada nuevas preguntas/respuestas al cuestionario.
// 1. Crear una matriz multidimensional para almacenar preguntas y respuestas del cuestionario

const preguntas = [
  [¿Cuántos campeonatos de liga ha ganado el Manchester United?, 20],
  [¿Cuántos goles marcó Eric Cantona para el Manchester United?, 64],
  [¿Quién es el máximo goleador histórico del Manchester United?, Wayne Rooney]
];

// 2. Almacenar el número de preguntas respondidas correctamente
let correctAnswers = 0;

// variable para almacenar la respuesta actual ingresada por el usuario
let answer;
// crear arrays para almacenar las preguntas correctas e incorrectas por separado
const correctQuestions = [];
const incorrectQuestions = [];

/* 
  3. Usar un bucle para recorrer cada pregunta
      - Presentar cada pregunta al usuario
      - Comparar la respuesta del usuario con la respuesta en la matriz
      - Si la respuesta coincide con la respuesta, el número de preguntas respondidas correctamente
        aumenta en 1
*/

para (let i = 0; i < preguntas.longitud; i++) {
  answer = prompt(preguntas[i][0]).toUpperCase();
  // si la respuesta es correcta, incrementa correctAnswers, y añade la pregunta al array correctQuestions
  if (answer === preguntas[i][1].toUpperCase()) {
    correctAnswers++;
    correctQuestions.push(preguntas[i][0]);
  }
  // si la respuesta es incorrecta, añade la pregunta al array incorrectQuestions
  else {
   incorrectQuestions.push(preguntas[i][0]); 
  }
}

// 4. Mostrar el número de respuestas correctas al usuario

// div padre
// crear un div contenedor y añadirlo a la sección principal
let div = documento.createElement('div');
documento.querySelector('main').appendChild(div);

// crear un elemento para mostrar el número de preguntas respondidas correctamente, y añadirlo a la página
let scoreDiv = documento.createElement('h1');
if (correctAnswers == 1) {
  scoreDiv.textContent = `Respondiste ${correctAnswers} pregunta correctamente.`
} else {
  scoreDiv.textContent = `Respondiste ${correctAnswers} preguntas correctamente.`
}
div.appendChild(scoreDiv);

// mostrar cuáles fueron las respuestas correctas e incorrectas
// función para crear un título para cada sección que liste las preguntas correctas o incorrectas, y añadirlo a la página. Pasar el título que queremos
función createTitleElement(title) {
  // crear un elemento de encabezado, y añadir el título que pasamos. Luego añadirlo a la página en el contenedor
  let titleHeading = documento.createElement('h2');
  titleHeading.textContent = title;
  div.appendChild(titleHeading);
}

// bucle a través de los arrays de preguntas correctas e incorrectas y mostrar en la página
// añadir un array de preguntas para recorrer, y listar para mostrar las preguntas
función addQuestionsList(arr) {
  // si el array es correctQuestions, añade este título
  if (arr === correctQuestions) {
    createTitleElement('Respondiste correctamente estas preguntas:');
    // si no, añade este título en su lugar
  } else {
     createTitleElement('Respondiste incorrectamente estas preguntas:');
  }
  // si el array está vacío, añade una etiqueta <p> que diga 'Ninguno'
  if (arr.longitud === 0) {
    let empty = documento.createElement('p');
    empty.estilo.textAlign = 'left';
    empty.textContent = 'Ninguno.';
    div.appendChild(empty);
  } else {
    // si el array no está vacío, añade una lista y recorre el array para añadir las preguntas a ella
    // crear el elemento padre para la lista, & añadirlo a la página
    let mostrarListaPreguntas = documento.createElement('ol');
    div.appendChild(mostrarListaPreguntas);
    // recorrer la matriz e añadir las preguntas a la lista.
    para (let j = 0; j < arr.longitud; j++) {
      // crear el elemento de lista para la pregunta
      let mostrarPregunta = documento.createElement('li');
      mostrarPregunta.textContent = arr[j];
      // luego añadir el elemento de lista al padre <ol>
      mostrarListaPreguntas.appendChild(mostrarPregunta);
    }
  }
}

// ejecutar la función para las matrices de preguntas correctas e incorrectas
addQuestionsList(correctQuestions);
addQuestionsList(incorrectQuestions);

2 Respuestas

Travis Alstrand
sello-máscara
.a{fill-rule:evenodd;}techdegree seal-36
Travis Alstrand
Revisor de Proyectos Treehouse

Hola Andrew Whatmore ! 👋

¡Gracias por compartir tu trabajo increíble aquí!

Desde el punto de vista del rendimiento, la solución original sería ligeramente más eficiente porque realiza una única actualización del DOM, pero en algo de este tamaño es tan pequeño que nunca lo notaríamos.

Sin embargo, tu solución revisada es más segura, más mantenible y maneja los casos extremos mejor, lo que importa mucho más que las pequeñas optimizaciones de rendimiento en una aplicación pequeña como esta.

En proyectos reales, la corrección, claridad y seguridad casi siempre superan la eficiencia bruta del DOM.

En cuanto a .textcontent y innerHTML, en la solución de este video, la entrada del usuario no se inyecta en la cadena HTML, por lo que no es inherentemente malo o peligroso aquí. Dicho esto, tu enfoque es más defensivo y a prueba de futuro. Yo también siempre opto por textContent de forma predeterminada.

¡Muy buen trabajo aquí!

Andrew Whatmore
sello-máscara
.a{fill-rule:evenodd;}techdegree
Andrew Whatmore
JavaScript Full Stack Estudiante de Techdegree 11,380 Puntos

Gracias Travis.

¿Habría sido entonces lo anterior más eficiente si hubiera construido todo el contenido primero (usando textContent como se muestra arriba) y luego hubiera añadido todo a la página de una sola vez (usando una única actualización del DOM), en lugar de pieza por pieza como se muestra arriba?

Travis Alstrand
sello-máscara
.a{fill-rule:evenodd;}techdegree seal-36
Travis Alstrand
Revisor de Proyectos Treehouse

Sí, podría ser más eficiente en una aplicación/configuración mucho más grande, pero tu enfoque actual es absolutamente el correcto para este contexto. Optimizar esta pequeña aplicación para el rendimiento no lograría nada notable de ninguna manera, solo quería responder la pregunta original a fondo. ¡Estás haciendo un trabajo fantástico! ¡Excelente trabajo!