如何在测验中一次显示一个元素

时间:2017-04-25 04:40:42

标签: javascript

我有一个非常简单的测验,询问用户很少有关于他们应该购买什么样的汽车的多项选择问题。

如何一次只显示一个问题?就像添加“下一个”和“上一个”按钮一样。我仍然是Javascript的初学者,我找不到答案。

Here is my code on codepen

<html>
    <head>
    <meta charset="UTF-8">
    <title>What kind of car should I buy?</title>
    <link rel="stylesheet" href="stylesheet.css" type="text/css">
  </head>
  <body>
  <h1>What kind of car should I buy?</h1>
    <p id="suggestion"></p>

  <form id="form" action="">
    <p>What size do you need?</p>
    <input type="radio" name="size" value="compact">Compact<br>
    <input type="radio" name="size" value="mid">Midsize<br>
    <input type="radio" name="size" value="small">Small SUV<br>
    <input type="radio" name="size" value="med">Medium SUV<br>
    <input type="radio" name="size" value="big">Big SUV

    <p>What kind of driving will you be doing?</p>
    <input type="radio" name="drive" value="city">City/suburb driving<br>
    <input type="radio" name="drive" value="mountain">Mountain driving

    <p>Which would you rather have?</p>
    <input type="radio" name="mpg" value="gas">Good gas milage<br>
    <input type="radio" name="mpg" value="performance">Performance

    <p>How much do luxury features matter to you?</p>
    <input type="radio" name="money" value="save">I'd rather save money and have less luxury features<br>
    <input type="radio" name="money" value="luxury">I'd rather spend a little more and have luxury features.

    <p><input id="submit" type="submit" value="submit"></p>
    </form> 

  </body>
</html>

这是我的Javascript

const types = {
  size: {
    compact: 'compact',
    mid: 'mid',
    small: 'small',
    med: 'med',
    big: 'big'
  },
  drive: {
    city: 'city',
    mountain: 'mountain'
  },
  mpg: {
    gas: 'gas',
    performance: 'performance'
  },
  money: {
    save: 'save',
    luxury: 'luxury'
  }
};

const cars = [
  {
    car: 'Prius',
    requirements: {
      size: types.size.compact,
      drive: types.drive.city,
      mpg: types.mpg.gas,
      money: types.money.save
    }
  },
  {
    car: 'BMW i-3',
    requirements: {
      size: types.size.compact,
      drive: types.drive.city,
      mpg: types.mpg.gas,
      money: types.money.luxury
    }
  },
  {
    car: 'Civic SI',
    requirements: {
      size: types.size.compact,
      drive: types.drive.city,
      mpg: types.mpg.performance,
      money: types.money.save
    }
  },
  {
    car: 'BMW 328',
    requirements: {
      size: types.size.compact,
      drive: types.drive.city,
      mpg: types.mpg.performance,
      money: types.money.luxury
    }
  },
  {
    car: 'Mini Cooper All4',
    requirements: {
      size: types.size.compact,
      drive: types.drive.mountain,
      mpg: types.mpg.gas,
      money: types.money.save
    }
  },
  {
    car: 'BMW 328 XI',
    requirements: {
      size: types.size.compact,
      drive: types.drive.mountain,
      mpg: types.mpg.gas,
      money: types.money.luxury
    }
  },
  {
    car: 'BMW XI',
    requirements: {
      size: types.size.compact,
      drive: types.drive.mountain,
      mpg: types.mpg.performance,
      money: types.money.luxury
    }
  },
  {
    car: 'Subaru Impreza',
    requirements: {
      size: types.size.compact,
      drive: types.drive.mountain,
      mpg: types.mpg.performance,
      money: types.money.save
    }
  },

  {
    car: 'Accord Hybrid',
    requirements: {
      size: types.size.mid,
      drive: types.drive.city,
      mpg: types.mpg.gas,
      money: types.money.save
    }
  },
  {
    car: 'BMW 528',
    requirements: {
      size: types.size.mid,
      drive: types.drive.city,
      mpg: types.mpg.performance,
      money: types.money.luxury
    }
  },
  {
    car: 'VW CC',
    requirements: {
      size: types.size.mid,
      drive: types.drive.city,
      mpg: types.mpg.performance,
      money: types.money.save
    }
  },
  {
    car: 'Subaru Legacy',
    requirements: {
      size: types.size.mid,
      drive: types.drive.mountain,
      mpg: types.mpg.gas,
      money: types.money.save
    }
  },
  {
    car: 'BMW 528 XI',
    requirements: {
      size: types.size.mid,
      drive: types.drive.mountain,
      mpg: types.mpg.gas,
      money: types.money.luxury
    }
  },
  {
    car: 'Dodge Charger AWD',
    requirements: {
      size: types.size.mid,
      drive: types.drive.mountain,
      mpg: types.mpg.performance,
      money: types.money.save
    }
  },
  {
    car: 'Audi A4 Quattro',
    requirements: {
      size: types.size.mid,
      drive: types.drive.mountain,
      mpg: types.mpg.performance,
      money: types.money.luxury
    }
  },

  {
    car: 'Rav4 Hybrid',
    requirements: {
      size: types.size.small,
      drive: types.drive.city,
      mpg: types.mpg.gas,
      money: types.money.save
    }
  },
  {
    car: 'Buick Encore',
    requirements: {
      size: types.size.small,
      drive: types.drive.city,
      mpg: types.mpg.gas,
      money: types.money.luxury
    }
  },
  {
    car: 'Mazda CX-5',
    requirements: {
      size: types.size.small,
      drive: types.drive.city,
      mpg: types.mpg.performance,
      money: types.money.save
    }
  },
  {
    car: 'BMW X3',
    requirements: {
      size: types.size.smal,
      drive: types.drive.city,
      mpg: types.mpg.performance,
      money: types.money.luxury
    }
  },
  {
    car: 'Honda CR-V AWD',
    requirements: {
      size: types.size.small,
      drive: types.drive.mountain,
      mpg: types.mpg.gas,
      money: types.money.save
    }
  },
  {
    car: 'Buick Encore AWD',
    requirements: {
      size: types.size.small,
      drive: types.drive.mountain,
      mpg: types.mpg.gas,
      money: types.money.luxury
    }
  },
  {
    car: 'Mazda CX-5 AWD',
    requirements: {
      size: types.size.small,
      drive: types.drive.mountain,
      mpg: types.mpg.performance,
      money: types.money.save
    }
  },
  {
    car: 'BMW X3 AWD',
    requirements: {
      size: types.size.small,
      drive: types.drive.mountain,
      mpg: types.mpg.performance,
      money: types.money.luxury
    }
  },

  {
    car: 'Highlander Hybrid',
    requirements: {
      size: types.size.med,
      drive: types.drive.city,
      mpg: types.mpg.gas,
      money: types.money.save
    }
  },
  {
    car: 'Buick Enclave',
    requirements: {
      size: types.size.med,
      drive: types.drive.city,
      mpg: types.mpg.gas,
      money: types.money.luxury
    }
  },
  {
    car: 'Mazda CX-7',
    requirements: {
      size: types.size.med,
      drive: types.drive.city,
      mpg: types.mpg.performance,
      money: types.money.save
    }
  },
  {
    car: 'BMW X5',
    requirements: {
      size: types.size.med,
      drive: types.drive.city,
      mpg: types.mpg.performance,
      money: types.money.luxury
    }
  },
  {
    car: 'Honda Pilot AWD',
    requirements: {
      size: types.size.med,
      drive: types.drive.mountain,
      mpg: types.mpg.gas,
      money: types.money.save
    }
  },
  {
    car: 'Buick Enclave AWD',
    requirements: {
      size: types.size.med,
      drive: types.drive.mountain,
      mpg: types.mpg.gas,
      money: types.money.luxury
    }
  },
  {
    car: 'Mazda CX-7 AWD',
    requirements: {
      size: types.size.med,
      drive: types.drive.mountain,
      mpg: types.mpg.performance,
      money: types.money.money
    }
  },  
  {
    car: 'BMW X5 AWD',
    requirements: {
      size: types.size.med,
      drive: types.drive.mountain,
      mpg: types.mpg.performance,
      money: types.money.luxury
    }
  },

  {
    car: 'Chevy Tahoe',
    requirements: {
      size: types.size.big,
      drive: types.drive.city,
      mpg: types.mpg.gas,
      money: types.money.save
    }
  },
  {
    car: 'Audi A7',
    requirements: {
      size: types.size.big,
      drive: types.drive.city,
      mpg: types.mpg.gas,
      money: types.money.luxury
    }
  },
  {
    car: 'Chevy Tahoe',
    requirements: {
      size: types.size.big,
      drive: types.drive.city,
      mpg: types.mpg.performance,
      money: types.money.save
    }
  },
  {
    car: 'Cadallac Escalade',
    requirements: {
      size: types.size.big,
      drive: types.drive.city,
      mpg: types.mpg.performance,
      money: types.money.luxury
    }
  },
  {
    car: 'Chevy Tahoe 4WD',
    requirements: {
      size: types.size.big,
      drive: types.drive.mountain,
      mpg: types.mpg.gas,
      money: types.money.save
    }
  },
  {
    car: 'Infiniti QX80 4WD',
    requirements: {
      size: types.size.big,
      drive: types.drive.mountain,
      mpg: types.mpg.gas,
      money: types.money.luxury
    }
  },
  {
    car: 'Ford Expedition 4WD',
    requirements: {
      size: types.size.big,
      drive: types.drive.mountain,
      mpg: types.mpg.performance,
      money: types.money.save
    }
  },
  {
    car: 'Caddalac Escalade 4WD',
    requirements: {
      size: types.size.big,
      drive: types.drive.mountain,
      mpg: types.mpg.performance,
      money: types.money.luxury
    }
  },  
];

const getElements = () => {
  const checkedValue = selector => (
  document.querySelector('input[name = "' + selector + '"]:checked').value
  );

  return {
    size: checkedValue('size'),
    drive: checkedValue('drive'),
    mpg: checkedValue('mpg'),
    money: checkedValue('money'),
    submit: document.getElementById("submit"),
    suggestion: document.getElementById("suggestion")
  };  
}

function submit(event) {
  event.preventDefault();

  const {
    size,
    drive,
    mpg,
    money,
    suggestion
  } = getElements();

  const result = cars.find(({
    requirements
  }) => (
  requirements.size === size &&
  requirements.drive === drive &&
  requirements.mpg === mpg &&
  requirements.money === money
  ));

  suggestion.innerHTML = result.car;
}

document.getElementById("form").addEventListener("submit", submit);

1 个答案:

答案 0 :(得分:0)

有几种方法可以解决这个问题。我尝试解释一个解决方案,但我不能给你一个完整的脚本解决方案,因为我不认为这是StackOverflow的范围。

您可以做的第一件事就是将您的不同问题分组到html标签中。大多数情况下,div标签是一个不错的选择,例如:

<div id="question1">
  <p>What size do you need?</p>
  <input type="radio" name="size" value="compact">Compact<br>
  <input type="radio" name="size" value="mid">Midsize<br>
  <input type="radio" name="size" value="small">Small SUV<br>
  <input type="radio" name="size" value="med">Medium SUV<br>
  <input type="radio" name="size" value="big">Big SUV
</div>

随后,使用一个隐藏你不需要的div的类:

/* CSS */
.hidden {
  display: none;
}

<!-- HTML -->
<div id="question2" class="hidden">...</div>
<div id="question3" class="hidden">...</div>

您可以使用dig标记替换表单,而不是表单,并添加到按钮。第一个按钮(上一个)被隐藏,另一个按钮(下一个)可见。

要显示当前问题,请使用简单的计数器:

// JS
var question = 1;

如果您的“下一个”按钮的ID为“下一个”,请为点击事件添加事件处理程序:

// JS
var nextButton = document.getElementById('next');
nextButton.onClick = function() {
  // Increment the current question
  question++;
  if (question > MAX_QUESTIONS) {
    // Hide the button
    nextButton.className += " hidden";
  }
  // Hide the last question
  document.getElementById('question' + (question - 1)).className += " hidden";
  // Show the current question
  document.getElementById('question' + question).className =
    document.getElementById('question' + question).className.replace("hidden", "");
}

等等。我想你会自己弄清楚其余部分。

请记住,这是纯粹的JS。您还可以使用一些库来使学习JS变得更容易,例如jQuery。

要从dom元素添加和删除类,您还可以实现此处描述的功能:https://jaketrent.com/post/addremove-classes-raw-javascript/