使用Vanilla Javascript使用REST国家API JSON数据生成多项选择测验。随机排列答案顺序

时间:2018-10-11 02:15:20

标签: javascript json api

enter image description here我正在尝试使用Google Maps API和REST Country API来构建地理游戏/测验。我也将Google Maps功能与REST Country API一起使用。发生的是,在每次刷新页面时,都会从REST国家API中随机加载国家/地区,并生成数据(该信息已隐藏,因此用户仅能获得有关国家/地区的提示)。该地图还将平移到随机国家/地区的中心(仅混合图像,没有国家/地区标签)。这正是我想要发生的事情。

我在Java语言中有一个循环,在多选部分中提取国家(答案),但这只是从一开始就得出的。有没有一种方法可以使标签随机化,并在其中插入正确的答案(countryData.name)?我已经完成了这项工作,但是我的代码一点也不干,第一个选择始终是正确的答案。也不知道如何获得循环随机抽取答案。这是我开始设计和修复点系统之前需要做的最后一件事。抱歉,必须隐藏我的Google API密钥。

const countriesList = document.getElementById("countries");
let gameTitle = document.querySelector(".gameTitle");
let selectedCountry;
let updateScore = document.querySelector(".score");
let guesses = document.querySelector(".wrongAnswers");
let score = 0;
let wrongAnswers = 0;

// Rest Countries
function newQuestion() {
    fetch("https://restcountries.eu/rest/v2/all")
    .then(response => response.json())
    .then(data => initialize(data))
    .catch(error => console.log("Error:", error));

function initialize(countriesData) {
    // Define countries
    countries = countriesData;
    // Create an empty string where you add your option value in at random as a string
    let options = "";
    countries.forEach(country => options += `<option value="${country.alpha3Code}">${country.name}</option>`);
    countriesList.innerHTML = options;
    // Random index of one instance of the API call
    countriesList.selectedIndex = Math.floor(Math.random() * countriesList.length);
    // Set or return the index of the selected value
    // for display card
    displayCountryInfo(countriesList[countriesList.selectedIndex].value);
    // displayCountryInfo(countriesList.value);
}

function displayCountryInfo(countryByAlpha3Code) {
    let addQuestions = document.querySelector(".question");
    const countryData = countries.find(country => country.alpha3Code === countryByAlpha3Code);
    selectedCountry = countryData.name;
    document.querySelector("#flag-container img").src = countryData.flag;
    // If the flag fails to load, display the country name
    document.querySelector("#flag-container img").alt = `flag of ${countryData.name}`;
    document.getElementById("country").innerHTML = countryData.name;
    document.getElementById("capital").innerHTML = countryData.capital;
    document.getElementById("population").innerHTML = countryData.population.toLocaleString("en-US");
    document.getElementById("currencies").innerHTML = countryData.currencies.filter(c => c.name).map(c => `${c.name} (${c.code})`).join(', ');
    let languages = document.getElementById("languages").innerHTML = countryData.languages.filter(l => l.name).map(l => `${l.name}`).join(', ');
    document.getElementById("region").innerHTML = countryData.region;
    document.getElementById("subregion").innerHTML = countryData.subregion;
    document.getElementById("lat-long").innerHTML = countryData.latlng;
    
    initMap(countryData);

    addQuestions.innerHTML = `I am located in ${countryData.subregion}. There are ${countryData.languages.length} language(s) spoken here: ${languages}. My capital city is ${countryData.capital}. What's my name?`;

    function multipleChoice() {
        for (let i = 0; i < 7; i++) {
            let $input = document.querySelector('#inputs');
            $input.innerHTML = $input.innerHTML + `<input id='choice${i}' name='countries' type='radio' onchange='getValue(this)' value='${countries[i].name}'/> ${countries[i].name}`;
        }
    }

    multipleChoice();
}
  
// Access Google Maps API
function initMap(country) {
    // Create a variable 
    let myLatLng = new google.maps.LatLng(country.latlng[0], country.latlng[1]);
    //object literal
    //instantiate map with mapOptions object
    let mapOptions = { 
        center: myLatLng,
        zoom: 5, 
        disableDefaultUI: true,
        mapTypeId: 'satellite',
        heading: 90,
        tilt: 45,
        rotateControl: true,
    }

    let marker = new google.maps.Marker({
        position: myLatLng
    });

    // Create map
    let map = new google.maps.Map(document.getElementById("mapDiv"), mapOptions);
    // Set marker
    marker.setMap(map);
  }

}

newQuestion();

function getValue(element) {
    if (element.value === selectedCountry) {
        score++;
        updateScore.innerHTML = `Score: ${score}`;
        newQuestion();
        if (score === 10) {
            gameTitle.innerHTML = "You Won!";
        }
    } else {
        wrongAnswers++;
        guesses.innerHTML = `Wrong guesses ${wrongAnswers}`
        newQuestion();
        if (wrongAnswers === 3) {
            gameTitle.innerHTML = "Game Over!";
        }
    }
}
body {
    font-family: Helvetica, Arial, sans-serif;
    font-size: 15px;
    background: rgb(51, 45, 45);
    height: 100%; 
    margin: 0; 
    padding: 0;
}
  
p {
    padding: 0 2.5rem 2.5rem;
    margin: 0;
}

h3, .score, .wrongAnswers {
    text-align: center;
}

html {
    font-family: 'Dosis', sans-serif;
    height: 100%;
}

#mapDiv { 
    height: 50%; 
}

#main-container {
    display: none;
    float: right;
    width: 502px;
    margin: 30px auto;
    padding: 0;
  }

#flag-container {
    float: left;
    height: 252px;
    width: 502px;
    background-color: rgb(19, 16, 16);
    border: 10px solid rgb(32, 13, 28);
    box-shadow: 2px 4px 25px rgb(27, 4, 4);
  }

#flag-container img {
    width: 100%;
    height: 100%;
  }

#quiz-container {
    color: white;
    background: rgb(51, 45, 45);
    overflow: hidden;
}

@media screen and (max-width: 768px) {
    body { 
        font-size: 12px; 
    }

    #main-container { 
        width: 342px; 
    }  

    #flag-container { 
        height: 172px;
        width: 50%; 
    }  

    #info-container select { 
        font-size: 12px; font-weight: 600; 
    }
}





  
 

  
 
 
<!DOCTYPE html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>MapApp Quiz</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="main.css">
        <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
        <!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">         -->
    </head>
    <body>
        <div id="mapDiv"><h1></h1></div>
        <div id="root"></div>

        <div id="flag-container">
            <img src="" alt="">
        </div>

        <div id="main-container">
            <div class="card">
                <div id="info-container">
                    <select id="countries"></select>
                    <p>Country: <span id="country"></span></p>
                    <p>Capital: <span id="capital"></span></p>
                    <p>Population: <span id="population"></span></p>
                    <p>Currencies: <span id="currencies"></span></p>
                    <p>Languages: <span id="languages"></span></p>
                    <p>Region: <span id="region"></span></p>
                    <p>Subregion: <span id="subregion"></span></p>
                    <p>Lat/Long: <span id="lat-long"></span></p>
                </div>
            </div>
        </div>

        <div id="quiz-container">
            <h3 class="gameTitle">MapApp Quiz</h3>
                <h5 class="score">Score: 0</h5>
                <h5 class="wrongAnswers">Wrong guesses: 0</h5>
            <p class="question"></p>
            <form id="inputs">
            </form>
        </div>

        <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=[API_KEY]"></script>
        <script src="main.js" async defer></script>
    </body>
</html>

1 个答案:

答案 0 :(得分:1)

好的,所以我不清楚您如何选择“正确”答案,但是让我们假设您有一个国家作为答案,然后是所有国家/地区的列表。您可以像这样列出4个随机国家/地区和正确的国家/地区:

function generateAnswers(answer, allCountries) {
    let wrongCountries = allCountries.filter(country => country.alpha3Code !== answer.alpha3Code); 

    const countOfAnswers = 5;
    const positionOfCorrectAnswer = Math.floor(Math.random() * (countOfAnswers + 1));
    const answers = []; 
    for(let i=0; i< countOfAnswers; i++) {
       if (i === positionOfCorrectAnswer) {
          answers.push(answer);
       } else {
         let randomAnswer = wrongCountries[Math.floor(Math.random() * wrongCountries.length)]; 
          wrongCountries = wrongCountries.filter(country => country.alpha3Code !== randomAnswer.alpha3Code); 
          answers.push({ name: randomAnswer.name, alpha3Code: randomAnswer.alpha3Code } );
       } 
    }
    return answers;
};

好,因此此函数应返回5个国家/地区的数组,包括正确答案和4个随机错误答案。您可以在构建选项并从中构建HTML的代码中调用此代码,而不用使用完整的国家/地区列表。