You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于JavaScript的日出日落晨昏图片显示故障排查及方案咨询

问题排查与修复方案

让我帮你梳理下代码里导致功能失效的核心问题,再给出针对性的修复和更优的替代实现:

原代码的关键问题

  • 命名冲突:你把img元素的ID设为sunriseI和sunsetI,同时又用相同名称定义函数。由于DOM元素会自动挂载到全局window对象上,这会导致函数定义被DOM元素覆盖,调用时直接出错。
  • 时间比较逻辑错误:你直接拿DOM元素对象(比如dtime、dsunrise)做比较,而不是提取它们的文本内容转换成可比较的时间值。对象之间的引用比较永远不会得到你想要的结果。
  • 调用时机与数据同步问题:mainUpdate函数定义后从未执行,而且img的onload事件触发时,weather对象的日出日落时间可能还没加载完成,导致拿不到有效数据。
  • 逻辑笔误:sunsetI函数里错误地修改了sunriseI.src,而非sunsetI.src,导致日落逻辑错误影响日出图片。
  • 严格相等判断不合理:dtime == dsunset这种精确匹配几乎永远不会触发,因为当前时间很难刚好和日落时间完全一致,应该判断当前时间处于目标时段内。

修复后的代码实现

下面是修正了所有问题的代码,同时优化了逻辑和调用时机:

<!-- 移除img的onload事件,避免提前调用 -->
<img id="sunriseImg" src="images/blank.png" />
<img id="sunsetImg" src="images/blank.png" />

<script>
const doc = document;

// 时钟组件成功回调中,每次刷新都更新时间与晨昏图片
clock({ 
  twentyfour: !!twentyfour, 
  padzero: true, 
  refresh: 5000, 
  success: function(clock) { 
    // 更新页面时间显示
    doc.getElementById('time').textContent = `${clock.hour()}:${clock.minute()}`; 
    doc.getElementById('todate').textContent = `${clock.date()} ${translate[current].month[clock.month()]} ${clock.year()}`; 
    doc.getElementById('today').textContent = translate[current].weekday[clock.day()];
    
    // 每次时钟刷新后同步更新晨昏图片
    updateTwilightImages();
  } 
});

// 工具函数:将"HH:MM"格式的时间转为分钟数,方便比较
function timeToMinutes(timeStr) {
  const [hours, minutes] = timeStr.split(':').map(Number);
  return hours * 60 + minutes;
}

// 核心逻辑:更新晨昏图片
function updateTwilightImages() {
  // 先检查weather数据是否已加载
  if (!weather?.sunriseTimeFormatted || !weather?.sunsetTimeFormatted) {
    console.warn("日出日落数据尚未加载完成");
    return;
  }

  // 获取当前时间、日出日落时间的分钟数
  const currentTime = doc.getElementById('time').textContent;
  const currentMinutes = timeToMinutes(currentTime);
  const sunriseMinutes = timeToMinutes(weather.sunriseTimeFormatted);
  const sunsetMinutes = timeToMinutes(weather.sunsetTimeFormatted);

  // 获取图片元素
  const sunriseImg = doc.getElementById('sunriseImg');
  const sunsetImg = doc.getElementById('sunsetImg');

  // 日出时段逻辑:当前时间 >= 日出时间(可根据需求调整为前后时段)
  sunriseImg.src = currentMinutes >= sunriseMinutes ? 'images/daytwilight.png' : 'images/blank.png';
  
  // 日落时段逻辑:当前时间 >= 日落时间(可根据需求调整为前后时段)
  sunsetImg.src = currentMinutes >= sunsetMinutes ? 'images/nighttwilight.png' : 'images/blank.png';
}

// 如果有weather数据加载完成的回调,可在此处添加触发
// 例如:weather.onLoaded = updateTwilightImages;
</script>

更优的替代实现方案

如果你的需求是基于系统真实时间判断晨昏,并且想灵活设置晨昏时段(比如日出前后30分钟),可以使用原生Date对象实现,摆脱对页面时钟组件的依赖:

<!-- 用单张图片切换,更简洁 -->
<img id="twilightImg" src="images/blank.png" />

<script>
const twilightImg = document.getElementById('twilightImg');
// 从weather对象获取实际的日出日落时间(示例值)
const sunriseTime = weather.sunriseTimeFormatted;
const sunsetTime = weather.sunsetTimeFormatted;

// 工具函数:将"HH:MM"转为当天的Date对象
function getDailyTime(timeStr) {
  const now = new Date();
  const [hours, minutes] = timeStr.split(':').map(Number);
  return new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes);
}

// 判断当前时间是否在目标时间的前后N分钟内
function isInTwilightWindow(targetTimeStr, windowMinutes = 30) {
  const targetDate = getDailyTime(targetTimeStr);
  const now = new Date();
  const windowMs = windowMinutes * 60 * 1000;
  return now >= targetDate - windowMs && now <= targetDate + windowMs;
}

// 更新晨昏图片
function updateTwilight() {
  const isSunriseWindow = isInTwilightWindow(sunriseTime);
  const isSunsetWindow = isInTwilightWindow(sunsetTime);

  if (isSunriseWindow) {
    twilightImg.src = 'images/daytwilight.png';
  } else if (isSunsetWindow) {
    twilightImg.src = 'images/nighttwilight.png';
  } else {
    twilightImg.src = 'images/blank.png';
  }
}

// 初始化调用一次
updateTwilight();
// 每5分钟自动刷新一次(可调整频率)
setInterval(updateTwilight, 5 * 60 * 1000);
</script>

这个方案的优势:

  • 直接使用系统时间,无需依赖第三方时钟组件,更稳定可靠
  • 支持自定义晨昏时段的时间范围,比精确匹配更符合实际需求
  • 代码结构更清晰,封装性更强,便于后续维护和扩展

内容的提问来源于stack exchange,提问作者trueson65

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:20:16