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

JavaScript判断图片是否存在的函数首次调用失效问题求助

JavaScript判断图片是否存在的函数首次调用失效问题求助

兄弟,你猜的完全没错!这个问题就是因为JavaScript加载图片是异步操作导致的~

你当前的代码里,创建Image实例后立刻去判断img.height,这时候图片还在加载过程中(甚至可能还没开始加载),所以height还是0,自然会返回原匹配内容;而第二次调用时,浏览器已经把图片缓存下来了,设置src后图片瞬间加载完成,height就能正确获取到,所以函数就正常工作了。

因为你不能用npm包,那我给你两个纯原生JS的解决方案,你可以根据自己的场景选:

方案一:提前预加载所有Emoji图片

如果知道所有可能用到的Emoji名称,可以在页面初始化的时候就把这些图片预加载一遍,把存在的图片记录下来,这样后续replacer调用时直接从缓存的记录里判断就行:

// 用来记录哪些Emoji图片存在的Map
const emojiExists = new Map();

// 预加载Emoji的函数
function preloadEmojis(possibleEmojiNames) {
  possibleEmojiNames.forEach(name => {
    const img = new Image();
    // 加载成功,标记为存在
    img.onload = () => emojiExists.set(name, true);
    // 加载失败(比如图片不存在),标记为不存在
    img.onerror = () => emojiExists.set(name, false);
    img.src = `./img/emoji/${name}.png`;
  });
}

// 假设你有所有可能的Emoji名称列表,替换成你实际的列表就行
preloadEmojis(['smile', 'cry', 'laugh', 'heart']);

// 修改你的replacer函数
this.replacer = function (match, name) {
  // 直接从预加载的记录里判断
  if (emojiExists.get(name)) {
    return `<img class="emoji" src="./img/emoji/${name}.png" title="${name}" height="20px">`;
  } else {
    return match;
  }
};

方案二:异步批量处理替换

如果不知道所有Emoji名称,或者不想预加载太多图片,可以先把文本里所有匹配的Emoji名称收集起来,批量检查图片是否存在,再完成替换:

// 异步替换Emoji的函数,需要传入你的文本和匹配用的正则
function replaceEmojisAsync(text, emojiRegex) {
  // 先找出所有匹配的Emoji名称,去重
  const matches = [...text.matchAll(emojiRegex)];
  const uniqueNames = [...new Set(matches.map(item => item[1]))];

  // 批量检查每个名称对应的图片是否存在
  return Promise.all(uniqueNames.map(name => {
    return new Promise(resolve => {
      const img = new Image();
      img.onload = () => resolve({ name, exists: true });
      img.onerror = () => resolve({ name, exists: false });
      img.src = `./img/emoji/${name}.png`;
    });
  })).then(checkResults => {
    // 把检查结果转成Map方便查询
    const emojiMap = new Map(checkResults.map(result => [result.name, result.exists]));
    // 执行替换
    return text.replace(emojiRegex, (match, name) => {
      if (emojiMap.get(name)) {
        return `<img class="emoji" src="./img/emoji/${name}.png" title="${name}" height="20px">`;
      } else {
        return match;
      }
    });
  });
}

// 使用示例:
// 替换成你实际用来匹配Emoji的正则
const emojiRegex = /:([a-z]+):/g;
// 传入要处理的文本
replaceEmojisAsync("Hello :smile:! How are you :cry:?", emojiRegex).then(updatedText => {
  // 把替换后的文本插入到DOM里,比如:
  document.getElementById('content').innerHTML = updatedText;
});

这样就能解决首次调用失效的问题啦~

备注:内容来源于stack exchange,提问作者Landon Kuehner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 13:20:29