// 天气查询应用 class WeatherApp { constructor() { this.apiEndpoints = [ "https://60s.api.shumengya.top/v2/weather/forecast", "https://60s-cf.viki.moe/v2/weather/forecast" ]; this.currentEndpointIndex = 0; this.init(); } init() { this.bindEvents(); // 页面加载时自动查询北京天气 this.searchWeather('北京'); } bindEvents() { const searchBtn = document.getElementById('searchBtn'); const cityInput = document.getElementById('cityInput'); searchBtn.addEventListener('click', () => { const city = cityInput.value.trim(); if (city) { this.searchWeather(city); } else { this.showError('请输入城市名称'); } }); cityInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { const city = cityInput.value.trim(); if (city) { this.searchWeather(city); } else { this.showError('请输入城市名称'); } } }); // 防止输入框为空时查询 cityInput.addEventListener('input', () => { const searchBtn = document.getElementById('searchBtn'); searchBtn.disabled = !cityInput.value.trim(); }); } async searchWeather(city) { this.showLoading(); for (let i = 0; i < this.apiEndpoints.length; i++) { try { const endpoint = this.apiEndpoints[this.currentEndpointIndex]; const response = await this.fetchWeatherData(endpoint, city); if (response && response.code === 200) { this.displayWeatherData(response.data); return; } } catch (error) { console.warn(`API ${this.apiEndpoints[this.currentEndpointIndex]} 请求失败:`, error); } // 切换到下一个API端点 this.currentEndpointIndex = (this.currentEndpointIndex + 1) % this.apiEndpoints.length; } // 所有API都失败了 this.showError('获取天气信息失败,请检查网络连接或稍后重试'); } async fetchWeatherData(endpoint, city) { const url = `${endpoint}?query=${encodeURIComponent(city)}`; const response = await fetch(url, { method: 'GET', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, timeout: 10000 }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } return await response.json(); } displayWeatherData(data) { const { location, daily_forecast, hourly_forecast } = data; // 显示位置信息 document.getElementById('locationName').textContent = location.name || '未知位置'; document.getElementById('locationDetail').textContent = `${location.province || ''} ${location.city || ''} ${location.county || ''}`.trim(); // 使用第一天的预报数据作为当前天气(今天的天气) const todayWeather = daily_forecast && daily_forecast[0]; if (todayWeather) { // 显示当前天气(使用今天的最高温度) document.getElementById('temperature').textContent = todayWeather.max_temperature; document.getElementById('weatherCondition').textContent = `${todayWeather.day_condition} 转 ${todayWeather.night_condition}`; // 体感温度(使用温度范围) document.getElementById('feelsLike').textContent = `温度范围 ${todayWeather.min_temperature}°C - ${todayWeather.max_temperature}°C`; } else { // 如果没有日预报数据,尝试使用小时预报数据 const currentHour = hourly_forecast && hourly_forecast[0]; if (currentHour) { document.getElementById('temperature').textContent = currentHour.temperature; document.getElementById('weatherCondition').textContent = currentHour.condition; document.getElementById('feelsLike').textContent = `风向: ${currentHour.wind_direction} ${currentHour.wind_power}`; } } // 显示更新时间(使用当前时间) document.getElementById('updateTime').textContent = `${this.formatDate(new Date())} (基于预报数据)`; // 显示天气预报 this.displayForecast(daily_forecast || []); this.showWeatherContainer(); } displayForecast(forecast) { const forecastGrid = document.getElementById('forecastGrid'); forecastGrid.innerHTML = ''; if (!forecast || forecast.length === 0) { forecastGrid.innerHTML = '