`
sd1992585
  • 浏览: 49759 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

多选图片一次上传(as+js) ,仿QQ相册

阅读更多

做上传图片功能的时候,经常会遇到这样一个问题,有时候可能需要一次上传多张图片,而用html中默认的上控件,却只能选定一个文件,且不能对文件的后缀进行筛选。需要一次上传多个文件的需求,往往可以通过添加多个上传控件来予以满足,比如百度空间的相册上传功能就是这样来实现的。不过,要实现对上传文件后缀的过滤,却始终无法通过常规的方法予以实现。
这两个功能真的这么难以实现吗?非也,看看flickr的上传功能即可获得明确的答复。
为什么能实现这样的功能呢?google了一下,谜底就揭晓了。原来,这是利用了flash的若干功能,通过javascript和 actionscript的交互得以实现的。js和as的通讯以前有研究过,所以要实现起来非常简单。再到flash里边f1一下,关于上传方面的相关只是也差不多了解了,因此,接下来的事情的就只是顺水推舟的事情了。
最重要的还是flash代码的完善,最后的成果如下:

Java代码
  1. // MultiUploader.fla   
  2. import flash.net.FileReferenceList;   
  3. import flash.net.FileReference;   
  4. import flash.external.ExternalInterface;   
  5.   
  6. // 设置as中函数和js调用时的映射关系   
  7. ExternalInterface.addCallback("fu_open_dialog"null, openDialog);   
  8. ExternalInterface.addCallback("fu_begin_upload"null, beginUpload);   
  9.   
  10. // 可以通过html页面里边设置FlashVars里边的upload_url来更改上传文件的路径   
  11. var uploadUrl:String = typeof(_root.upload_url) == "undefined" ? "FlashUpload.ashx" : _root.upload_url;   
  12. var listener:Object = new Object();   
  13. // 选择文件后,会视图调用js函数onUploaderSelect,并将文件列表传入进去,便于js进一步做一些逻辑控制   
  14. listener.onSelect = function(fileRefList:FileReferenceList) {   
  15.     ExternalInterface.call("onUploaderSelect", fileRefList.fileList);    
  16. };   
  17.   
  18. var fileRefList:FileReferenceList = null;   
  19. var imageTypes:Object = new Object();   
  20. imageTypes.description = "Images (*.jpg, *.jpeg, *.gif, *.png)"// 上传文件类型说明   
  21. imageTypes.extension = "*.jpg; *.jpeg; *.gif; *.png"// 控制上传文件类型   
  22.   
  23. // 显示文件打开窗口   
  24. function openDialog():Void {   
  25.     if (fileRefList == null) {   
  26.         fileRefList = new FileReferenceList();   
  27.         fileRefList.addListener(listener);   
  28.     }   
  29.     fileRefList.browse([imageTypes]);   
  30. }   
  31. // 开始上传   
  32. function beginUpload():Void {   
  33.     var lis = new Object();   
  34.     // 每上传完一个文件后调用js函数onUploaderComplete   
  35.     lis.onComplete = function(file:FileReference):Void {   
  36.         ExternalInterface.call("onUploaderComplete", file.name);    
  37.     };   
  38.     // 处理上传地址的http状态错误。比如404等。   
  39.     lis.onHTTPError = function(file:FileReference, httpError: Number):Void {   
  40.         ExternalInterface.call("onUploaderHTTPError", httpError, file.name);   
  41.     }   
  42.        
  43.     var list:Array = fileRefList.fileList;   
  44.     var item:FileReference;   
  45.     // 最终还是将文件分单次传到指定上传页面进行处理   
  46.     for(var i:Number = 0; i < list.length; i++) {   
  47.         item = list[i];   
  48.         item.addListener(lis);   
  49.         item.upload(uploadUrl);   
  50.     }   
  51. }  
// MultiUploader.fla
import flash.net.FileReferenceList;
import flash.net.FileReference;
import flash.external.ExternalInterface;

// 设置as中函数和js调用时的映射关系
ExternalInterface.addCallback("fu_open_dialog", null, openDialog);
ExternalInterface.addCallback("fu_begin_upload", null, beginUpload);

// 可以通过html页面里边设置FlashVars里边的upload_url来更改上传文件的路径
var uploadUrl:String = typeof(_root.upload_url) == "undefined" ? "FlashUpload.ashx" : _root.upload_url;
var listener:Object = new Object();
// 选择文件后,会视图调用js函数onUploaderSelect,并将文件列表传入进去,便于js进一步做一些逻辑控制
listener.onSelect = function(fileRefList:FileReferenceList) {
    ExternalInterface.call("onUploaderSelect", fileRefList.fileList); 
};

var fileRefList:FileReferenceList = null;
var imageTypes:Object = new Object();
imageTypes.description = "Images (*.jpg, *.jpeg, *.gif, *.png)"; // 上传文件类型说明
imageTypes.extension = "*.jpg; *.jpeg; *.gif; *.png"; // 控制上传文件类型

// 显示文件打开窗口
function openDialog():Void {
    if (fileRefList == null) {
        fileRefList = new FileReferenceList();
        fileRefList.addListener(listener);
    }
    fileRefList.browse([imageTypes]);
}
// 开始上传
function beginUpload():Void {
    var lis = new Object();
    // 每上传完一个文件后调用js函数onUploaderComplete
    lis.onComplete = function(file:FileReference):Void {
        ExternalInterface.call("onUploaderComplete", file.name); 
    };
    // 处理上传地址的http状态错误。比如404等。
    lis.onHTTPError = function(file:FileReference, httpError: Number):Void {
        ExternalInterface.call("onUploaderHTTPError", httpError, file.name);
    }
    
    var list:Array = fileRefList.fileList;
    var item:FileReference;
    // 最终还是将文件分单次传到指定上传页面进行处理
    for(var i:Number = 0; i < list.length; i++) {
        item = list[i];
        item.addListener(lis);
        item.upload(uploadUrl);
    }
}


至于客户端的处理,只需要将as中自动调用的几个js函数实现即可。最后的页面代码如下:

Java代码
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">   
  2. <html>   
  3. <head>   
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">   
  5. <title>Insert title here</title>   
  6. </head>   
  7. <body>   
  8. <input type="button" value="open" onclick="openUploadDialog();"/>   
  9. <input type="button" value="upload" onclick="uploadFiles();"/>   
  10.   
  11. <div id="flashPanel"></div>   
  12.   
  13. </body>   
  14. <script type="text/javascript">   
  15. var flash = createUploadFlash(document.getElementById('flashPanel'), 'upload.swf''FlashUpload.ashx')   
  16. // 打开文件对话框   
  17. function openUploadDialog() {   
  18.     flash.fu_open_dialog();   
  19. }   
  20. // 上传文件   
  21. function uploadFiles() {   
  22.     flash.fu_begin_upload();   
  23. }   
  24.   
  25. // 选择文件以后   
  26. function onUploaderSelect(list) {   
  27.     alert(list);   
  28. }   
  29.   
  30. // 上传完一个文件以后   
  31. function onUploaderComplete(name) {   
  32.     alert(name);       
  33. }   
  34.   
  35. // 上传文件出错时   
  36. function onUploaderHTTPError(number, name) {   
  37.     switch (number) {   
  38.         case 413:   
  39.             alert("文件" + name + "大于10K,不能上传");   
  40.             break;       
  41.     }   
  42. }   
  43. /**  
  44. * 创建一个flash。主要是在ie7里边需要用鼠标点击才能激活flash,通过动态生成flash的方式可以绕过这一点。  
  45. * @param panel 用来放置flash的div  
  46. * @param flashUrl flash的地址  
  47. * @param uploadUrl 用来出来上传文件的地址  
  48. */  
  49. function createUploadFlash(panel, flashUrl, uploadUrl){   
  50.     var code = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="0" height="0" id="flashObject" align="middle">\   
  51.         <param name="allowScriptAccess" value="sameDomain" />\   
  52.         <param name="movie" value="' + flashUrl + '" />\   
  53.         <param name="quality" value="high" />\   
  54.         <param name="bgcolor" value="#ffffff" />\   
  55.         <param name="FlashVars" value="upload_url=' + uploadUrl + '" />\   
  56.         <embed src="' + flashUrl + '" quality="high" bgcolor="#ffffff" width="0" height="0" name="flashObject" FlashVars="upload_url=' + uploadUrl + '" align="middle" allowScriptAccess="sameDomain" id="flashObject" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />\   
  57.     </object>';   
  58.     panel.innerHTML = code;   
  59.     return window.document.flashObject;   
  60. }   
  61.   
  62. </script>   
  63. </html>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<input type="button" value="open" onclick="openUploadDialog();"/>
<input type="button" value="upload" onclick="uploadFiles();"/>

<div id="flashPanel"></div>

</body>
<script type="text/javascript">
var flash = createUploadFlash(document.getElementById('flashPanel'), 'upload.swf', 'FlashUpload.ashx')
// 打开文件对话框
function openUploadDialog() {
    flash.fu_open_dialog();
}
// 上传文件
function uploadFiles() {
    flash.fu_begin_upload();
}

// 选择文件以后
function onUploaderSelect(list) {
    alert(list);
}

// 上传完一个文件以后
function onUploaderComplete(name) {
    alert(name);    
}

// 上传文件出错时
function onUploaderHTTPError(number, name) {
    switch (number) {
        case 413:
            alert("文件" + name + "大于10K,不能上传");
            break;    
    }
}
/**
* 创建一个flash。主要是在ie7里边需要用鼠标点击才能激活flash,通过动态生成flash的方式可以绕过这一点。
* @param panel 用来放置flash的div
* @param flashUrl flash的地址
* @param uploadUrl 用来出来上传文件的地址
*/
function createUploadFlash(panel, flashUrl, uploadUrl){
    var code = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="0" height="0" id="flashObject" align="middle">\
        <param name="allowScriptAccess" value="sameDomain" />\
        <param name="movie" value="' + flashUrl + '" />\
        <param name="quality" value="high" />\
        <param name="bgcolor" value="#ffffff" />\
        <param name="FlashVars" value="upload_url=' + uploadUrl + '" />\
        <embed src="' + flashUrl + '" quality="high" bgcolor="#ffffff" width="0" height="0" name="flashObject" FlashVars="upload_url=' + uploadUrl + '" align="middle" allowScriptAccess="sameDomain" id="flashObject" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />\
    </object>';
    panel.innerHTML = code;
    return window.document.flashObject;
}

</script>
</html>


这次功能的实现上,在其他方面都还很顺利得以实现,反而是在createUploadFlash这个函数的实现上遇到了一些麻烦。因为最后返回flash对象的时候经常不被正常地识别。如果这段代码不用js生成,那么用 document.flashObject和dobument.getElementById('flashObject')都可以正常识别 flashObject,但动态生成以后,用后者就不能正常被访问到了,可能的原因是加载需要一定的延时,有待研究。

通过这样的方式实现文件上传,一则能解决掉多选问题和文件类型过滤问题,另外也能实现文件的无刷新上传,可以在图片上传的同时去进行别的工作。

分享到:
评论

相关推荐

    android仿QQ相册滑动多选

    在Android开发中,"android仿QQ相册滑动多选"是一个常见的需求,它涉及到UI设计、触摸事件处理、图片加载以及数据管理等多个方面。在这个项目中,开发者需要实现一个可以滑动浏览相册,并且支持多选照片的功能,与QQ...

    Javscript+html仿QQ相册图片拖动排序

    在JavaScript和HTML的世界里,实现一个仿QQ相册的图片拖动排序功能是一项常见的交互设计需求。这个功能允许用户通过直观的手势操作调整图片的顺序,增强了用户体验,尤其是在展示个人相册或者进行图像管理时。以下...

    Android 仿微信QQ多选图片

    在Android开发中,"仿微信QQ多选图片"是一个常见的需求,主要涉及到用户在应用内选择多张图片,类似于微信和QQ中的图片选取功能。这个功能的实现涉及到多个技术点,包括图片的显示、选择状态的管理、权限处理以及...

    仿QQ相册多图片上传控件

    Web仿QQ相册图片上传控件 ,带预览的 ,支持单个图片进度条

    javascript仿QQ相册特效

    JavaScript仿QQ相册特效是一种常见的前端开发技巧,用于在网页上实现类似QQ相册的动态展示效果。这种特效通常涉及到图片预加载、图片滑动、缩放、旋转、动画过渡等交互功能,为用户带来更加生动和丰富的浏览体验。...

    仿QQ相册百度图片滚动浏览

    综上所述,"仿QQ相册百度图片滚动浏览"项目涵盖了图片上传的前端交互设计、图片展示的动态加载效果,以及对用户体验的细致考虑。开发这样一个功能需要深入理解Web前端技术,包括HTML、CSS、JavaScript,以及相关的...

    fragment+viewpager 仿qq界面

    在Android应用开发中,"fragment+viewpager 仿qq界面"是一个常见的需求,它涉及到对Android UI组件的深入理解和巧妙组合。在这个项目中,我们主要会利用`Fragment`和`ViewPager`来创建一个类似QQ应用的多页面切换...

    jquery实现仿qq相册功能

    在本文中,我们将深入探讨如何使用jQuery来实现一个仿QQ相册的功能,这是一个常见的Web开发需求,特别是在构建个人或企业网站时。QQ相册因其直观的界面和丰富的交互性而广受欢迎,因此学习如何复制其核心特性对于...

    仿QQ相册图片上传

    本项目名为"仿QQ相册图片上传",其目标是高度模拟腾讯QQ空间的图片上传体验,包括批量上传和图片旋转等实用特性。这个功能的实现主要依赖于Flash技术,这在早期网络应用中是非常普遍的,因为Flash提供了跨平台的...

    javascript(仿QQ相册的特效)

    在"javascript(仿QQ相册的特效)"这个项目中,我们将探讨如何利用JavaScript来实现类似QQ相册的视觉效果,提升用户体验。QQ相册作为一款流行的在线照片存储和分享平台,其界面设计和交互功能具有一定的参考价值。 ...

    android相册多选功能,可以多选,类似微信的发图片功能

    在Android开发中,实现一个类似于微信的图片多选功能是一项常见的需求。这个功能允许用户从手机相册中选择多张图片进行发送或者其他操作。在这个"android相册多选功能"的示例(Demo)中,我们将探讨如何实现这样一个...

    仿qq相册源码ajax_js

    综上所述,"仿qq相册源码ajax_js"是一个利用AJAX和JavaScript技术实现的动态相册系统,它通过模仿QQ相册的特性,提供了一种无刷新、交互性强的图片浏览和管理体验。这个源码对于学习和实践Web前端开发,尤其是AJAX和...

    html+css+js实现的8款图片展示设计,可用于制作网页版相册

    本资源包含8种不同的图片展示设计,这些设计都是基于这三种语言实现的,适用于创建吸引人的网页版相册。以下是每种设计的核心知识点和实现细节: 1. **响应式图片网格布局**:利用HTML的`&lt;img&gt;`标签结合CSS3的媒体...

    仿QQ相册上的图片上的左右箭头js代码

    在网页设计中,为了提供类似QQ相册的用户体验,我们经常需要实现图片浏览功能,其中包括左右箭头切换图片的效果。这个需求可以通过JavaScript编程语言来实现,结合HTML和CSS,我们可以创建一个具有前后翻页提示的...

    Android 相册图片多选

    在Android开发中,"Android 相册图片多选"是一个常见的功能需求,用户可以在系统相册中选取多张图片以供应用使用。这个功能涉及到的知识点主要包括:Intent、权限管理、图片选择库、图片处理以及回调机制。 1. **...

    Java项目:在线考试系统(单选,多选,判断)(java+Springboot+ssm+mysql+html+maven)

    功能: 学生信息 班级 专业 学号 姓名 在线考试 成绩查询 个人信息 密码修改 教师管理 教师编号 姓名 所教科目 题库管理 单选题 多选题 填空题 判断题,简答题(人工阅卷) 试卷管理 新建试卷 在试库中选择...

    Javascript+html精仿QQ空间相册幻灯片

    JavaScript+HTML精仿QQ空间相册幻灯片是一种常见的网页动态效果,用于展示图片集,让用户可以像在QQ空间浏览相册那样,以平滑过渡的方式查看一组照片。这种技术结合了JavaScript的动态功能和HTML的结构化能力,提供...

    用js实现仿QQ空间相册源码

    【JavaScript实现仿QQ空间相册源码解析】 在互联网应用中,用户对于图片展示的需求日益增长,特别是社交媒体平台,如QQ空间。QQ空间相册以其独特的用户体验和丰富的功能深受用户喜爱。为了提供类似的功能,开发者...

    CSS+JS 仿 QQ 切换 菜单

    ### CSS+JS 仿QQ切换菜单知识点解析 #### 一、概述 本示例通过结合CSS和JavaScript技术,实现了一个类似QQ菜单项切换的效果。它不仅展示了如何利用CSS进行基本的样式设定,还通过JavaScript实现了动态效果,如点击...

Global site tag (gtag.js) - Google Analytics