Ajax學習案例——使用JSONP實現騰訊天氣
注:本次案例實現較爲簡單,這裏捋一下大致思路:
- 到騰訊天氣網站,按F12切換到Network,找到common開頭的一次請求,點擊查看需要傳遞的參數,見下圖
source:代表以何種方式訪問 填 PC / WX
weather_type:代表天氣 forecast_1h 表示未來48小時 forecast_24h 表示未來7天
province:表示省份
city:表示城市 - 調用封裝好的jsonp函數,填入相關信息,此時就可以得到服務器端返回的相關內容
- 用模板引擎(這裏使用的是art-template)拼接到頁面上即可
個人比較容易出錯的有幾個地方就是:
template.defaults.imports.dataFormat = dataFormat;
在格式化時間的時候,要在模板中使用自定義的函數,此時要將函數名暴露出來,不能直接調用函數;- . 後面不能跟變量,變量應該放到 [ ] 中
代碼如下:
<!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">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<title>Document</title>
</head>
<body>
<div class="container">
<table class="table table-striped table-hover" align="center" id="box">
</table>
</div>
<script src="./JSONP封裝完成函數.js"></script>
<script src="./template-web.js"></script>
<!-- 模板 -->
<script type="text/html" id="tpl">
<tr>
<th>時間</th>
<th>溫度</th>
<th>天氣</th>
<th>風向</th>
<th>風力</th>
</tr>
{{each data}}
<tr>
<td>{{dataFormat($value.update_time)}}</td>
<td>{{$value.degree}}</td>
<td>{{$value.weather}}</td>
<td>{{$value.wind_direction}}</td>
<td>{{$value.wind_power}}</td>
</tr>
{{/each}}
</script>
<script>
// 獲取box標籤 用來顯示模板數據的地方s
var box = document.getElementById('box');
// node的語法規則 將dataFormat暴露出來使模板中的數據可以調用此方法
// 第一個dataFormat表示追加的屬性,模板中可以使用的屬性
// 第二個dataFormat表示函數名,調用此函數方法
template.defaults.imports.dataFormat = dataFormat;
// 將返回的時間數據進行格式化
function dataFormat(data){
var year = data.substr(0,4);
var month = data.substr(4,2);
var day = data.substr(6,2);
var hour = data.substr(8,2);
var min = data.substr(10,2);
var sec = data.substr(12,2);
return year + '年' + month + '月' + day + '日' + ' ' + hour + ':' + min + ':' + sec;
}
//調用jsonp方法
jsonp({
url:'https://wis.qq.com/weather/common',
data:{
source:'pc',
weather_type:'forecast_1h',
province: '浙江省',
city: '麗水市'
},
success:function(data){
// 將模板與數據進行拼接
var html = template('tpl',{data:data.data.forecast_1h});
// 將拼接好的html顯示在頁面上
box.innerHTML = html;
}
});
</script>
</body>
</html>
JSONP封裝的js文件如下:
function jsonp(options) {
//動態添加script標籤 使發送請求這一動作變得可控,否則頁面一上來就會被加載
var script = document.createElement('script');
//拼接字符串的變量
var params = '';
//遍歷拿到數據
for (attr in options.data) {
params += '&' + attr + '=' + options.data[attr];
}
//函數名隨機 否則如果有兩個按鈕同時點擊響應同一個函數的話,後面函數返回結果會覆蓋前面函數的返回結果
var attrName = 'script' + Math.random().toString().replace('.', '');
//它已經不是一個全局函數了
///我們要想辦法讓它重新變爲全局函數 .後面不能是個變量哦!
window[attrName] = options.success;
//設置script標籤的src屬性
script.src = options.url + '?callback=' + attrName + params;
//動態添加script標籤
document.body.appendChild(script);
//爲script標籤添加onload事件 此事件是頁面全部加載完畢後才觸發
script.onload = function () {
//頁面加載完畢後移除script標籤,因爲執行完畢後此標籤已沒有意義
document.body.removeChild(script);
}
}