仿淘宝头像上传功能(三)——兼容 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">保 存</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 浏览器。的更多相关文章
- Android仿淘宝继续上拉进入商品详情页的效果,使用双Fragment动画切换;
仿淘宝继续上拉进入商品详情页的效果,双Fragment实现: 动画效果: slide_above_in.xml <?xml version="1.0" encoding=&q ...
- 转::iOS 仿淘宝,上拉进入详情页面
今天做的主要是一个模仿淘宝,上拉进入商品详情的功能,主要是通过 tableView 与 webView 一起来实现的,当然也可根据自己的需要把 webView 替换成你想要的 // // ViewCo ...
- 基于Bootstrap仿淘宝分页控件实现
.header { cursor: pointer } p { margin: 3px 6px } th { background: lightblue; width: 20% } table { t ...
- 高仿淘宝和聚美优品商城详情页实现《IT蓝豹》
高仿淘宝和聚美优品商城详情页实现 android-vertical-slide-view高仿淘宝和聚美优品商城详情页实现,在商品详情页,向上拖动时,可以加载下一页. 使用ViewDragHelper, ...
- android版高仿淘宝客户端源码V2.3
android版高仿淘宝客户端源码V2.3,这个版本我已经更新到2.3了,源码也上传到源码天堂那里了,大家可以看一下吧,该应用实现了我们常用的购物功能了,也就是在手机上进行网购的流程的,如查看产品(浏 ...
- 一款基于jQuery仿淘宝红色分类导航
今天给大家分享一款基于jQuery仿淘宝红色分类导航.这款分类导航适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览 ...
- 仿淘宝左侧菜单导航栏纯Html + css 写的
这俩天闲来没事淘宝逛了一圈看到淘宝的左侧导航菜单做的是真心的棒啊,一时兴起,查了点资料抓了几个图片仿淘宝写了个css,时间紧写的不太好,大神勿喷,给小白做个参考 废话不多说先来个效果图 接下来直接上代 ...
- 淘宝网站上的 HTTP 缓存问题两则
在阅读本文前推荐你先阅读我的前两篇文章< 扼杀 304,Cache-Control: immutable>和<关于缓存和 Chrome 的“新版刷新”>:下面要说的两个问题是在 ...
- Android仿淘宝头条滚动广告条
之前我使用TextView+Handler+动画,实现了一个简单的仿淘宝广告条的滚动,https://download.csdn.net/download/qq_35605213/9660825: 无 ...
随机推荐
- Android DatePicker / TimePicker 占空间太大的解决办法
DatePicker 与 TimePicker 控件占用的空间是固定的,没有参数可以更改. 如果修改 length 和 width 属性,只会让控件被切割,显示将不完整.很多人说可以使用 scale ...
- django系列6--Ajax04 请求设置(设置csrf_token)
Ajax请求设置csrf_token 官方文档 csrf_token: https://docs.djangoproject.com/en/1.11/ref/csrf/ CSRF 跨站请求攻击,简单地 ...
- Web Api 内部数据思考 和 利用http缓存优化 Api
在上篇<Web Api 端点设计 与 Oauth>后,接着我们思考Web Api 的内部数据: 其他文章:<API接口安全加强设计方法> 第一 实际使用应该返回怎样的数据 ? ...
- PHP header函数设置http报文头示例详解以及解决http返回头中content-length与Transfer-Encoding: chunked的问题
最近在服务器上,多媒体与设备(摄像头)对接的时候,总是发生错误导致设备崩溃,抓包发现响应头不对,没有返回length,使得摄像头立即崩溃.找了一下资料,改了一下响应头就好了. //定义编码 heade ...
- “全栈2019”Java第一百一十章:局部内部类与匿名内部类区别详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- soapui加载天气预报接口报错Characters larger than 4 bytes are not supported: byte 0xb1 implies a length of more than 4 byte的解决办法
soapui加载天气预报接口时报错如下: Error loading [http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl ...
- mysql 赋给用户远程权限 grant all privileges on
我配置了权限 就可以在Windows下访问我虚拟机中的数据库了 来源:http://blog.csdn.net/louisliaoxh/article/details/52767209 登录: 在本机 ...
- tomcat 线程模型
最近看到了内网ATA上的一篇断网故障时Mtop触发tomcat高并发场景下的BUG排查和修复(已被apache采纳),引起了我的好奇,感觉原作者对应底层十分了解,写的很复杂.原来对于tomcat的线程 ...
- php性能优化三(PHP语言本身)
0.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册 ...
- (Lua) C++ 呼叫 Lua 的變數、函式
簡單的在C++裡頭與Lua交互操作 首先提供 Lua 的簡單範例 print(" Lua 2019/01/07 !!!") -- Variable monster_type = & ...