首页 > 解决方案 > 为什么在 Vue.js 中获取图像宽度有时效果很好,但有时却不行?

问题描述

我想检查上传图像的宽度和高度。所以我用JS来获取那些,但它返回0。有时它可以工作,但通常它不会。我不知道原因,所以请告诉我发生这种情况的原因。

<label class="add-label" title="イメージ追加" v-if="!uploadedImage">
  <i class="material-icons add-rich-image" v-if="!uploadedImage">add</i>
  <input type="file" @change="onFileChange" class="imageBtn" ref="richImage" accept="img/*">
</label>
<div class="richmenu-img-area">
  <img class="richmenu-img" :src="uploadedImage" ref="uploaded" ondragstart="return false">
</div>
onFileChange(e){
  let files = e.target.files || e.dataTransfer.files;
  if(!files[0].type.match(/image.*/)){
    alert("イメージファイルをアップロードしてください。")
    return;
  }
  this.imageFile = files[0]
  this.createImage(files[0]);
},
createImage(file){
  let reader = new FileReader();
  let image = new Image();
  reader.onload = (e) => {
    image.src = e.target.result;
    console.log(image.width)//********************* sometimes ok but sometimes 0
    console.log(image.height)//********************* sometimes ok but sometimes 0
    this.uploadedImage = e.target.result;
  }
  reader.readAsDataURL(file);
},

标签: javascripthtmlcssvue.js

解决方案


问题

要重现您的问题,请使用下面的代码段并按照以下步骤操作:

  1. 上传一个文件。
  2. 上传另一个文件。
  3. 在步骤 1 中上传相同的文件。

const input = document.getElementById('input');

input.addEventListener('change', createImage);


function createImage(e){
  const files = e.target.files || e.dataTransfer.files;

  const reader = new FileReader();
  const image = new Image();
  
  reader.addEventListener('load', function(e){
    image.src = e.target.result;
    console.log(image.width, image.height);
  });
  
  reader.readAsDataURL(files[0]);
}
<input id="input" type="file" accept="image/*">

解释

您应该看到前 2 次上传返回0 0,第三次上传返回正确的图像宽度和高度。

这是因为图像需要在元数据(即宽度和高度)可用之前完全加载。

再次上传相同文件时产生正确结果的原因是因为图像是从之前加载的,并被浏览器保存在缓存中。因此,下次您尝试加载它时,浏览器已经将该信息传递给您的代码。

解决方案

如果您需要在每次上传文件时获取.width和,您应该在加载图像元素时进行监听:.height

const input = document.getElementById('input');

input.addEventListener('change', createImage);


function createImage(e){
  const files = e.target.files || e.dataTransfer.files;

  const reader = new FileReader();
  const image = new Image();

  // Get the image data only after it is loaded.
  image.addEventListener('load', function(e){
    console.log(image.width, image.height);
  });
  
  reader.addEventListener('load', function(e){
    image.src = e.target.result;
  });
  
  reader.readAsDataURL(files[0]);
}
<input id="input" type="file" accept="image/*">


推荐阅读