背景:
我正在做一个小型项目,学习如何通过带有JSON文件的原始JavaScript来使用AJAX。我知道我可以使用Jquery,但是我正在学习很长的路要走,Jquery将是下一个。
目标:
我的目标是能够输入城市,一旦我单击按钮,它将呈现我输入城市的当前天气。
问题:
我无法弄清楚,并且正在寻找有关如何从本质上获取该值并将其附加到键上并呈现我正在寻找的所有数据的指导。我的思维过程是引入输入值,并将其与名称键进行比较,如果匹配则呈现结果。我只是无法理解代码中的外观,因此非常感谢任何指导。
我所拥有的:
到目前为止,我可以通过以下文件的硬编码来呈现所需的内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Ajax3 - JSON(external api practice) File</title>
</head>
<body>
<input id="city">
<button id="button">Get Weather</button>
<br><br>
<h1>Weather</h1>
<div id='weather'></div>
<script>
// Create an event listener
document.getElementById('button').addEventListener('click', loadWeather);
function loadWeather(){
// console.log(city);
let xhr = new XMLHttpRequest();
xhr.open('GET', 'weather.json', true);
xhr.onload = function(){
let city = document.getElementById('city').value;
// let keys = Object.keys(weather);
if(this.status == 200){
let weatherTest = JSON.parse(this.responseText);
let result = '';
// weather.forEach((item, index) =>{
result += '<ul>'+
'<li>City: '+JSON.stringify(weatherTest[1].name )+ '</li>' +
'<li>Weather: '+JSON.stringify(weatherTest[1].weather[0].description )+ '</li>' +
'<li>Latitude: '+JSON.stringify(weatherTest[1].coord.lat )+ '</li>' +
'<li>Longitude: '+JSON.stringify(weatherTest[1].coord.lon )+ '</li>' +
'</ul>';
document.getElementById('weather').innerHTML = result;
// })
}
}
xhr.send();
}
//HTTP statuses
// 200: 'Ok'
// 403: 'Forbidden'
// 404: 'Not Found'
</script>
</body>
</html>
这是我正在使用的JSON文件数据:
[{
"coord":{
"lon":-62.08,
"lat":-31.43
},
"sys":{
"message":0.3897,
"country":"AR",
"sunrise":1428575101,
"sunset":1428616476
},
"weather":[
{
"id":802,
"main":"Clouds",
"description":"scattered clouds",
"icon":"03d"
}
],
"base":"stations",
"main":{
"temp":303.364,
"temp_min":303.364,
"temp_max":303.364,
"pressure":1015.65,
"sea_level":1026.91,
"grnd_level":1015.65,
"humidity":42
},
"wind":{
"speed":2.85,
"deg":32.0037
},
"clouds":{
"all":44
},
"dt":1428614645,
"id":3837675,
"name":"San Francisco",
"cod":200
},
{
"coord":{
"lon":-87.65,
"lat":41.85
},
"sys":{
"message":0.014,
"country":"US",
"sunrise":1428578344,
"sunset":1428625502
},
"weather":[
{
"id":501,
"main":"Rain",
"description":"moderate rain",
"icon":"10d"
}
],
"base":"stations",
"main":{
"temp":286.264,
"temp_min":286.264,
"temp_max":286.264,
"pressure":991.9,
"sea_level":1013.82,
"grnd_level":991.9,
"humidity":76
},
"wind":{
"speed":8.25,
"deg":202.004
},
"clouds":{
"all":92
},
"rain":{
"3h":4.61
},
"dt":1428615189,
"id":4887398,
"name":"Chicago",
"cod":200
}
]
答案 0 :(得分:1)
您快到了。在“ forEach”注释的开始处,进行weatherTest以“查找”(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)与“ city”匹配的元素。然后使用从“查找”返回的元素构建“结果”。
希望对您有所帮助!
答案 1 :(得分:1)
就像Todd R所说的那样,您只需要在访问属性之前找到您真正想要的数组元素即可。您也不需要JSON.stringify
,因为这些值已经是字符串或数字,并且可以直接放入HTML中。将它们包装在stringify调用中会导致将引号添加到字符串值,例如。
<li>City: "San Francisco"</li>
示例代码:
xhr.onload = function(){
const city = document.getElementById('city').value;
if(this.status == 200){
let cityWeathers;
try {
cityWeathers = JSON.parse(this.responseText);
} catch (e) {
// JSON not valid, show error message
}
const cityWeather = Array.isArray(cityWeathers) && cityWeathers.find((obj)=>obj.name === city);
if (cityWeather) {
const result = `<ul><li>City: ${cityWeather.name}</li>` +
`<li>Weather: ${cityWeather.weather[0].description}</li>` +
`<li>Latitude: ${cityWeather.coord.lat}</li>` +
`<li>Longitude: ${cityWeather.coord.lon}</li></ul>`;
document.getElementById('weather').innerHTML = result
}
}
}
答案 2 :(得分:1)
这是一个稍有不同的演示,展示了fetch()
作为Vanilla Javascript做Ajax的新方式的使用:
我只获取一次数据(在加载时,然后在数组中扫描与城市匹配的模式。这绑定到输入字段的keyup
事件,使按钮过时了。
var data, ct=document.querySelector('#city'), wt=document.querySelector('#weather');
fetch('https://jsonplaceholder.typicode.com/users')
.then(function(r){r.json().then(function(da){data=da;
document.querySelector('#all').innerHTML=data.map(function(v){return v.address.city}).join(', ');});
})
ct.addEventListener('keyup',function(){
wt.innerHTML='';
var i,n=data.length, rx=new RegExp(ct.value,'i');
for (i=0;i<n;i++) if (rx.test(data[i].address.city)) {
wt.innerHTML=data[i].address.city+': '+data[i].address.zipcode
}
});
<input id="city"><br>
<div id="all"></div>
<h1>City and zip code</h1>
<div id='weather'></div>