介绍

用原生js实现了一个简单的小应用,可以用来查询全国天气,主要实现了以下两个功能

  • 点开链接时,页面自动获取当前所在城市,并显示所在城市的天气信息
  • 在搜索栏搜索要查询的城市,可显示要查询城市的天气信息

页面效果如下:
天气查询.jpg

预览

请使用高级浏览器查看,预览时若速度较慢,请耐心等待

实现原理

1.用jsonp的方式请求天气数据

由于现有免费天气api较少,在此推荐两个api

这两者都是可以免费使用的,nowapi的免费天气数据可以提供未来7天天气数据,百度地图的api可以提供当前所在地理位置及当日天气详情,结合使用基本可以满足个人需求

以上地址仅供测试使用,若需使用,请单独申请key。另外,以上数据接口均支持https,并支持jsonp调用

jsonp方式的数据请求函数

1
2
3
4
5
6
function jsonp(url){
var script = document.createElement('script');
script.src = url;
document.body.insertBefore(script, document.body.firstChild);
document.body.removeChild(script);
}

将上述天气api地址传入此函数,便可得到天气数据,对于请求所需参数及返回数据格式请参考官方api文档,在此不再赘述。采用jsonp的方式可以完美解决跨域的问题,但需注意一点,使用https协议的站点也只能调用支持https的api接口

返回数据如下

数据.jpg

返回的数据为json格式,由于我的chrome安装了JSONview插件,所以可以看到格式化后的json数据

2.将返回数据展示在页面上

这一步比较简单,主要是用js操作dom,将对应的数据填在页面相应的位置上,除了文字数据外,还需对天气图标进行操作,使之与天气相对应。返回的数据中已含有天气图标url,只需根据返回数据动态改变原有htmlimgsrc即可。但由于以上api所提供的天气图标太丑,所以我采用了自己的天气图标来替换

主要代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//调用jsonp函数请求当前所在城市
jsonp('https://api.map.baidu.com/api?v=2.0&ak=Dv1NMU23dh1sGS9n2tUouDEYY96Dfzh3&s=1&callback=getCity');
window.onload=function(){
//请求天气车数据
btn.onclick=function (){
jsonp(createUrl()[0]);
jsonp(createUrl()[1]);
}
};
function getCity(){
function city(result){
//去掉城市名后的"市"
var city = result.name.substring(0,result.name.length-1);
//请求当前城市的天气数据
jsonp(createUrl(city)[0]);
jsonp(createUrl(city)[1]);
}
var cityName = new BMap.LocalCity();
cityName.get(city);
}
// 数据请求函数
function jsonp(url){
var script = document.createElement('script');
script.src = url;
document.body.insertBefore(script, document.body.firstChild);
document.body.removeChild(script);
}
//数据请求成功回调函数,用于将获取到的数据放入页面相应位置
function getWeather(response) {
var oSpan = document.getElementsByClassName('info');
var data = response.result;
oSpan[0].innerHTML=data[0].citynm;
oSpan[1].innerHTML=data[0].days;
oSpan[2].innerHTML=data[0].week;
oSpan[3].innerHTML=data[0].weather;
oSpan[4].innerHTML=data[0].temperature;
oSpan[5].innerHTML=data[0].winp;
oSpan[6].innerHTML=data[0].wind;
var aDiv = document.getElementsByClassName('future_box');
for(var i=0; i<aDiv.length; i++){
var aSpan = aDiv[i].getElementsByClassName('future_info');
aSpan[0].innerHTML = data[i+1].days;
aSpan[1].innerHTML = data[i+1].week;
aSpan[2].innerHTML =data[i+1].weather;
aSpan[3].innerHTML = data[i+1].temperature;
}
//根据返回数据,替换不同天气图片
changeImg(response);
}
//请求今日天气详细数据回调函数
function getTodayWeather(response){
var oSpan = document.getElementsByClassName('info');
var data = response.results;
oSpan[7].innerHTML=data[0].pm25;
oSpan[8].innerHTML=data[0].index[4].zs;
oSpan[9].innerHTML=data[0].index[1].zs;
oSpan[10].innerHTML=data[0].index[2].zs;
oSpan[11].innerHTML=data[0].index[0].zs;
}
//根据获取到的数据更改页面中相应的图片
function changeImg(data){
var firstImg = document.getElementsByTagName("img")[0];
var firstWeatherId=data.result[0].weatid;
chooseImg(firstWeatherId,firstImg);
var aImg = document.getElementById('future_container').getElementsByTagName('img');
for(var j=0; j<aImg.length; j++){
var weatherId = data.result[j+1].weatid;
chooseImg(weatherId,aImg[j]);
}
}
//选择图片
function chooseImg(id,index){
switch(id){
case '1':
index.src='images/weather_icon/1.png';
break;
case '2':
index.src='images/weather_icon/2.png';
break;
case '3':
index.src='images/weather_icon/3.png';
break;
case '4':
case '5':
case '6':
case '8':
case '9':
case '10':
case '11':
case '12':
case '13':
case '20':
case '22':
case '23':
case '24':
case '25':
case '26':
index.src='images/weather_icon/4.png';
break;
case '7':
index.src='images/weather_icon/6.png';
break;
case '14':
case '15':
case '16':
case '17':
case '18':
case '27':
case '28':
case '29':
index.src='images/weather_icon/5.png';
break;
case '19':
case '21':
case '30':
case '31':
case '32':
case '33':
index.src='images/weather_icon/7.png';
break;
default:
index.src='images/weather_icon/8.png';
}
}
//根据城市名创建请求数据及url
function createUrl(){
var cityName = '';
if(arguments.length == 0) {
cityName = document.getElementById('text').value;
}else{
cityName = arguments[0];
}
var urls = [];
urls[0] = 'https://sapi.k780.com/?app=weather.future&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json&jsoncallback=getWeather&weaid=' + encodeURI(cityName);
urls[1] = 'https://api.map.baidu.com/telematics/v3/weather?output=json&ak=FK9mkfdQsloEngodbFl4FeY3&callback=getTodayWeather&location=' + encodeURI(cityName);
return urls;
}

实现过程很简单,作为自己第一个的小demo,难免有很多不足,若能得到指正或建议,我将不胜感激。