前段时候发布了某天气提示的1.1.0版本。
因我苦静态久矣,故打算利用API重写个“动态页面”。
顺便记录下开发过程,这里是第一篇。

请求API

这里以JMA的半公开API获取东京都天气预报为例。

提示:在使用JMA提供的内容时,请遵守《气象业务法》等相关法律。

fetch('https://www.jma.go.jp/bosai/forecast/data/overview_forecast/130000.json')
.then(
    function(response){
        return response.json()
    }
)
得到的JSON如下。
{
    "publishingOffice":"気象庁",
    "reportDatetime":"2022-05-30T16:37:00+09:00",
    "targetArea":"東京都",
    "headlineText":"",
    "text":" 東日本は高気圧に覆われています。一方、華中から九州の南を通って、日本の東に前線がのびています。\n\n 東京地方は、おおむね晴れています。\n\n 30日は、高気圧に覆われますが、前線上の四国沖に低気圧が発生して東北東に進む見込みです。このため、晴れ夜曇りとなり、夜遅くに雨の降る所があるでしょう。\n\n 31日は、低気圧や前線の影響で、雨昼過ぎから曇りとなる見込みです。伊豆諸島では、雨や雷雨となる所があるでしょう。\n\n【関東甲信地方】\n 関東甲信地方は、晴れや曇りとなっています。\n\n 30日は、高気圧に覆われますが、前線上の四国沖に低気圧が発生して東北東に進む見込みです。このため、晴れや曇りとなり、雨の降る所があるでしょう。\n\n 31日は、低気圧や前線の影響で、曇りや雨となり、雷を伴う所がある見込みです。\n\n 関東地方と伊豆諸島の海上では、30日は波がやや高く、31日はうねりを伴って波が高いでしょう。また、所々で霧が発生する見込みです。船舶は高波や視程障害に注意してください。"
}

这里我们需要用到publishingOfficereportDatetimetargetAreatext四个键。

解析JSON并写入DOM

在HTML新增几个div容器,用来输出数据。

这里使用了MDUI框架。

<div class="mdui-card">
    <div class="mdui-card-primary">
        <div id="kisho-title" class="mdui-card-primary-title">
            <!-- 标题 -->
        </div>
        <div id="kisho-sub" class="mdui-card-primary-subtitle">
            <!-- 副标题 -->
        </div>
    </div>
    <div id="kisho-content" class="mdui-card-content">
        <!-- 内容 -->
    </div>
</div>

用一个函数处理数据:

// 在上面的return response.json()后
.then(function(data){
    var text = data.text;
        targetArea = data.targetArea,
        publishingOffice = data.publishingOffice,
        reportDatetime = new Date(data.reportDatetime);
    document.getElementById('kisho-sub').innerHTML = new Date(reportDatetime).getTime() + ' ' + publishingOffice + '発表';
    document.getElementById('kisho-title').innerHTML = targetArea + '気象情報';
    document.getElementById('kisho-content').innerHTML = text
    }
}

text的值包含\n,会被浏览器无视,故将\n替换成<br />

var text = data.text.replace(/\n/g,'<br />') // 使用g匹配正则

getTime()返回值为时间戳,故将其进行格式化。
这里定义了一个函数用来自定义时区及格式(根据参考自行修改合并)。

function formatDate(time,timezone,format='YY-MM-DD hh:mm:ss'){
    var oldDate = new Date(time);
    var newDate = new Date(
        oldDate.getTime() 
      + oldDate.getTimezoneOffset()*60000 // UTC偏移
      + (3600000*timezone) // 时区偏移
    );
    var year = newDate.getFullYear(),
    month = newDate.getMonth()+1, // 月份从0开始
    day = newDate.getDate(),
    hour = newDate.getHours(),
    min = newDate.getMinutes(),
    sec = newDate.getSeconds();
    var preArr = Array.apply(null,Array(10)).map(function(elem, index) {
        return '0'+index;
    }); // 当数值<10时补上前边的0

    var newTime = format.replace(/YY/g,year)
        .replace(/MM/g,preArr[month]||month)
        .replace(/DD/g,preArr[day]||day)
        .replace(/M/g,month) // 单字不补0,下同
        .replace(/D/g,day)
        .replace(/hh/g,preArr[hour]||hour)
        .replace(/h/g,hour)
        .replace(/mm/g,preArr[min]||min)
        .replace(/ss/g,preArr[sec]||sec);
    return newTime;
}

将原来的getTime()替换成函数。

document.getElementById('kisho-sub').innerHTML = formatDate(new Date(reportDatetime).getTime(),9,'YY年M月D日 hh:mm:ss') + '(JST) ' + publishingOffice + '発表';

Preview预览图

参考