AJAX多图像上传程序在JavaScript中的进度在Firefox中不起作用
这是我的XHTML AJAX图像上传程序的完整版本,几乎可以正常工作。它使用AJAX上传文件,我不支持IE9和更高版本以及Opera11.6和更高版本(IE10和Opera12支持它)。然而,我在Firefox上遇到了麻烦 主要问题是动态地将id附加到目标(甚至将与AJAX多图像上传程序在JavaScript中的进度在Firefox中不起作用,javascript,ajax,file-upload,Javascript,Ajax,File Upload,这是我的XHTML AJAX图像上传程序的完整版本,几乎可以正常工作。它使用AJAX上传文件,我不支持IE9和更高版本以及Opera11.6和更高版本(IE10和Opera12支持它)。然而,我在Firefox上遇到了麻烦 主要问题是动态地将id附加到目标(甚至将与元素[i]相关的i传递到进度事件)。它在Chrome和Opera 12中运行良好,但在Firefox 10中不起作用。事件侦听器位于下面代码的第100行 <?xml version="1.0" encoding="UTF-8"?
元素[i]
相关的i
传递到进度事件)。它在Chrome和Opera 12中运行良好,但在Firefox 10中不起作用。事件侦听器位于下面代码的第100行
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Image Preview</title>
<script type="application/javascript">
//<![CDATA[
function images_name(s)
{
var a = reverse(s);
var b = a.split('.');
var c = reverse(b[1]);
var d = c.toLowerCase();
var e = d.replace(/^\s+|\s+$/g,'');
var f = e.replace(/^-+|-+$/g,'');
var g = f.replace(/ /g,'-');
var h = g.replace(/[--]+/g,'-');
var i = h.replace(/[^a-zA-Z 0-9-]+/g,'');
return i;
}
function images_preview()
{
if (typeof FileReader=='function')
{
var files = document.getElementById('post_files').files;
for (var i = 0; i < files.length; i++)
{
var fr = new FileReader();
fr.file = files[i];
fr.onloadend = function(e)
{
var ip = document.getElementById('images_preview');
var file = e.target.file;
var d1 = document.createElement('div');
var dn = images_name(file.name);
d1.setAttribute('id',dn);
var t = document.createElement('img');
t.setAttribute('alt','Preview');
t.setAttribute('class','left');
t.setAttribute('src',e.target.result);
d1.appendChild(t);
ip.appendChild(d1);
var d2 = document.createElement('div');
var s2 = document.createElement('span');
var s2t = document.createTextNode(file.name);
s2.appendChild(s2t);
d2.appendChild(s2);
d1.appendChild(d2);
var d3 = document.createElement('div');
var s3 = document.createElement('span');
var s3t = document.createTextNode(file.type);
s3.appendChild(s3t);
d3.appendChild(s3);
d1.appendChild(d3);
var d4 = document.createElement('div');
var s4 = document.createElement('span');
var s4t = document.createTextNode(Math.round(file.size/1024)+' KB');
s4.appendChild(s4t);
d4.appendChild(s4);
d1.appendChild(d4);
var d5 = document.createElement('div');
d5.setAttribute('class','progress');
var d6 = document.createElement('div');
d6.setAttribute('class','status');
d5.appendChild(d6);
d1.appendChild(d5);
}
fr.readAsDataURL(files[i]);
}
}
else {alert('Notice: image preview not supported by your browser.');}
}
function images_upload(e)
{
e.preventDefault();
var n = '';
for (var i = 0; i < document.getElementById('post_files').files.length; i++)
{
var file = document.getElementById('post_files').files[i];
n = images_name(file.name);
//alert('n1 = '+n);
var xhr = new XMLHttpRequest();
if (typeof xhr.upload=='object')
{
var upload = xhr.upload;
upload.addEventListener('progress',function(n)
{
return function(e)
{
//alert('n = '+n);
var loader = document.getElementById(n).getElementsByClassName('status')[0];
var p = Math.round((e.loaded * 100) / e.total);
loader.style.width = p+'%';
//alert('n = ' + n);
};
}(n), false);
xhr.open('POST','upload.php');
xhr.setRequestHeader('Cache-Control','no-cache');
xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
xhr.setRequestHeader('X-File-Name',file.name);
xhr.send(file);
}
else {var ns = true;}
}
if (ns) {alert('Error: your browser does not support AJAX file uploads.');}
}
function reverse(s) {return s.split('').reverse().join('');}
window.onload = function()
{
if (window.addEventListener)
{
document.getElementById('form_images').addEventListener('submit',function(e) {images_upload(e);},false);
document.getElementById('post_files').addEventListener('change',function() {images_preview();},false);
}
}
//]]>
</script>
<style type="text/css">
.left {float: left;}
#images_preview > div {border: #000 solid 1px; clear: both; float: right; margin: 8px; overflow: auto; width: 400px;}
#images_preview > div > div {margin-top: 8px;}
#images_preview div.progress, #images_preview div.status {background-color: orange; bottom: 0px; clear: both; height: 2px; position: relative;}
#images_preview div.status {background-color: #0f0; width: 0px;}
#images_preview img {background-color: #ccc; border: #666 solid 1px; margin: 8px; max-height: 100px; max-width: 100px; padding: 4px;}
</style>
</head>
<body>
<form action="" id="form_images" method="post" enctype="multipart/form-data">
<fieldset>
<div><input id="post_files" name="post_files" multiple="multiple" size="128" type="file" /></div>
<div><input name="post_files" type="submit" /></div>
<div id="images_preview"></div>
</fieldset>
</form>
</body>
</html>
图片预览
//
.left{float:left;}
#图像_preview>div{border:#000实心1px;清除:两个;浮动:右;边距:8px;溢出:自动;宽度:400px;}
#图像_preview>div>div{margin top:8px;}
#图像预览分区进度,#图像预览分区状态{背景色:橙色;底部:0px;清除:两者;高度:2px;位置:相对;}
#图像预览分区状态{背景色:#0f0;宽度:0px;}
#图片预览图片{背景颜色:ccc;边框:666实心1px;边距:8px;最大高度:100px;最大宽度:100px;填充:4px;}
一些澄清:首先,我只关心在Firefox、Chrome、Opera 12+和IE 10+中进行这项工作,我将使用单文件非AJAX回退。但现在我只想集中精力让它发挥作用
我已经测试过了,它可以在Opera12+、IE 10、Chrome(无论什么)中使用,但甚至不能在Firefox 14(当前的夜间构建版本)中使用。我非常希望Firefox有一个合理的版本号,可以像示例中的Firefox4一样工作
没有框架,我试着提高质量,解决这样的问题可以帮助我正确地学习真正的JavaScript代码
当我发布JavaScript问题时,人们开始挑出明显应该留在示例中的东西,这是一个AJAX文件上传,所以我不明白为什么有人会删除默认值
function images_upload(e)
{
//...
var n = '';
//...
upload.addEventListener('progress',function(n)
{
return function(e)
{
//using n here
};
}(n), false);
以我唯一的、谦逊的、未经证实的观点:
变量n
在第一个函数中可见(images\u upload(e)
)
您将其传递给第二个函数(未命名的函数(n)
),假设它没有被自动传递的事件对象覆盖(我对此表示怀疑),因此它在这里也是可见的(作为“不同的”n
,请参见下面代码块中的注释):
但是,您不会将其传递给第三个函数(未命名的函数(e)
)。网络上有很多关于此约束的帖子,但我可以想到两种解决方法(待测试,这里仅介绍精神):
更简单的是:
upload.savemyvar=n;
upload.addEventListener('progress',function(e)
{
var n=this.savemyvar;
//using the event e and your variable n here
}, false);
或者,我很确定它应该会起作用(尽管速度很慢):
同样,更简单的是:
eval("upload.addEventListener('progress',function(e)
{
var n="+n+";
//using the event e and your variable n here
//don't forget to \"escape\" correctly if needed ;)
}, false);");
在最后一种情况下,您可能需要将所有eval
代码放在一行,这取决于JS解析器是否需要
结束代码行或仅结束\n
请告知第一个选项是否“按原样”工作,最重要的是,它是否解决了您的问题(因为您的代码与其他浏览器配合使用听起来很奇怪)。尝试一下,稍后会回复,谢谢您的回复!昨晚花了几个小时试图找出问题所在,并尽可能多地覆盖了基础内容……结果发现localhost存在问题,因此测试127.0.0.1和192.168.x.y以及live domains会有所不同。我目前正在为Firefox编写一份bug报告。稍后,如果有机会,我将查看我发布的代码和您发布的内容,并解决这个问题,以免让您挂起。将for循环中的所有内容封装到新函数()中{}修复了变量范围并解决了问题。我基本上接受了你第二个建议的一个稍微不同的版本。我很少使用eval…尽管你的帖子帮助我朝着正确的方向前进,即使这花了我一些时间。谢谢投票表决并接受作为答案。
upload.savemyvar=n;
upload.addEventListener('progress',function(e)
{
var n=this.savemyvar;
//using the event e and your variable n here
}, false);
eval("upload.addEventListener('progress',function(e)
{
return function(e , n)
{
//using the event e and your variable n here
//don't forget to \"escape\" correctly if needed ;)
}(e , "+n+");
}, false);");
eval("upload.addEventListener('progress',function(e)
{
var n="+n+";
//using the event e and your variable n here
//don't forget to \"escape\" correctly if needed ;)
}, false);");