因为标题写的是实例,所以本次就不做讲解了,因为这个实例我也算是东拼西凑整出来的,参考了大概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个功能实现起来都不麻烦。
本文转自胡尐睿丶博客园博客,原文链接:http://www.cnblogs.com/hooray/archive/2012/01/30/2331648.html,如需转载请自行联系原作者