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

JS货币转换器初始加载不计算默认汇率问题修复

问题根因

初始化不计算、rate相关报错由4个问题导致:

  • 乌克兰央行汇率接口调用错误:原请求拼接的?json=${currency_one}是无效参数,接口固定返回所有非UAH货币兑UAH的汇率列表,本身不包含UAH条目,当find匹配不到目标货币时直接访问rate.rate会触发undefined访问报错。
  • 初始金额输入框无默认值,页面加载时amountEl_one.value为空,计算结果为NaN。
  • HTML结构非法:select标签内嵌套div、svg等非option标签,会导致DOM解析异常,部分场景下取值出错。
  • 缺少反向计算逻辑:仅支持从第一个输入框换算第二个,输入第二个金额时无法反向换算。
修复方案
  1. 修正接口调用逻辑,拉取全量汇率后手动补UAH的基准汇率(1UAH=1UAH),通过交叉汇率计算任意两个货币的兑换比例
  2. 给初始金额设置默认值1,保证首次加载即可出结果
  3. 增加空值判断,匹配不到汇率时直接终止逻辑,避免JS报错
  4. 补全双向计算逻辑,支持两个输入框任意输入自动换算
  5. 清理select内非法嵌套的标签,保证DOM结构合法
修复后完整JS代码
const currencyEl_one = document.getElementById('currency-one');
const currencyEl_two = document.getElementById('currency-two');
const amountEl_one = document.getElementById('amount-one');
const amountEl_two = document.getElementById('amount-two');
const rateEl = document.getElementById('rate');
const swap = document.getElementById('swap');

// 初始化默认金额
amountEl_one.value = 1;

/**
 * 汇率计算
 * @param {boolean} isFromFirst 触发源是否为第一个输入/选择框
 */
function converter(isFromFirst = true) {
  const currency_one = currencyEl_one.value;
  const currency_two = currencyEl_two.value;
  const inputAmount = isFromFirst ? Number(amountEl_one.value) : Number(amountEl_two.value);

  fetch('https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?json')
    .then(res => res.json())
    .then(data => {
      // 补全UAH基准汇率
      data.push({ cc: 'UAH', rate: 1 });
      const sourceRate = data.find(item => item.cc === currency_one);
      const targetRate = data.find(item => item.cc === currency_two);

      // 异常拦截:汇率不存在或输入金额非法时直接返回
      if (!sourceRate || !targetRate || Number.isNaN(inputAmount)) return;

      // 计算交叉汇率
      const exchangeRate = sourceRate.rate / targetRate.rate;
      rateEl.innerText = `1 ${currency_one} = ${exchangeRate.toFixed(4)} ${currency_two}`;

      // 按触发源计算对应金额
      if (isFromFirst) {
        amountEl_two.value = (inputAmount * exchangeRate).toFixed(2);
      } else {
        amountEl_one.value = (inputAmount / exchangeRate).toFixed(2);
      }
    })
    .catch(err => {
      console.error('汇率获取失败', err);
      rateEl.innerText = '汇率加载失败,请检查网络后重试';
    });
}

// 绑定事件
currencyEl_one.addEventListener('change', () => converter(true));
currencyEl_two.addEventListener('change', () => converter(true));
amountEl_one.addEventListener('input', () => converter(true));
amountEl_two.addEventListener('input', () => converter(false));
swap.addEventListener('click', () => {
  const temp = currencyEl_one.value;
  currencyEl_one.value = currencyEl_two.value;
  currencyEl_two.value = temp;
  converter(true);
});

// 页面初始化执行计算
converter();
HTML修正说明

删除currency-one选择框内嵌套的div、svg等非option标签,修正后结构如下:

<select id="currency-one">
  <option class="select-placeholder">Виберите</option>
  <option value="EUR">EUR</option>
  <option value="USD" selected>USD</option>
  <option value="GBP">GBP</option>
  <option value="UAH">UAH</option>
</select>

修复后页面初始化、切换货币、修改任意一侧金额、点击交换按钮均可正常完成换算,不会再出现rate相关报错。

内容的提问来源于stack exchange,提问作者Андрей Хотюн

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 08:06:18