HTML5 拖拽上传图片实例
因为标题写的是实例,所以本次就不做讲解了,因为这个实例我也算是东拼西凑整出来的,参考了大概5、6款拖拽上传的插件和demo,然后把其中好的地方挑出来,最后就成了这么一个实例,一起来看下吧(地址不能保证长久有效,如果失效请在文章最后点击demo下载):http://hoorayos.caifutang.com/dropupload.html
界面样式我是参考了一个国外的相册网站,改动不大,只是把鸟语转换成中文,以及上传时的样式也进行了改动,之所以选这个的原因就是,我很容易做扩展,它支持3种方式添加图片,一种拖拽上传,一种常规的选择文件上传,另外的就是添加网络图片。它很巧妙的把三种上传模式整合到了一起,而且你可以用IE浏览器浏览下,如果不支持HTML5,是没有拖拽上传图片的提示的,如图:
拖拽上传最重要的就是js部分的代码,它实现了70%的功能,另外30%仅仅是把图片信息提交到后台,然后做对应的处理,比如压缩啊,裁剪啊云云。所以先来看下js实现代码吧。
$().ready( function (){ if ($.browser.safari || $.browser.mozilla){ $( '#dtb-msg1 .compatible' ).show(); $( '#dtb-msg1 .notcompatible' ).hide(); $( '#drop_zone_home' ).hover( function (){ $( this ).children( 'p' ).stop().animate({top: '0px' },200); }, function (){ $( this ).children( 'p' ).stop().animate({top: '-44px' },200); }); //功能实现 $(document).on({ dragleave: function (e){ e.preventDefault(); $( '.dashboard_target_box' ).removeClass( 'over' ); }, drop: function (e){ e.preventDefault(); //$('.dashboard_target_box').removeClass('over'); }, dragenter: function (e){ e.preventDefault(); $( '.dashboard_target_box' ).addClass( 'over' ); }, dragover: function (e){ e.preventDefault(); $( '.dashboard_target_box' ).addClass( 'over' ); } }); var box = document.getElementById( 'target_box' ); box.addEventListener( "drop" , function (e){ e.preventDefault(); //获取文件列表 var fileList = e.dataTransfer.files; var img = document.createElement( 'img' ); //检测是否是拖拽文件到页面的操作 if (fileList.length == 0){ $( '.dashboard_target_box' ).removeClass( 'over' ); return ; } //检测文件是不是图片 if (fileList[0].type.indexOf( 'image' ) === -1){ $( '.dashboard_target_box' ).removeClass( 'over' ); return ; } if ($.browser.safari){ //Chrome8+ img.src = window.webkitURL.createObjectURL(fileList[0]); } else if ($.browser.mozilla){ //FF4+ img.src = window.URL.createObjectURL(fileList[0]); } else { //实例化file reader对象 var reader = new FileReader(); reader.onload = function (e){ img.src = this .result; $(document.body).appendChild(img); } reader.readAsDataURL(fileList[0]); } var xhr = new XMLHttpRequest(); xhr.open( "post" , "test.php" , true ); xhr.setRequestHeader( "X-Requested-With" , "XMLHttpRequest" ); xhr.upload.addEventListener( "progress" , function (e){ $( "#dtb-msg3" ).hide(); $( "#dtb-msg4 span" ).show(); $( "#dtb-msg4" ).children( 'span' ).eq(1).css({width: '0px' }); $( '.show' ).html( '' ); if (e.lengthComputable){ var loaded = Math.ceil((e.loaded / e.total) * 100); $( "#dtb-msg4" ).children( 'span' ).eq(1).css({width:(loaded*2)+ 'px' }); } }, false ); xhr.addEventListener( "load" , function (e){ $( '.dashboard_target_box' ).removeClass( 'over' ); $( "#dtb-msg3" ).show(); $( "#dtb-msg4 span" ).hide(); var result = jQuery.parseJSON(e.target.responseText); alert(result.filename); $( '.show' ).append(result.img); }, false ); var fd = new FormData(); fd.append( 'xfile' , fileList[0]); xhr.send(fd); }, false ); } else { $( '#dtb-msg1 .compatible' ).hide(); $( '#dtb-msg1 .notcompatible' ).show(); } }); |
开始我是先判断浏览器类型,因为刚才介绍过,不同浏览器看到的是不同界面。主要实现代码是从“功能实现”开始的,这块具体为何这样操作,原理是什么,我就不多说了,大家可以参考下这篇文章:《人人网首页拖拽上传详解(HTML5 Drag&Drop、FileReader API、formdata)》,不过ajax上传部分的代码还是有点不一样的,因为人人那个似乎有点麻烦,我就另寻途径了。
最后就是上传部分的PHP代码了,这里我只是提供个参考,你可以根据项目的需求来自己编写。
$r = new stdClass(); header( 'content-type: application/json' ); $maxsize = 10; //Mb if ( $_FILES [ 'xfile' ][ 'size' ] > ( $maxsize * 1048576)){ $r ->error = "图片大小不超过 $maxsize MB" ; } $folder = 'files/' ; if (! is_dir ( $folder )){ mkdir ( $folder ); } $folder .= $_POST [ 'folder' ] ? $_POST [ 'folder' ] . '/' : '' ; if (! is_dir ( $folder )){ mkdir ( $folder ); } if (preg_match( '/image/i' , $_FILES [ 'xfile' ][ 'type' ])){ $filename = $_POST [ 'value' ] ? $_POST [ 'value' ] : $folder . sha1(@microtime() . '-' . $_FILES [ 'xfile' ][ 'name' ]) . '.jpg' ; } else { $tld = split( ',' , $_FILES [ 'xfile' ][ 'name' ]); $tld = $tld [ count ( $tld ) - 1]; $filename = $_POST [ 'value' ] ? $_POST [ 'value' ] : $folder . sha1(@microtime() . '-' . $_FILES [ 'xfile' ][ 'name' ]) . $tld ; } $types = Array( 'image/png' , 'image/gif' , 'image/jpeg' ); if (in_array( $_FILES [ 'xfile' ][ 'type' ], $types )){ $source = file_get_contents ( $_FILES [ "xfile" ][ "tmp_name" ]); imageresize( $source , $filename , $_POST [ 'width' ], $_POST [ 'height' ], $_POST [ 'crop' ], $_POST [ 'quality' ]); } else { move_uploaded_file( $_FILES [ "xfile" ][ "tmp_name" ], $filename ); } $path = str_replace ( 'test.php' , '' , $_SERVER [ 'SCRIPT_NAME' ]); $r ->filename = $filename ; $r ->path = $path ; $r ->img = '<img src="' . $path . $filename . '" alt="image" />' ; echo json_encode( $r ); function imageresize( $source , $destination , $width = 0, $height = 0, $crop = false, $quality = 80) { $quality = $quality ? $quality : 80; $image = imagecreatefromstring( $source ); if ( $image ) { // Get dimensions $w = imagesx( $image ); $h = imagesy( $image ); if (( $width && $w > $width ) || ( $height && $h > $height )) { $ratio = $w / $h ; if (( $ratio >= 1 || $height == 0) && $width && ! $crop ) { $new_height = $width / $ratio ; $new_width = $width ; } elseif ( $crop && $ratio <= ( $width / $height )) { $new_height = $width / $ratio ; $new_width = $width ; } else { $new_width = $height * $ratio ; $new_height = $height ; } } else { $new_width = $w ; $new_height = $h ; } $x_mid = $new_width * .5; //horizontal middle $y_mid = $new_height * .5; //vertical middle // Resample error_log ( 'height: ' . $new_height . ' - width: ' . $new_width ); $new = imagecreatetruecolor( round ( $new_width ), round ( $new_height )); imagecopyresampled( $new , $image , 0, 0, 0, 0, $new_width , $new_height , $w , $h ); // Crop if ( $crop ) { $crop = imagecreatetruecolor( $width ? $width : $new_width , $height ? $height : $new_height ); imagecopyresampled( $crop , $new , 0, 0, ( $x_mid - ( $width * .5)), 0, $width , $height , $width , $height ); //($y_mid - ($height * .5)) } // Output // Enable interlancing [for progressive JPEG] imageinterlace( $crop ? $crop : $new , true); $dext = strtolower ( pathinfo ( $destination , PATHINFO_EXTENSION)); if ( $dext == '' ) { $dext = $ext ; $destination .= '.' . $ext ; } switch ( $dext ) { case 'jpeg' : case 'jpg' : imagejpeg( $crop ? $crop : $new , $destination , $quality ); break ; case 'png' : $pngQuality = ( $quality - 100) / 11.111111; $pngQuality = round ( abs ( $pngQuality )); imagepng( $crop ? $crop : $new , $destination , $pngQuality ); break ; case 'gif' : imagegif( $crop ? $crop : $new , $destination ); break ; } @imagedestroy( $image ); @imagedestroy( $new ); @imagedestroy( $crop ); } } |
PHP最终会返回一个JSON格式的数组,我返回的信息就是图片地址、名称,还有段img的html代码,最后在js那边获取到json数组并处理,至此,操作结束。
文章最开始提到,还有点击选择文件上传和网络图片,因为这2个不属于这次的主题范围内,就不说了。况且这2个功能实现起来都不麻烦。
hooray.github.io
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库