使用高德api实现天气查询

创建应用获取 Key

天气查询-基础 API 文档-开发指南-Web服务 API | 高德地图API

代码编写

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>天气查询</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Microsoft YaHei', sans-serif;
            background: linear-gradient(to bottom, #87CEEB, #1E90FF);
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        
        .container {
            width: 90%;
            max-width: 500px;
            background-color: rgba(255, 255, 255, 0.8);
            border-radius: 10px;
            padding: 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
        }
        
        h1 {
            text-align: center;
            margin-bottom: 20px;
            color: #333;
        }
        
        .search-box {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
        }
        
        .location-select {
            flex: 1;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
            font-size: 16px;
        }
        
        #search-btn {
            padding: 10px 20px;
            border-radius: 5px;
        }
        
        .weather-info {
            display: none;
            padding: 15px;
            background-color: white;
            border-radius: 5px;
            box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
            margin-top: 20px;
        }
        
        .weather-info h2 {
            color: #1E90FF;
            text-align: center;
            margin-bottom: 15px;
        }
        
        .weather-details {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 15px;
            padding: 10px;
        }
        
        .weather-item {
            background-color: #f5f5f5;
            border-radius: 8px;
            padding: 15px;
            text-align: center;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        
        .weather-item h3 {
            color: #333;
            font-size: 14px;
            margin-bottom: 8px;
        }
        
        .weather-item p {
            color: #666;
            font-size: 16px;
            font-weight: bold;
        }
        
        .error-message {
            color: red;
            text-align: center;
            margin-top: 10px;
            display: none;
        }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/xlsx.full.min.js"></script>
</head>
<body>
    <div class="container">
        <h1>天气查询</h1>
        <div class="search-box">
            <select id="province-select" class="location-select">
                <option value="">请选择省份</option>
            </select>
            <select id="city-select" class="location-select" disabled>
                <option value="">请选择城市</option>
            </select>
            <select id="district-select" class="location-select" disabled>
                <option value="">请选择区县</option>
            </select>
            <button id="search-btn">查询</button>
        </div>
        <div id="error-message" class="error-message"></div>
        <div id="weather-info" class="weather-info">
            <h2 id="city-name"></h2>
            <div class="weather-details">
                <div class="weather-item">
                    <h3>天气现象</h3>
                    <p id="weather-desc"></p>
                </div>
                <div class="weather-item">
                    <h3>实时温度</h3>
                    <p id="temperature"></p>
                </div>
                <div class="weather-item">
                    <h3>空气湿度</h3>
                    <p id="humidity"></p>
                </div>
                <div class="weather-item">
                    <h3>风向</h3>
                    <p id="wind-direction"></p>
                </div>
                <div class="weather-item">
                    <h3>风力级别</h3>
                    <p id="wind-speed"></p>
                </div>
                <div class="weather-item">
                    <h3>数据发布时间</h3>
                    <p id="report-time"></p>
                </div>
            </div>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const searchBtn = document.getElementById('search-btn');
            const weatherInfo = document.getElementById('weather-info');
            const errorMessage = document.getElementById('error-message');
            const cityName = document.getElementById('city-name');
            const weatherDesc = document.getElementById('weather-desc');
            const temperature = document.getElementById('temperature');
            const humidity = document.getElementById('humidity');
            const windSpeed = document.getElementById('wind-speed');
            
            // 使用高德地图API,替换为您的密钥 
            // https://console.amap.com/dev/key/app
            const API_KEY = '';
            
            // 省份和城市数据
            let provinces = [];
            let citiesByProvince = {};
            let districtsByCity = {};
            let areaCodeMap = {};
            
            // 加载并解析xlsx文件
            async function loadCityData() {
                try {
                    const response = await fetch('AMap_adcode_citycode.xlsx');
                    const arrayBuffer = await response.arrayBuffer();
                    const data = new Uint8Array(arrayBuffer);
                    const workbook = XLSX.read(data, {type: 'array'});
                    
                    const worksheet = workbook.Sheets[workbook.SheetNames[0]];
                    const jsonData = XLSX.utils.sheet_to_json(worksheet);
                    
                    // 处理数据
                    jsonData.forEach(row => {
                        const name = row['中文名'] || '';
                        const code = String(row['adcode'] || '');
                        
                        if (name && code) {
                            // 添加到区域编码映射
                            areaCodeMap[name] = code;
                            
                            if (code.endsWith('0000')) {
                                // 处理直辖市和省份
                                const isDirectCity = ['北京市', '上海市', '天津市', '重庆市'].includes(name);
                                if (isDirectCity) {
                                    // 直辖市作为城市处理
                                    const province = name.substring(0, 2); // 去掉"市"字
                                    if (!provinces.includes(province)) {
                                        provinces.push(province);
                                        citiesByProvince[province] = [name];
                                    }
                                    // 初始化直辖市的区县数组
                                    districtsByCity[name] = [];
                                } else {
                                    // 普通省份
                                    provinces.push(name);
                                    citiesByProvince[name] = [];
                                }
                            } else if (code.endsWith('00')) {
                                // 市级
                                const provinceCode = code.substring(0, 2) + '0000';
                                const province = jsonData.find(item => 
                                    String(item['adcode']) === provinceCode
                                )?.['中文名'];
                                
                                if (province) {
                                    const provinceName = province.endsWith('市') ? 
                                        province.substring(0, 2) : province;
                                    if (!citiesByProvince[provinceName]) {
                                        citiesByProvince[provinceName] = [];
                                    }
                                    if (!citiesByProvince[provinceName].includes(name)) {
                                        citiesByProvince[provinceName].push(name);
                                    }
                                    districtsByCity[name] = [];
                                }
                            } else {
                                // 区县级
                                const cityCode = code.substring(0, 4) + '00';
                                const city = jsonData.find(item => 
                                    String(item['adcode']) === cityCode
                                )?.['中文名'];
                                
                                // 处理直辖市的区县
                                const provinceCode = code.substring(0, 2) + '0000';
                                const province = jsonData.find(item => 
                                    String(item['adcode']) === provinceCode
                                )?.['中文名'];
                                
                                if (province && ['北京市', '上海市', '天津市', '重庆市'].includes(province)) {
                                    // 直辖市的区县直接添加到市级
                                    if (districtsByCity[province]) {
                                        districtsByCity[province].push(name);
                                    }
                                } else if (city && districtsByCity[city]) {
                                    // 普通城市的区县
                                    districtsByCity[city].push(name);
                                }
                            }
                        }
                    });
                    
                    // 初始化下拉框
                    populateProvinceSelect();
                    console.log('城市数据加载完成');
                    
                } catch (error) {
                    console.error('加载城市数据失败:', error);
                    showError('加载城市数据失败');
                }
            }
            
            // 填充省份下拉框
            function populateProvinceSelect() {
                const provinceSelect = document.getElementById('province-select');
                const citySelect = document.getElementById('city-select');
                const districtSelect = document.getElementById('district-select');
                
                // 清空所有选择
                provinceSelect.innerHTML = '<option value="">请选择省份</option>';
                resetCitySelect();
                resetDistrictSelect();
                
                provinces.sort().forEach(province => {
                    const option = document.createElement('option');
                    option.value = province;
                    option.textContent = province;
                    provinceSelect.appendChild(option);
                });
                
                // 监听省份选择变化
                provinceSelect.addEventListener('change', function() {
                    const selectedProvince = this.value;
                    if (selectedProvince) {
                        populateCitySelect(selectedProvince);
                        // 直辖市不需要在省级查询天气
                        if (!['北京', '上海', '天津', '重庆'].includes(selectedProvince)) {
                            fetchWeather(selectedProvince);
                        }
                    } else {
                        resetCitySelect();
                        resetDistrictSelect();
                    }
                });
            }
            
            // 填充城市下拉框
            function populateCitySelect(province) {
                const citySelect = document.getElementById('city-select');
                
                // 清空城市和区县选择
                resetCitySelect();
                resetDistrictSelect();
                
                citySelect.disabled = false;
                
                citiesByProvince[province].sort().forEach(city => {
                    const option = document.createElement('option');
                    option.value = city;
                    option.textContent = city;
                    citySelect.appendChild(option);
                });
                
                // 如果是直辖市,自动选择第一个城市
                if (['北京', '上海', '天津', '重庆'].includes(province) && citiesByProvince[province].length > 0) {
                    citySelect.value = citiesByProvince[province][0];
                    const selectedCity = citySelect.value;
                    if (selectedCity) {
                        populateDistrictSelect(selectedCity);
                        fetchWeather(selectedCity);
                    }
                }
                
                // 监听城市选择变化
                citySelect.addEventListener('change', function() {
                    const selectedCity = this.value;
                    if (selectedCity) {
                        populateDistrictSelect(selectedCity);
                        fetchWeather(selectedCity);
                    } else {
                        resetDistrictSelect();
                    }
                });
            }
            
            // 添加区县选择处理
            function populateDistrictSelect(city) {
                const districtSelect = document.getElementById('district-select');
                
                // 清空区县选择
                resetDistrictSelect();
                
                if (districtsByCity[city] && districtsByCity[city].length > 0) {
                    districtSelect.disabled = false;
                    
                    districtsByCity[city].sort().forEach(district => {
                        const option = document.createElement('option');
                        option.value = district;
                        option.textContent = district;
                        districtSelect.appendChild(option);
                    });
                }
                
                // 监听区县选择变化
                districtSelect.addEventListener('change', function() {
                    const selectedDistrict = this.value;
                    if (selectedDistrict) {
                        fetchWeather(selectedDistrict);
                    }
                });
            }
            
            // 添加重置函数
            function resetCitySelect() {
                const citySelect = document.getElementById('city-select');
                citySelect.innerHTML = '<option value="">请选择城市</option>';
                citySelect.disabled = true;
            }
            
            function resetDistrictSelect() {
                const districtSelect = document.getElementById('district-select');
                districtSelect.innerHTML = '<option value="">请选择区县</option>';
                districtSelect.disabled = true;
            }
            
            // 修改天气查询函数
            function fetchWeather(area) {
                weatherInfo.style.display = 'none';
                errorMessage.style.display = 'none';
                searchBtn.disabled = true;
                searchBtn.textContent = '查询中...';
                
                const areaCode = areaCodeMap[area];
                
                if (!areaCode) {
                    showError('未找到该地区的编码');
                    searchBtn.disabled = false;
                    searchBtn.textContent = '查询';
                    return;
                }
                
                const weatherUrl = `https://restapi.amap.com/v3/weather/weatherInfo?city=${areaCode}&key=${API_KEY}`;
                
                fetch(weatherUrl)
                    .then(response => response.json())
                    .then(data => {
                        if (data.status === '1' && data.lives && data.lives.length > 0) {
                            displayWeather(data, area);
                        } else {
                            showError('未找到天气信息');
                        }
                    })
                    .catch(error => {
                        showError('查询失败: ' + error.message);
                        console.error('Error:', error);
                    })
                    .finally(() => {
                        searchBtn.disabled = false;
                        searchBtn.textContent = '查询';
                    });
            }
            
            // 更新查询按钮事件监听
            document.addEventListener('click', function(e) {
                if (e.target && e.target.id === 'search-btn') {
                    const citySelect = document.getElementById('city-select');
                    const selectedCity = citySelect.value;
                    
                    if (!selectedCity) {
                        showError('请选择城市');
                        return;
                    }
                    
                    fetchWeather(selectedCity);
                }
            });
            
            // 初始化
            loadCityData();
            
            function updateWeatherInfo() {
                const weatherDetails = document.querySelector('.weather-details');
                weatherDetails.innerHTML = `
                    <div class="weather-item">
                        <h3>天气现象</h3>
                        <p id="weather-desc"></p>
                    </div>
                    <div class="weather-item">
                        <h3>实时温度</h3>
                        <p id="temperature"></p>
                    </div>
                    <div class="weather-item">
                        <h3>空气湿度</h3>
                        <p id="humidity"></p>
                    </div>
                    <div class="weather-item">
                        <h3>风向</h3>
                        <p id="wind-direction"></p>
                    </div>
                    <div class="weather-item">
                        <h3>风力级别</h3>
                        <p id="wind-speed"></p>
                    </div>
                    <div class="weather-item">
                        <h3>数据发布时间</h3>
                        <p id="report-time"></p>
                    </div>
                `;
            }
            
            function displayWeather(data, city) {
                const weatherData = data.lives[0];
                console.log('天气数据:', weatherData); // 调试用
                
                // 更新城市名称
                cityName.textContent = weatherData.city || city;
                
                // 更新所有天气信息
                document.getElementById('weather-desc').textContent = weatherData.weather || '未知';
                document.getElementById('temperature').textContent = `${weatherData.temperature || '--'}°C`;
                document.getElementById('humidity').textContent = `${weatherData.humidity || '--'}%`;
                document.getElementById('wind-direction').textContent = weatherData.winddirection || '未知';
                document.getElementById('wind-speed').textContent = `${weatherData.windpower || '--'} 级`;
                
                // 格式化并显示发布时间
                const reportTime = weatherData.reporttime || '';
                const formattedTime = reportTime ? new Date(reportTime).toLocaleString('zh-CN') : '未知';
                document.getElementById('report-time').textContent = formattedTime;
                
                // 显示天气信息区域
                weatherInfo.style.display = 'block';
            }
            
            function showError(message) {
                errorMessage.textContent = message;
                errorMessage.style.display = 'block';
                weatherInfo.style.display = 'none';
            }
            
            // 更新天气信息展示区域
            updateWeatherInfo();
        });
    </script>
</body>
</html>

效果实现

项目地址

https://github.com/R-K05/weather_inquiry

相关推荐
范文杰2 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪2 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪2 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy3 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom3 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom3 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom3 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom4 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom4 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试
LaoZhangAI5 小时前
2025最全GPT-4o图像生成API指南:官方接口配置+15个实用提示词【保姆级教程】
前端