介绍
用原生js实现了一个简单的小应用,可以用来查询全国天气,主要实现了以下两个功能
- 点开链接时,页面自动获取当前所在城市,并显示所在城市的天气信息
- 在搜索栏搜索要查询的城市,可显示要查询城市的天气信息
页面效果如下:
预览
请使用高级浏览器查看,预览时若速度较慢,请耐心等待
实现原理
1.用jsonp的方式请求天气数据
由于现有免费天气api较少,在此推荐两个api
这两者都是可以免费使用的,nowapi的免费天气数据可以提供未来7天天气数据,百度地图的api可以提供当前所在地理位置及当日天气详情,结合使用基本可以满足个人需求
百度天气api测试示例:http://api.map.baidu.com/telematics/v3/weather?location=西安&output=json&ak=FK9mkfdQsloEngodbFl4FeY3
newapi天气api测试示例:http://api.k780.com:88/?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json
以上地址仅供测试使用,若需使用,请单独申请key。另外,以上数据接口均支持https
,并支持jsonp
调用
jsonp方式的数据请求函数
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接口
返回数据如下
返回的数据为json
格式,由于我的chrome安装了JSONview
插件,所以可以看到格式化后的json
数据
2.将返回数据展示在页面上
这一步比较简单,主要是用js操作dom,将对应的数据填在页面相应的位置上,除了文字数据外,还需对天气图标进行操作,使之与天气相对应。返回的数据中已含有天气图标url,只需根据返回数据动态改变原有html
中img
的src
即可。但由于以上api所提供的天气图标太丑,所以我采用了自己的天气图标来替换
主要代码
//调用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;
}
实现过程很简单,代码量也不大,有兴趣的朋友可以自己动手试试,当然,若是能给我个star就再好不过了(_)