本文转载于:猿2048网站➨HTML5经典应用:拖拽上传图片
因为标题写的是实例,所以本次就不做讲解了,因为这个实例我也算是东拼西凑整出来的,参考了大概5、6款拖拽上传的插件和demo,然后把其中好的地方挑出来,最后就成了这么一个实例,一起来看下吧。界面样式我是参考了一个国外的相册网站,改动不大,只是把鸟语转换成中文,以及上传时的样式也进行了改动,之所以选这个的原因就是,我很容易做 扩展,它支持3种方式添加图片,一种拖拽上传,一种常规的选择文件上传,另外的就是添加网络图片。它很巧妙的把三种上传模式整合到了一起,而且你可以用 IE浏览器浏览下,如果不支持HTML5,是没有拖拽上传图片的提示的,如图:
拖拽上传最重要的就是js部分的代码,它实现了70%的功能,另外30%仅仅是把图片信息提交到后台,然后做对应的处理,比如压缩啊,裁剪啊云云。所以先来看下js实现代码吧。
01 |
$().ready( function (){ |
02 |
if ($.browser.safari || $.browser.mozilla){ |
03 |
$( '#dtb-msg1 .compatible' ).show(); |
04 |
$( '#dtb-msg1 .notcompatible' ).hide(); |
05 |
$( '#drop_zone_home' ).hover( function (){ |
06 |
$( this ).children( 'p' ).stop().animate({top: '0px' },200); |
07 |
}, function (){ |
08 |
$( this ).children( 'p' ).stop().animate({top: '-44px' },200); |
09 |
}); |
10 |
//功能实现 |
11 |
$(document).on({ |
12 |
dragleave: function (e){ |
13 |
e.preventDefault(); |
14 |
$( '.dashboard_target_box' ).removeClass( 'over' ); |
15 |
}, |
16 |
drop: function (e){ |
17 |
e.preventDefault(); |
18 |
//$('.dashboard_target_box').removeClass('over'); |
19 |
}, |
20 |
dragenter: function (e){ |
21 |
e.preventDefault(); |
22 |
$( '.dashboard_target_box' ).addClass( 'over' ); |
23 |
}, |
24 |
dragover: function (e){ |
25 |
e.preventDefault(); |
26 |
$( '.dashboard_target_box' ).addClass( 'over' ); |
27 |
} |
28 |
}); |
29 |
var box = document.getElementById( 'target_box' ); |
30 |
box.addEventListener( "drop" , function (e){ |
31 |
e.preventDefault(); |
32 |
//获取文件列表 |
33 |
var fileList = e.dataTransfer.files; |
34 |
var img = document.createElement( 'img' ); |
35 |
//检测是否是拖拽文件到页面的操作 |
36 |
if (fileList.length == 0){ |
37 |
$( '.dashboard_target_box' ).removeClass( 'over' ); |
38 |
return ; |
39 |
} |
40 |
//检测文件是不是图片 |
41 |
if (fileList[0].type.indexOf( 'image' ) === -1){ |
42 |
$( '.dashboard_target_box' ).removeClass( 'over' ); |
43 |
return ; |
44 |
} |
45 |
|
46 |
if ($.browser.safari){ |
47 |
//Chrome8+ |
48 |
img.src = window.webkitURL.createObjectURL(fileList[0]); |
49 |
} else if ($.browser.mozilla){ |
50 |
//FF4+ |
51 |
img.src = window.URL.createObjectURL(fileList[0]); |
52 |
} else { |
53 |
//实例化file reader对象 |
54 |
var reader = new FileReader(); |
55 |
reader.onload = function (e){ |
56 |
img.src = this .result; |
57 |
$(document.body).appendChild(img); |
58 |
} |
59 |
reader.readAsDataURL(fileList[0]); |
60 |
} |
61 |
var xhr = new XMLHttpRequest(); |
62 |
xhr.open( "post" , "test.php" , true ); |
63 |
xhr.setRequestHeader( "X-Requested-With" , "XMLHttpRequest" ); |
64 |
xhr.upload.addEventListener( "progress" , function (e){ |
65 |
$( "#dtb-msg3" ).hide(); |
66 |
$( "#dtb-msg4 span" ).show(); |
67 |
$( "#dtb-msg4" ).children( 'span' ).eq(1).css({width: '0px' }); |
68 |
$( '.show' ).html( '' ); |
69 |
if (e.lengthComputable){ |
70 |
var loaded = Math.ceil((e.loaded / e.total) * 100); |
71 |
$( "#dtb-msg4" ). 'span' ).eq(1).css({width:(loaded*2)+ 'px' }); |
72 |
} |
73 |
}, false ); |
74 |
xhr.addEventListener( "load" , function (e){ |
75 |
$( '.dashboard_target_box' ).removeClass( 'over' ); |
76 |
$( "#dtb-msg3" ).show(); |
77 |
$( "#dtb-msg4 span" ).hide(); |
78 |
var result = jQuery.parseJSON(e.target.responseText); |
79 |
alert(result.filename); |
80 |
$( '.show' ).append(result.img); |
81 |
}, false ); |
82 |
|
83 |
var fd = new FormData(); |
84 |
fd.append( 'xfile' , fileList[0]); |
85 |
xhr.send(fd); |
86 |
}, false ); |
87 |
} else { |
88 |
$( '#dtb-msg1 .compatible' ).hide(); |
89 |
$( '#dtb-msg1 .notcompatible' ).show(); |
90 |
} |
91 |
}); |
开始我是先判断浏览器类型,因为刚才介绍过,不同浏览器看到的是不同界面。主要实现代码是从“功能实现”开始的,这块具体为何这样操作,原理是什么,我就不多说了,大家可以参考下这篇文章:《人人网首页拖拽上传详解(HTML5 Drag&Drop、FileReader API、formdata)》,不过ajax上传部分的代码还是有点不一样的,因为人人那个似乎有点麻烦,我就另寻途径了。
最后就是上传部分的PHP代码了,这里我只是提供个参考,你可以根据项目的需求来自己编写。
001 |
$r = new stdClass(); |
002 |
header( 'content-type: application/json' ); |
003 |
$maxsize = 10; //Mb |
004 |
if ($_FILES[ 'xfile' ][ 'size' ] > ($maxsize * 1048576)){ |
005 |
$r->error = "图片大小不超过 $maxsize MB" ; |
006 |
} |
007 |
$folder = 'files/' ; |
008 |
if (!is_dir($folder)){ |
009 |
mkdir($folder); |
010 |
} |
011 |
$folder .= $_POST[ 'folder' ] ? $_POST[ 'folder' ] . '/' : '' ; |
012 |
if (!is_dir($folder)){ |
013 |
mkdir($folder); |
014 |
} |
015 |
|
016 |
if (preg_match( '/image/i' , $_FILES[ 'xfile' ][ 'type' ])){ |
017 |
$filename = $_POST[ 'value' ] ? 'value' ] : $folder . '-' . $_FILES[ 'xfile' ][ 'name' ]) . '.jpg' ; |
018 |
} else { |
019 |
$tld = split( ',' , $_FILES[ 'xfile' ][ 'name' ]); |
020 |
$tld = $tld[count($tld) - 1]; |
021 |
$filename = $_POST[ 'value' ] ? 'value' ] : $folder . '-' . $_FILES[ 'xfile' ][ 'name' ]) . $tld; |
022 |
} |
023 |
|
024 |
$types = Array( 'image/png' , 'image/gif' , 'image/jpeg' ); |
025 |
if (in_array($_FILES[ 'xfile' ][ 'type' ], $types)){ |
026 |
$source = file_get_contents($_FILES[ "xfile" ][ "tmp_name" ]); |
027 |
imageresize($source, $filename, $_POST[ 'width' ], 'height' ], $_POST[ 'crop' ], $_POST[ 'quality' ]); |
028 |
} else { |
029 |
move_uploaded_file($_FILES[ "xfile" ][ "tmp_name" ], $filename); |
030 |
} |
031 |
|
032 |
$path = str_replace( 'test.php' , '' , $_SERVER[ 'SCRIPT_NAME' ]); |
033 |
|
034 |
$r->filename = $filename; |
035 |
$r->path = $path; |
036 |
$r->img = '<img src="' . $path . $filename . '" alt="image" />' ; |
037 |
|
038 |
echo json_encode($r); |
039 |
|
040 |
function imageresize($source, $destination, $width = 0, false , $quality = 80) { |
041 |
$quality = $quality ? $quality : 80; |
042 |
$image = imagecreatefromstring($source); |
043 |
if ($image) { |
044 |
// Get dimensions |
045 |
$w = imagesx($image); |
046 |
$h = imagesy($image); |
047 |
if (($width && $w > $width) || ($height && $h > $height)) { |
048 |
$ratio = $w / $h; |
049 |
if (($ratio >= 1 || $height == 0) && $width && !$crop) { |
050 |
$new_height = $width / $ratio; |
051 |
$new_width = $width; |
052 |
} elseif ($crop && $ratio <= ($width / $height)) { |
053 |
$new_height = $width / $ratio; |
054 |
$new_width = $width; |
055 |
} else { |
056 |
$new_width = $height * $ratio; |
057 |
$new_height = $height; |
058 |
} |
059 |
} else { |
060 |
$new_width = $w; |
061 |
$new_height = $h; |
062 |
} |
063 |
$x_mid = $new_width * .5; //horizontal middle |
064 |
$y_mid = $new_height * .5; //vertical middle |
065 |
// Resample |
066 |
error_log( 'height: ' . $new_height . ' - width: ' . $new_width); |
067 |
$ new = imagecreatetruecolor(round($new_width), round($new_height)); |
068 |
imagecopyresampled($ new , $image, 0, 0, 0, 0, |
069 |
// Crop |
070 |
if ($crop) { |
071 |
$crop = imagecreatetruecolor($width ? |
072 |
imagecopyresampled($crop, $ new , 0, 0, |
073 |
//($y_mid - ($height * .5)) |
074 |
} |
075 |
// Output |
更多专业前端知识,请上 【猿2048】www.mk2048.com