想做个直接通过JS获取某个城市的天气。本来想通过直接调用中国气象网的接口:
http://www.weather.com.cn/weather/101070201.shtml,但是跨域问题一直无法解决,有谁知道请告诉我。因而改调用腾讯接口,部分源码如下:
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 "香港": 1
101 },
102 "澳门": {
103 "_": 2,
104 "澳门": 2
105 },
106 "*省": {
107 "_": 280,
108 "台北市": 280
109 },
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 "迪庆州": 373
129 },
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 "乌兰察布市": 384
144 }
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 + offset
194 };
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 - scrollTop
203 };
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: actualTop
221 };
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>