想做个直接通过JS获取某个城市的天气。本来想通过直接调用中国气象网的接口:
,但是跨域问题一直无法解决,有谁知道请告诉我。因而改调用腾讯接口,部分源码如下:
1 function Weather() {}; 2 3 Weather.prototype = { 4 5 getWeather: function (city, callback) { 6 var that = this, 7 cities = Weather.cityParse(), 8 code = cities[city] ? cities[city] : 125, // 默认使用北京城市 9 url = 'http://mat1.qq.com/weather/inc/minisite2_' + code + '.js'; // 腾讯天气API jsonp接口 10 11 this.createJsonp(url, function (para) { 12 var desc = that.weatherParse(para); // 通过jsonp获取天气相关信息 13 callback(desc); 14 }); 15 }, 16 // jsonp
17 createJsonp: function (url, callback) {
18 var script = document.createElement('script'); 19 script.type = 'text/javascript'; 20 script.src = url; 21 22 script.onreadystatechange = function () { 23 if (script.readyState === 'loaded' || script.readyState === 'complete') { 24 callback(__minisite2__weather__); 25 26 script.onreadystatechange = null; 27 script.onload = null; 28 } 29 }; 30 31 script.onload = function () { 32 callback(__minisite2__weather__); 33 script.onreadystatechange = null; 34 script.onload = null; 35 }; 36 37 document.body.appendChild(script); 38 }, 39 40 weatherParse: function (para) { 41 42 try { 43 var params = para.split(' '); 44 var weather = { 45 city: params[0], 46 temperature: params[1], 47 range: params[2], 48 describe: params[3] 49 }; 50 51 return weather; 52 } catch (e) { 53 54 } 55 } 56 }; 57 // 将城市及其对应代码解析成hash形式 58 Weather.cityParse = function () { 59 var cities = {}, 60 prop, 61 code, 62 item; 63 64 for (prop in this.city) { 65 item = Weather.city[prop]; 66 for (var city in item) { 67 if (city !== '_') { 68 code = item[city]; 69 city = city.slice(0, -1); 70 cities[city] = code; 71 } 72 } 73 } 74 75 return cities; 76 }; 77 78 Weather.city = { 79 "北京市": { 80 "_": 125, 81 "北京市": 125 82 }, 83 "上海市": { 84 "_": 252, 85 "上海市": 252 86 }, 87 "天津市": { 88 "_": 127, 89 "天津市": 127, 90 "塘沽区": 132 91 }, 92 "重庆市" : { 93 "_": 212, 94 "奉节区": 201, 95 "重庆市": 212, 96 "涪陵区": 213 97 }, 98 "香港": { 99 "_": 1,100 "香港": 1101 },102 "澳门": { 103 "_": 2,104 "澳门": 2105 },106 "台湾省": { 107 "_": 280,108 "台北市": 280109 },110 "云南省": { 111 "_": 179,112 "昭通市": 173,113 "丽江市": 174,114 "曲靖市": 175,115 "保山市": 176,116 "大理州": 177,117 "楚雄州": 178,118 "昆明市": 179,119 "瑞丽市": 180,120 "玉溪市": 181,121 "临沧市": 182,122 "思茅市": 184,123 "红河州": 185,124 "文山州": 369,125 "西双版纳州": 370,126 "德宏州": 371,127 "怒江州": 372,128 "迪庆州": 373129 },130 "内蒙古": { 131 "_": 69,132 "呼伦贝尔市": 4,133 "兴安盟": 7,134 "锡林郭勒盟": 16,135 "巴彦淖尔市": 63,136 "包头市": 64,137 "呼和浩特市": 69,138 "锡林浩特市": 99,139 "通辽市": 101,140 "赤峰市": 106,141 "乌海市": 382,142 "鄂尔多斯市": 383,143 "乌兰察布市": 384144 }145 };146 // 主要是些事件处理相关的方法包装147var Util = {
148 addEvent: function (element, type, handler) {
149 if (element.addEventListener) { 150 element.addEventListener(type, handler, false);151 } else if (element.attachEvent) { 152 element.attachEvent('on' + type, handler);153 }154 },155 156 getEvent: function (event) { 157 return event || window.event;158 },159 160 getTarget: function (event) { 161 return event.target || event.srcElement;162 },163 164 getComputedStyle: function (element) { 165 if (element.currentStyle) { 166 return element.currentStyle;167 } else { 168 return document.defaultView.getComputedStyle(element, null);169 }170 },171 172 getBoundingClientRect: function (element) { 173 var scrollTop = document.documentElement.scrollTop;174 var scrollLeft = document.documentElement.scrollLeft;175 176 if (element.getBoundingClientRect) { 177 if (typeof arguments.callee.offset != 'number') { 178 var temp = document.createElement('div');179 temp.style.cssText = 'position: absolute; left: 0; top: 0;';180 document.body.appendChild(temp);181 arguments.callee.offset = -temp.getBoundingClientRect().top - scrollTop;182 document.body.removeChild(temp);183 temp = null;184 }185 186 var rect = element.getBoundingClientRect();187 var offset = arguments.callee.offset;188 189 return { 190 left: rect.left + offset,191 rigth: rect.right + offset,192 top: rect.top + offset,193 bottom: rect.bottom + offset194 };195 } else { 196 var offset = this.getElementOffset(element);197 198 return { 199 left: offset.left - scrollLeft,200 right: offset.left + element.offsetWidth - scrollLeft,201 top: offset.top - scrollTop,202 bottom: offset.top + element.offsetWidth - scrollTop203 };204 }205 },206 207 getElementOffset: function (element) { 208 var actualLeft = element.offsetLeft;209 var actualTop = element.offsetTop;210 var current = element.offsetParent;211 212 while (current !== null) { 213 actualLeft += current.offsetLeft;214 actualTop += current.actualTop;215 current = current.offsetParent;216 }217 218 return { 219 left: actualLeft,220 top: actualTop221 };222 }223 };
HTML页面的代码如下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>weather</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=gbk;" /> 6 <style type="text/css" > 7 #city { 8 width: 150px; 9 heigth: 30px; 10 } 11 #inputCity { 12 position: absolute; 13 width: 130px; 14 heigth: 25px; 15 } 16 </style> 17 </head> 18 <body> 19 <h1>Weather</h1> 20 <fieldset> 21 <legend> 获取时间 </legend> 22 <label for="city">请选择城市:</label> 23 <select name="city" id="city"> 24 <!--<option selected="selected"></option>--> 25 <option>北京</option> 26 <option>大连</option> 27 <option>福州</option> 28 </select> 29 <input type="text" id="inputCity" value = '请输入或选择城市' /> 30 <input type="button" id="getWeather" value="获取天气" /> 31 </fieldset> 32 <div id="showWeather"> 33 34 </div> 35 <script type="text/javascript" src="weather.js"></script> 36 <script> 37 (function(){ 112 113 var city = document.getElementById('city'); 114 var getWeather = document.getElementById('getWeather'); 115 var inputCity = document.getElementById('inputCity'); 116 var tip = inputCity.value; 117 var cities = Weather.cityParse(); 118 119 120 var pos = Util.getBoundingClientRect(city); 121 var volumn = Util.getComputedStyle(city); 122 console.log(pos); 123 124 // 设置输入文本框的位置 125 inputCity.style.left = pos.left + 'px'; 126 inputCity.style.top = pos.top + 'px'; 127 128 Util.addEvent(city, 'change', function (event) { 129 var value = city.options[city.selectedIndex].value; 130 inputCity.value = value; 131 } ); 132 133 Util.addEvent(inputCity, 'focus', function (event) { 134 Util.getTarget(event).select(); 135 } ); 136 137 Util.addEvent(inputCity, 'change', function () { 138 139 var city = inputCity.value; 140 if ( city.slice(-1) === '市') { 141 city = city.slice(0, -1); 142 } 143 if ( city && !cities[city] ) { 144 alert('目前无法获取' + city + '的天气,请输入其它城市'); 145 } else if ( !city ) { 146 inputCity.value = tip; 147 } 148 149 }); 150 151 Util.addEvent(getWeather, 'click', function (event) { 152 var city = inputCity.value; 153 if ( city && !cities[city] ) { 154 alert('目前无法获取' + city + '的天气,请输入其它城市'); 155 return false; 156 } 157 // 天气获取 158 (new Weather()).getWeather(city, function(param){ 159 160 var showWeather = document.getElementById('showWeather'); 161 showWeather.innerHTML = '城市: ' + param.city + 162 '<br /> 温度:' + param.temperature + 163 '<br /> 温度范围:' + param.range + 164 '<br /> 描述:' + param.describe; 165 } ); 166 }); 168 169 })(); 170 </script> 171 </body> 172 </html>