此博客不再维护,博客已迁移至 https://github.com/purplebamboo/blog/issues
文章目录
  1. 1. 第一种:
  2. 2. 第二种:
  3. 3. 第三种:
  4. 4. 第四种

最近做一个iframe上传的组件,需要限制上传文件的 高度宽度还有 大小。所以研究了下如何使用js获取这些信息。
网上的内容很多,不过很多解决方案都是有问题,下面进行些罗列和分析。
网上的几种解决方案

第一种:

1
2
3
4
var image1 = new Image();
image1.dynsrc = path;
alert(image1.dynsrc);  //这里路径显示真确
alert(image1.fileSize);  //但是这里老是-1 为什么??

老是-1 是因为没有加载完,所以需要onload判断
dynsrc只有ie支持,但是连ie自己都给放弃了,经测试只有ie6支持。7,8都不行。
应该使用src属性。

1
2
3
4
5
6
7
8
var image = new Image();
image.onload =function(){
    var width = image.width;
    var height = image.height;
    var fileSize = image.fileSize;
    //alert(width+'======'+height+"====="+fileSize);
}
image.src = path;

改成这个后,测试 ie系列都支持,但是 在chrome等现代浏览器下是不行的,chrome这些浏览器 不允许读取本地的文件。
这边需要注意的是:最好将onload函数放在image.src = path 的前面,因为image对象下次加载时会优先读取缓存,onload放在后面可能会造成加载太快,来不及触发onload事件。

第二种:

1
2
3
4
5
function getFileSize(filePath)     
{     
    var fso = new ActiveXObject("Scripting.FileSystemObject");     
    alert("文件大小为:"+fso.GetFile(filePath).size);     
}

没有测试 基本没有意义,会弹出安全提示
这种方法可以实现,也容易被开发人员想到,但是需要更改浏览器的安全设置,不然会报“Automation服务器不能创建对象”这个脚本错误。将浏览器的安全设置改为“中”,然后将ActiveX的设置设为启用就OK了,显然不能对用户做出什么要求,所以不推荐。

第三种:

使用html5的 http://caniuse.com/fileapi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    var f = document.getElementById("file").files[0];
    var reader = new FileReader();
    reader.onload = function (e) {
        var data = e.target.result;
        //加载图片获取图片真实宽度和高度
        var image = new Image();
        image.onload=function(){
            var width = image.width;
            var height = image.height;
            alert(width+'======'+height+"====="+f.size);
        };
        image.src= data;
   };
   reader.readAsDataURL(f);

这是使用的html5技术,测试大部分现代浏览器都是可行的。

第四种

经过查看开源组件的源码,发现了一种独特的写法,通过ie的滤镜实现读取文件的宽度高度

1
2
3
4
5
6
7
8
9
10
11
var input = self.input[0]
var temp_document = self.iframe[0].contentDocument || self.iframe[0].document;
input.select();
//确保IE9下,不会出现因为安全问题导致无法访问
input.blur();
var src = temp_document.selection.createRange().text;
var img = $('<img style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=image);width:300px;visibility:hidden;"  />').appendTo('body').getDOMNode();
img.filters.item('DXImageTransform.Microsoft.AlphaImageLoader').src = src;
var width = img.offsetWidth;
var height = img.offsetHeight;
$(img).remove();

此代码需要jquery选择器的支持。这种方法据说最稳定。

通过以上的分析,确定出一种最稳妥的跨浏览器的解决方案为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
window.check=function(){
var input = document.getElementById("file");
if(input.files){
                //读取图片数据
  var f = input.files[0];
  var reader = new FileReader();
  reader.onload = function (e) {
      var data = e.target.result;
      //加载图片获取图片真实宽度和高度
      var image = new Image();
      image.onload=function(){
          var width = image.width;
          var height = image.height;
          alert(width+'======'+height+"====="+f.size);
      };
      image.src= data;
  };
  reader.readAsDataURL(f);
  }else{
  var image = new Image(); 
  image.onload =function(){
      var width = image.width;
      var height = image.height;
      var fileSize = image.fileSize;
      alert(width+'======'+height+"====="+fileSize);
  }
  image.src = input.value;

  }

}

对应的html为:

1
2
<input id="file" type="file">
<input id="Button1" type="button" value="button" onclick="check()">

ps:
这个地址http://www.planeart.cn/?p=1121 使用一种方式可以很方便的提前获取 width和height 非常好
思路是,浏览器在图片未加载完时会通过http协议的header提前知道width和height,所以通过一个计时器,不停检测,快速的得到宽度高度。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// 更新:
// 05.27: 1、保证回调执行顺序:error > ready > load;2、回调函数this指向img本身
// 04-02: 1、增加图片完全加载后的回调 2、提高性能

/**
 * 图片头数据加载就绪事件 - 更快获取图片尺寸
 * @version 2011.05.27
 * @author  TangBin
 * @see   http://www.planeart.cn/?p=1121
 * @param {String}  图片路径
 * @param {Function}  尺寸就绪
 * @param {Function}  加载完毕 (可选)
 * @param {Function}  加载错误 (可选)
 * @example imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
    alert('size ready: width=' + this.width + '; height=' + this.height);
  });
 */
var imgReady = (function () {
  var list = [], intervalId = null,

  // 用来执行队列
  tick = function () {
    var i = 0;
    for (; i < list.length; i++) {
      list[i].end ? list.splice(i--, 1) : list[i]();
    };
    !list.length && stop();
  },

  // 停止所有定时器队列
  stop = function () {
    clearInterval(intervalId);
    intervalId = null;
  };

  return function (url, ready, load, error) {
    var onready, width, height, newWidth, newHeight,
      img = new Image();
    
    img.src = url;

    // 如果图片被缓存,则直接返回缓存数据
    if (img.complete) {
      ready.call(img);
      load && load.call(img);
      return;
    };
    
    width = img.width;
    height = img.height;
    
    // 加载错误后的事件
    img.onerror = function () {
      error && error.call(img);
      onready.end = true;
      img = img.onload = img.onerror = null;
    };
    
    // 图片尺寸就绪
    onready = function () {
      newWidth = img.width;
      newHeight = img.height;
      if (newWidth !== width || newHeight !== height ||
        // 如果图片已经在其他地方加载可使用面积检测
        newWidth * newHeight > 1024
      ) {
        ready.call(img);
        onready.end = true;
      };
    };
    onready();
    
    // 完全加载完毕的事件
    img.onload = function () {
      // onload在定时器时间差范围内可能比onready快
      // 这里进行检查并保证onready优先执行
      !onready.end && onready();
    
      load && load.call(img);
      
      // IE gif动画会循环执行onload,置空onload即可
      img = img.onload = img.onerror = null;
    };

    // 加入队列中定期执行
    if (!onready.end) {
      list.push(onready);
      // 无论何时只允许出现一个定时器,减少浏览器性能损耗
      if (intervalId === null) intervalId = setInterval(tick, 40);
    };
  };
})();

调用例子

1
2
3
imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
  alert('size ready: width=' + this.width + '; height=' + this.height);
});
文章目录
  1. 1. 第一种:
  2. 2. 第二种:
  3. 3. 第三种:
  4. 4. 第四种