如何确保图像在 DOM 中完全加载

Posted

技术标签:

【中文标题】如何确保图像在 DOM 中完全加载【英文标题】:How to make sure that an image is fully loaded in the DOM 【发布时间】:2016-02-02 19:10:16 【问题描述】:

我正在将裁剪工具集成到我的应用程序中。 (Jcrop)

我在页面中集成了以下 javascript

$(function() 
  $("#imgInp").change(function()
    readURL(this);
  );
);

function update_crop(coords) 
  var rx = 100/coords.w;
  var ry = 100/coords.h;
  $('#preview').css(
    width: Math.round(rx * 760) + 'px',
    height: Math.round(ry * 1000) + 'px',
    marginLeft: '-' + Math.round(rx * coords.x) + 'px',
    marginTop: '-' + Math.round(ry * coords.y) + 'px'
  );


function readURL(input) 
  if (input.files && input.files[0]) 
    var reader = new FileReader();
    reader.onload = function (e) 
      $('#cropbox').attr('src', e.target.result);
      $('#preview').attr('src', e.target.result);
      $('#cropbox').Jcrop(
        onChange: update_crop,
        onSelect: update_crop,
        setSelect: [0, 0, 500, 500],
        aspectRatio: 10 / 13.15
      );

    
    reader.readAsDataURL(input.files[0]);
 

在我的 html 中,我有以下内容:

<h1>Image to load</h1>
<form id="form1" runat="server">
  <input type='file' id="imgInp" />
</form>

<img id="cropbox" src="#" >
<h4>Preview:</h4>
<div style="width:100px; height:100px; overflow:hidden">
  <img id="preview" src="#" >
</div>

所以基本上我让用户可以上传图片,然后让他可视化要裁剪的区域。

问题是,当我加载第一张图片时,它很好,但是当我第二次加载另一张图片时,img#cropbox 元素中没有改变。

所以基本上$('#cropbox').Jcrop事件在浏览器更改$("#cropbox").attr('src',e.target.result)之前执行

我如何确保只有在执行$("#cropbox").attr('src',e.target.result) 并且图像已完全加载时才执行$('#cropbox').Jcrop

【问题讨论】:

【参考方案1】:

图像元素也有一个加载事件。在设置 src 属性之前,将该函数包装在该图像的加载事件回调中。

$('#cropbox').load(function()
    $('#cropbox').Jcrop(
      onChange: update_crop,
      onSelect: update_crop,
      setSelect: [0, 0, 500, 500],
      aspectRatio: 10 / 13.15
    );
);
$('#cropbox').attr('src', e.target.result);

【讨论】:

抱歉,刚看到这个。回答几乎一样。【参考方案2】:

尝试设置间隔轮询以查看新图像源是否与预期源匹配。

在继续 JCrop 之前,新的图像源(实际)应该与预期的图像源(您设置的那个)匹配。

这是一个简化的例子:

function checkImageLoaded(newImg)

if (newImg == expectedImg)
     $('#cropbox').Jcrop(
        onChange: update_crop,
        onSelect: update_crop,
        setSelect: [0, 0, 500, 500],
        aspectRatio: 10 / 13.15
      );

      //clear the interval
      window.clearInterval(imageInterval);
  


function pollImageSource() 

    //get the new Image source
    //set the expect Image source

    //then check if they match
    var imageInterval = setInterval(function() checkImageLoaded(newImageSource); , 300);

有很多图片插件可以检测图片是否已加载,但我认为没有必要。

此外,David Walsh 具有更强大的轮询机制。

https://davidwalsh.name/javascript-polling

摘录:

// Usage:  ensure element is visible
poll(function() 
    return document.getElementById('lightbox').offsetWidth > 0;
, 2000, 150);

但这可能不起作用,因为您的图像已经加载。您将不得不大量修改该脚本以比较上述图像源。

【讨论】:

【参考方案3】:

我认为您应该使用图像的 onload 事件。它在浏览器完成图像渲染时触发,并且每次图像更改时都会重新开始。

简单如点:

你可以用 jQuery 实现同样的效果: $("img").on("load",function() ....);

(之前有一个几乎相同的答案,抱歉)

【讨论】:

以上是关于如何确保图像在 DOM 中完全加载的主要内容,如果未能解决你的问题,请参考以下文章

页面完全加载后如何执行功能?

如何在对象完全加载到$ scope之前阻止DOM加载?

AngularJS:如何在页面完全加载之前显示预加载或加载?

如何在没有 Ajax Toolkit 的情况下显示加载图像直到 gridview 完全加载?

如何显示尚未完全加载的图像的缩略图

jQuery Mobile:在完全加载时修改 DOM 以使页面高度为 100%