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

修改已加载HTMLImageElement的src是否触发load事件?图片缩放代码求助

Image Scaling & HTMLImageElement load Event Questions

Hey there! Let's tackle your two key questions and the issue you're hitting with your image scaling feature.

Does modifying an HTMLImageElement's src trigger the load event again?

Short answer: Yes, but only if the new src value is different from the current one.

Here's the breakdown:

  • If you set image.src to a new, unique URL (even if the resource is cached), the browser will initiate a load (or pull from cache) and fire the load event once the resource is ready.
  • If you set image.src to the exact same URL it already has, the browser won't re-initiate a load—so no load event fires. This is probably what you're seeing when your image is already loaded.

Why isn't the load event firing when you modify src post-load?

Based on your scenario, the most likely culprit is that you're either:

  1. Reusing the same src value for the image (so the browser skips reloading), or
  2. Trying to listen for the load event after it's already fired (if the cached resource loads instantly, your Observable might miss it).

But here's a better approach for your image scaling goal: you don't need to re-set the src to scale the image. Once the original image loads, you can handle all scaling directly in a canvas, avoiding the load event entirely for subsequent resizes.

Optimized Code for Your 25% Iterative Scaling

Instead of relying on reloading the image, use canvas to iteratively shrink the image until it meets your size requirements:

generateData(data: File) {
  const image = new Image();
  image.src = URL.createObjectURL(data);
  
  return Observable.fromEvent(image, 'load').pipe(
    map(() => {
      let currentWidth = image.width;
      let currentHeight = image.height;
      const targetWidth = /* Define your target width here */;
      const targetHeight = /* Define your target height here */;
      
      // Initialize canvas with original image dimensions
      let canvas = document.createElement('canvas');
      let ctx = canvas.getContext('2d');
      canvas.width = currentWidth;
      canvas.height = currentHeight;
      ctx.drawImage(image, 0, 0);
      
      // Iteratively shrink by 25% until we hit the target size
      while (currentWidth > targetWidth || currentHeight > targetHeight) {
        // Calculate new dimensions (75% of current)
        currentWidth *= 0.75;
        currentHeight *= 0.75;
        
        // Create a temporary canvas for the scaled version
        const tempCanvas = document.createElement('canvas');
        tempCanvas.width = currentWidth;
        tempCanvas.height = currentHeight;
        const tempCtx = tempCanvas.getContext('2d');
        
        // Draw the current canvas onto the temp canvas at the new size
        tempCtx.drawImage(canvas, 0, 0, currentWidth, currentHeight);
        
        // Replace the main canvas with the scaled temp canvas
        canvas = tempCanvas;
      }
      
      // Clean up the object URL to free memory
      URL.revokeObjectURL(image.src);
      
      // Return the final scaled image (adjust format/quality as needed)
      return canvas.toDataURL('image/jpeg', 0.9);
    })
  );
}

Key Notes

  • This approach avoids the load event issue entirely because we only load the original image once.
  • Don't forget to call URL.revokeObjectURL(image.src) after loading to free up browser memory.
  • If you do need to reload an image with a new src, always ensure the URL is unique (even adding a cache-busting query param like ?v=1 if needed) and attach your load listener before setting the src.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:45:12