前两篇目录:

仿淘宝头像上传功能(一)——前端篇。

仿淘宝头像上传功能(二)——程序篇

仿淘宝头像上传功能(三)——兼容 IE6 浏览器

之前的这两篇虽然实现了功能,但不兼容低版本浏览器,而且有些浏览器还会死机,所以现在重新做了个新的。

现已在 IE6,IE10,IE11,谷歌测试通过。

这次使用了这两个插件:

Jquery:1.11.2

上图文件插件:ajaxFileUpload

裁剪插件:imgAreaSelect

1.文件上传需要使用到 file 表单,但 file 表单样式太难看,需要进行自定义。

由于在IE下需要手动点击 file 表单才有效果,所以,无法使用 onclick 事件!!

解决办法就是使用样式,覆盖在 file 表单上传,当点击该样式的时候,实际上点击的是 file 表单

2.ajaxFileUpload 插件的各种版本太多,这里给出自己使用的一个版本。

先直接给出JS源码了:

////////////////////////////////////////////////////////////////
// 上传头像JS
//上传头像插件:ajaxFileUpload
//裁剪插件:imgAreaSelect
/////////////////////////////////////////////////////////////// //上传文件按钮表单 ID。
var inputFileId = "fileupload_input"; //原图片显示 ID。
var sourceImageId = "photo"; //裁剪大图显示 ID。
var bigImageId = "cut1"; //裁剪中图显示 ID。
var centerImageId = "cut2"; //裁剪小图显示 ID。
var smallImageId = "cut3"; //临时图片(隐藏)。
var hiddenImage = "test"; //保存裁剪框左上角 X 坐标的表单。
var inputX = "X"; //保存裁剪框左上角 Y 坐标的表单。
var inputY = "Y"; //保存裁剪框宽度的表单。
var inputWidth = "Width"; //保存裁剪框高度的表单。
var inputHeight = "Height"; //提交按钮表单。
var submitButtonId = "btnAjaxSubmit"; //上传图片文件 URL。
var fileUploadUrl = "/user/icon/upload"; //提交裁剪坐标信息并保存图片的 URL。
var submitUrl = "/user/upload"; var hasFile = false;
var isSelect = false;
var imgArea = null; //初始化选择控件
function InitSelect() {
imgArea = $('#' + sourceImageId).imgAreaSelect({
x1: 0, y1: 0, x2: 10, y2: 10,
maxWidth: 300,
maxHeight: 300,
aspectRatio: '1:1', instance: true,
persistent: true,
//resizable: true,
show: true, handles: true,
onSelectEnd: preview
});
} function preview(img, selection) {
//获取图片链接到缩略图
var cut1 = $("#" + bigImageId);
var cut2 = $("#" + centerImageId);
var cut3 = $("#" + smallImageId);
Zoom(img, cut1, selection, 180, 180);
Zoom(img, cut2, selection, 50, 50);
Zoom(img, cut3, selection, 30, 30); isSelect = true; $("#" + inputX).val(selection.x1);
$("#" + inputY).val(selection.y1);
$("#" + inputWidth).val(selection.width);
$("#" + inputHeight).val(selection.height); CleanDisabled();
} //缩放预览
function Zoom(source, imgCut, selection, X, Y) {
var imgurl = $(source).attr("src");
var sWidth = $(source).width();
var sHight = $(source).height(); $(imgCut).attr("src", imgurl); var scaleX = X / (selection.width || 1);
var scaleY = Y / (selection.height || 1); $(imgCut).css({
width: Math.round(scaleX * sWidth) + 'px',
height: Math.round(scaleY * sHight) + 'px',
marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px',
marginTop: '-' + Math.round(scaleY * selection.y1) + 'px'
});
} //重设原图宽高
function resetImg() {
try {
var source = $("#" + sourceImageId);
var sWidth = $("#" + hiddenImage).width();
var sHight = $("#" + hiddenImage).height(); if (sWidth > sHight) {
$(source).attr("width", 300);
$(source).removeAttr("height");
}
else {
$(source).attr("height", 300);
$(source).removeAttr("width");
}
}
catch (ex) {
//showErr("截图程序异常");
}
} //默认图片选择区域
function setDefault_Selection() {
var x = $("#" + hiddenImage).width();
var y = $("#" + hiddenImage).height(); var scale = 0.0;
var x1, y1, x2, y2 = 0;
if (x > y) {
scale = 300 / x;
x = 300;
y = scale * y;
}
else {
scale = 300 / y;
y = 300;
x = scale * x;
} var rx = x / 2;
var ry = y / 2;
var length = 70; x1 = rx - length; y1 = ry - length;
x2 = rx + length, y2 = ry + length; imgArea.setSelection(x1, y1, x2, y2);
imgArea.update(); preview($("#" + sourceImageId), imgArea.getSelection());
} //图片上传预览
function previewImage(file) {
////只有高版本浏览器可用,可以直接使用本地图片预览。
//if (file.files && file.files[0]) {
// if (file.files[0].type != "image/jpeg") {
// showErr("仅支持JPG图片文件,且文件小于3M");
// return;
// } // if (file.files[0].size > 3145728) {
// showErr("仅支持JPG图片文件,且文件小于3M");
// $(file).attr("src", "");
// return;
// } // var img = document.getElementById('photo');
// var reader = new FileReader();
// reader.onload = function (evt) {
// img.src = evt.target.result;
// $("#test").attr("src", evt.target.result); // //延迟加载
// setTimeout(function () {
// hasFile = true;
// resetImg();
// InitSelect();
// setDefault_Selection();
// }, 200);
// }
// reader.readAsDataURL(file.files[0]);
//}
//else
// return; /*低版本浏览器兼容*/
var selection = $("#" + sourceImageId).imgAreaSelect({ instance: true }).getSelection();
$.ajaxFileUpload({
url: fileUploadUrl,
secureuri: false,
fileElementId: inputFileId, //文件上传域的ID
data: selection,
dataType: 'json',
success: function (data, status) //服务器成功响应处理函数
{
imgClear(); //图片上传成功后,返回包含原图 URL 的 Json 对象。
$("#" + sourceImageId).attr("src", data.Image + "?num=" + Math.random());
$("#" + hiddenImage).attr("src", data.Image); //延迟加载
setTimeout(function () {
hasFile = true;
resetImg();
InitSelect();
setDefault_Selection();
}, 200);
},
error: function (data, status, e) {
//showErr("头像加载失败,请重试或者联系管理员");
}
});
} function imgClear() {
$("#" + sourceImageId).attr("style", "");
$("#" + sourceImageId).attr("src", "");
$("#" + bigImageId).attr("src", "");
$("#" + centerImageId).attr("src", "");
$("#" + smallImageId).attr("src", "");
} //取消禁用。
function CleanDisabled() {
$("#" + submitButtonId).removeAttr("style");
$("#" + submitButtonId).removeAttr("disabled");
} //禁用按钮。
function SetDisabled() {
$("#" + submitButtonId).attr("style", "background-color:#f39898;");
$("#" + submitButtonId).attr("disabled", "disabled");
} $("#" + submitButtonId).click(function () {
$.ajax({
type: "POST",
url: submitUrl,
data: $(this).parent().serialize(),
dataType: 'json',
success: function (data) {
if (data.Status > 0) {
//showSuc("头像上传成功!");
//$("#currentIcon").attr("src", data.BigIcon);
//$("#nav-top-icon").attr("src", data.SmallIcon);
}
},
error: function () {
//showErr("头像上传异常,请重试或者联系管理员");
}
});
});

HTML:

<div class="boxbar headbox">
<div class="title">修改头像</div>
<div class="content">
<div class="upload_btn">
<form id="fm" method="post" action="/user/icon/upload" enctype="multipart/form-data">
<span id="fileupload-content" class="btn_sc">
<span>上传本地相片</span>
<input type="file" id="fileupload_input" name="fileInput" onchange="previewImage(this);" />
</span>
</form>
<span class="tip">仅支持JPG图片文件,且文件小于3M</span>
<img id="test" src="" hidden="hidden" style="display: none;" />
</div>
<div class="pic_box">
<div id="img-preview" class="pic_left" style="overflow: hidden;position:relative;">
<img id="photo" src="" />
</div>
<div class="pic_line"></div>
<div class="pic_con">
<p class="tip">您上传的头像会自动生成三种尺寸,请注意中小尺寸的头像是否清晰</p>
<div id="preview_box_200" class="big_pic" style="overflow: hidden;position:relative;">
<img id="cut1" style="position: relative;" />
</div>
<div class="pic_cc">大头像尺寸,180x180像素</div>
</div>
<div class="pic_right">
<div id="preview_box_50" class="midd_pic" style="overflow: hidden;position:relative;">
<img id="cut2" style="position: relative; width: 50px; height: 50px;" src="" />
</div>
<div class="pic_cc">
中尺寸头像50x50像素
<p>(自动生成)</p>
</div>
<div id="preview_box_small" class="small_pic" style="overflow: hidden;position:relative;">
<img id="cut3" style="position: relative; width: 30px; height: 30px;" />
</div>
<div class="pic_cc">
小尺寸头像30x30像素
<p>(自动生成)</p>
</div>
</div>
</div>
<form id="userIconForm" method="POST">
<input id="X" name="X" type="hidden" />
<input id="Y" name="Y" type="hidden" />
<input id="Width" name="Width" type="hidden" />
<input id="Height" name="Height" type="hidden" />
<button id="btnAjaxSubmit" class="btn_tj" type="button" style="background-color:#f39898" disabled="disabled">保&nbsp;&nbsp;存</button>
</form>
</div>
</div>

这里给出使用的插件源码

ajaxFileUpload

jQuery.extend({
createUploadIframe: function (id, uri) {
//create frame
var frameId = 'jUploadFrame' + id;
var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"';
if (window.ActiveXObject) {
if (typeof uri == 'boolean') {
iframeHtml += ' src="' + 'javascript:false' + '"';
}
else if (typeof uri == 'string') {
iframeHtml += ' src="' + uri + '"';
}
}
iframeHtml += ' />';
jQuery(iframeHtml).appendTo(document.body); return jQuery('#' + frameId).get(0);
},
createUploadForm: function (id, fileElementId, data) {
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
var form = jQuery('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
if (data) {
for (var i in data) {
jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
}
}
var oldElement = jQuery('#' + fileElementId);
var newElement = jQuery(oldElement).clone();
jQuery(oldElement).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(oldElement).appendTo(form); //set attributes
jQuery(form).css('position', 'absolute');
jQuery(form).css('top', '-1200px');
jQuery(form).css('left', '-1200px');
jQuery(form).appendTo('body');
return form;
}, ajaxFileUpload: function (s) {
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
s = jQuery.extend({}, jQuery.ajaxSettings, s);
var id = new Date().getTime()
var form = jQuery.createUploadForm(id, s.fileElementId, (typeof (s.data) == 'undefined' ? false : s.data));
var io = jQuery.createUploadIframe(id, s.secureuri);
var frameId = 'jUploadFrame' + id;
var formId = 'jUploadForm' + id;
// Watch for a new set of requests
if (s.global && !jQuery.active++) {
jQuery.event.trigger("ajaxStart");
}
var requestDone = false;
// Create the request object
var xml = {}
if (s.global)
jQuery.event.trigger("ajaxSend", [xml, s]);
// Wait for a response to come back
var uploadCallback = function (isTimeout) {
var io = document.getElementById(frameId);
try {
if (io.contentWindow) {
xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : null;
xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
} else if (io.contentDocument) {
xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML : null;
xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
}
} catch (e) {
jQuery.handleError(s, xml, null, e);
}
if (xml || isTimeout == "timeout") {
requestDone = true;
var status;
try {
status = isTimeout != "timeout" ? "success" : "error";
// Make sure that the request was successful or notmodified
if (status != "error") {
// process the data (runs the xml through httpData regardless of callback)
var data = jQuery.uploadHttpData(xml, s.dataType);
// If a local callback was specified, fire it and pass it the data
if (s.success)
s.success(data, status); // Fire the global callback
if (s.global)
jQuery.event.trigger("ajaxSuccess", [xml, s]);
} else
jQuery.handleError(s, xml, status);
} catch (e) {
status = "error";
jQuery.handleError(s, xml, status, e);
} // The request was completed
if (s.global)
jQuery.event.trigger("ajaxComplete", [xml, s]); // Handle the global AJAX counter
if (s.global && ! --jQuery.active)
jQuery.event.trigger("ajaxStop"); // Process result
if (s.complete)
s.complete(xml, status); jQuery(io).unbind() setTimeout(function () {
try {
jQuery(io).remove();
jQuery(form).remove();
} catch (e) {
jQuery.handleError(s, xml, null, e);
}
}, 100) xml = null
}
}
// Timeout checker
if (s.timeout > 0) {
setTimeout(function () {
// Check to see if the request is still happening
if (!requestDone) uploadCallback("timeout");
}, s.timeout);
}
try {
var form = jQuery('#' + formId);
jQuery(form).attr('action', s.url);
jQuery(form).attr('method', 'POST');
jQuery(form).attr('target', frameId);
if (form.encoding) {
jQuery(form).attr('encoding', 'multipart/form-data');
}
else {
jQuery(form).attr('enctype', 'multipart/form-data');
}
jQuery(form).submit(); //提交file域值不清空(原理:提交后把对象再复制回来,达到不清空的目的)
var oldElement = jQuery('#jUploadFile' + id, form);
var newElement = jQuery('#' + s.fileElementId);
jQuery(newElement).replaceWith(oldElement);
jQuery(oldElement).attr('id', s.fileElementId);
} catch (e) {
jQuery.handleError(s, xml, null, e);
} jQuery('#' + frameId).load(uploadCallback);
return { abort: function () { } };
}, //修正JQ1.6以上版本去除handleError的BUG
handleError: function (s, xhr, status, e) {
if (s.error) {
s.error.call(s.context || s, xhr, status, e);
}
if (s.global) {
(s.context ? jQuery(s.context) : jQuery.event).trigger("ajaxError", [xhr, s, e]);
}
}, uploadHttpData: function (r, type) {
var data = !type;
data = type == "xml" || data ? r.responseXML : r.responseText;
// If the type is "script", eval it in global context
if (type == "script")
jQuery.globalEval(data);
// Get the JavaScript object, if JSON is used.
//修正一直提示ERROR的BUG type==json
if (type == "json")
//eval("data = \" " + data + " \" ");
eval("data = " + data);
// evaluate scripts within html
if (type == "html")
jQuery("<div>").html(data).evalScripts(); return data;
}
})

仿淘宝头像上传功能(三)——兼容 IE6 浏览器。的更多相关文章

  1. Android仿淘宝继续上拉进入商品详情页的效果,使用双Fragment动画切换;

    仿淘宝继续上拉进入商品详情页的效果,双Fragment实现: 动画效果: slide_above_in.xml <?xml version="1.0" encoding=&q ...

  2. 转::iOS 仿淘宝,上拉进入详情页面

    今天做的主要是一个模仿淘宝,上拉进入商品详情的功能,主要是通过 tableView 与 webView 一起来实现的,当然也可根据自己的需要把 webView 替换成你想要的 // // ViewCo ...

  3. 基于Bootstrap仿淘宝分页控件实现

    .header { cursor: pointer } p { margin: 3px 6px } th { background: lightblue; width: 20% } table { t ...

  4. 高仿淘宝和聚美优品商城详情页实现《IT蓝豹》

    高仿淘宝和聚美优品商城详情页实现 android-vertical-slide-view高仿淘宝和聚美优品商城详情页实现,在商品详情页,向上拖动时,可以加载下一页. 使用ViewDragHelper, ...

  5. android版高仿淘宝客户端源码V2.3

    android版高仿淘宝客户端源码V2.3,这个版本我已经更新到2.3了,源码也上传到源码天堂那里了,大家可以看一下吧,该应用实现了我们常用的购物功能了,也就是在手机上进行网购的流程的,如查看产品(浏 ...

  6. 一款基于jQuery仿淘宝红色分类导航

    今天给大家分享一款基于jQuery仿淘宝红色分类导航.这款分类导航适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览    ...

  7. 仿淘宝左侧菜单导航栏纯Html + css 写的

    这俩天闲来没事淘宝逛了一圈看到淘宝的左侧导航菜单做的是真心的棒啊,一时兴起,查了点资料抓了几个图片仿淘宝写了个css,时间紧写的不太好,大神勿喷,给小白做个参考 废话不多说先来个效果图 接下来直接上代 ...

  8. 淘宝网站上的 HTTP 缓存问题两则

    在阅读本文前推荐你先阅读我的前两篇文章< 扼杀 304,Cache-Control: immutable>和<关于缓存和 Chrome 的“新版刷新”>:下面要说的两个问题是在 ...

  9. Android仿淘宝头条滚动广告条

    之前我使用TextView+Handler+动画,实现了一个简单的仿淘宝广告条的滚动,https://download.csdn.net/download/qq_35605213/9660825: 无 ...

随机推荐

  1. This InfoPath form template is browser-compatible, but it cannot be browser-enabled on the selected site

    - all features were running on sitecollection level and at site level But here is the solution, i do ...

  2. Vue前端数据采集 埋点 追踪用户系列行为

    什么是埋点?  综合    vue埋点 埋点分析,是网站分析的一种常用的数据采集方法.数据埋点分为初级.中级.高级三种方式.数据埋点是一种良好的私有化部署数据采集方式. 埋点技术如何采集数据,有何优缺 ...

  3. Python3.5 学习二

    模块/库: Python的强大在于丰富的各种库的存在. 用import方法导入的  分为标准库.第三方库 程序运行时会先从当前目录下寻找import的模块名的文件,如果没有,则去全局环境变量对应的路径 ...

  4. BZOJ 3239--Discrete Logging(BSGS)

    3239: Discrete Logging Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 635  Solved: 413[Submit][Statu ...

  5. (三)SSO之CAS框架单点退出,退出到CAS登录界面

    应需求的改变.CAS自定义登录页面不安全,不再使用,于是我一下子回到了原点,在linux上部署上了没有加自定义登陆界面的CAS,接下来开始修改CAS自己默认的登录界面为我们的界面. 一下子修改成功是根 ...

  6. 由button标签在 IE 8.0 下的异常表现引发的一场血案

    写在最前的最后:整篇文章絮絮叨叨说了半天,我得出一个最佳实践:和button标签say goodbay,用 a 标签模拟之. 首先看一个在chrome 下的简单demo 这样的布局在组件开发中再常见不 ...

  7. mxonline实战11,课程详情页2,课程章节页

    对应github地址:第11天   一. 课程详情页2   1. 课程详情页第2块中的课程介绍中,修改course-detail.html中代码,搜索课程详情,找到如下代码

  8. byte转文件流 下载到本地

    此方法将byte类型文件转为文件流保存到本地 byte 经过BASE64Decoder 进行编码之后的类型 所以需要解码 防止出现乱码及文件损毁 /** * byte 转文件 下载到本地 * @par ...

  9. 记录一次因为意外断电造成gitlab(docker容器)重启之后无法访问的问题

    容器启动成功,但是处于unhealthy状态,登录界面500. docker logs gitlab 最终错误是 err="opening storage failed: open bloc ...

  10. jmeter之beanshell断言---数据处理

    在做接口测试时,对响应数据的校验是非常重要的部分:在使用Jmeter进行接口测试时,有多种respone校验方式,比如响应断言.BeanShell断言等等,BeanShell断言可以自定义断言,自由灵 ...