起因
最近在做一个文件上传的功能,要根据一个select中内容的变化,来决定要上传哪些文件。也就是说:
// 伪代码
$('select').change(function() {
var html = '一组上传空间';
$('#upload-container').html(html);
});
对,大概就是这样的一个小功能点。在Chrome和FireFox下跑的都是ok的,但是一旦到了ie下,就会报一个著名问题:“缺少对象”。
补充说明一下,jQuery版本是1.11.3,上传控件是SWFUpload
排查过程
因为渲染的逻辑是通过一个匿名函数传进去的,根据函数栈的调用顺序,最终报出错误的地方其实是change这个函数被调用的地方。由于经验不足,当时我是从最初报error的地方一点点console.log出来的,过程大概如下:
.change()
.html()
.cleanData()
.acceptData()
getAttribute()
可以看到,这是jQuery在.html()方法中,想要清理对象的时候产生的问题。jQuery会对原来DOM下所有元素做一个事件缓存的卸载。当它找到
现象
先撇开业务问题不说,我在遇到这个问题后,在3大浏览器中(Chrome、Firefox、IE),做了一些对比:
其一:console.log(document.getElementById(‘SWFUpload_0’)):
- Chrome: 能找到对应的function,不过随后就会报一个错误:Uncaught TypeError: Cannot use ‘in’ operator to search for ‘rawScopes’ in undefined
- Firefox: 直接找到了
- IE: 直接找到了HTML的DOM对象,也没有报错误
其二:console.log(document.getElementById(‘SWFUpload_0’).getAttribute(‘classid’))(jQuery中真正用到的方法):
- Chrome: null
- Firefox: null
- IE: 报错:缺少对象
从这里比较中可以看出,Firefox是表现最好的,返回我们期望的值,并且不会报错。IE是最耿直的,能拿到就拿,一旦不行就告诉你“缺少对象”(花式虐狗啊),Chrome则是最矫情的,一旦遇到Object(Flash)就报错,但为了让开发者尽量少受困扰,则特殊处理了getAttribute函数,使其不会报错。