hi,大家好!今天为大家带来的是微信多图片上传组件封装的讲解。最近在做微信方面的开发研究,此研究背景是:
(1):项目之前一直使用单图片上传,而传统的表单多图片上传在安卓端(安卓系统目前不支持)无法实现多图片上传。
(2):使用过微信的同学都应该知道,微信前端js-sdk有一堆初始化代码,网上的微信多图片上传都是片段,未进行封装,使用起来非常麻烦.
废话不多说直接上代码:
jqwximgupload.js 组件代码如下
/*
* @autor:Aaron email:haotking@163.com
* @date:2016-11-05
* @version:1.1.2
* 微信多图片浏览选择图片上传插件
* 插件依赖jquery和微信js-sdk:jweixin-1.0.0.js
*
* <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
* <script type="text/javascript" src="*************jquery.min.js" ></script>
*
* window.jqwx.wxconfigure($id, options)
* $id:点击后弹出图片选择框的html标签的id
* options:扩展对象,
*
* 用法:
* window.jqwx.wxconfigure("uploadButton11",{
* signObject:signObject,
* jsApiList:['chooseImage','previewImage','uploadImage'] ,
* wxdownloadurl:url,
* isInitWx:false,
* wxsigniniturl:"/ump/page/bbsindex/wxJsAuth",
* onBefore:function(){
* },
* onSuccess:function(data,localIds){
* //图片下载成功后需要完成的事情
* },
* onComplete: function(){
* //弹窗关闭的回调,返回触发事件
* }
* });
* 说明:
* wxsigniniturl:本地服务器获取signObject的接口url
* signObject中对象对应微信js-sdk初始化微信sdk时签名对象
* signObject:{
* appid:"", 微信公众号appid *必须
* timestamp:"", 签名的时间戳 *必须
* noncestr:"", 签名的字符串 *必须
* signature:"" 签名 *必须
* }
* jsApiList:为需要用到的微信的js-sdk的接口,默认['chooseImage','previewImage','uploadImage'] *非必须
* wxdownloadurl:选择图片后,图片会自动上传到微信服务器;需要提供企业服务器从微信下载图片的接口的url
* 插件会通过ajax将data: {serverIds:serverIds},作为json格式上传到服务器,serverIds为存储
* 在微信服务器上的所有图片的媒体ID,通过","分割开. *必须
* onBefore:点击传按钮后,先执行的事件; 例如:在图片上传完成之前,禁止用户做其他的一些点击操作 *非必须
* onSuccess:function(data,localIds){}图片上传成功后,由wxdownloadurl对应接口返回来的data数据,将data数据进行一些页面的处理,比如显示上传成功的图片
* localIds对应的是微信选择的所有本地图片对应的id通过","分割开的字符串
* onComplete:上传插件已经调用完成,最后进行的操作
* isInitWx:是否要执行微信Js-sdk的初始化,一个页面只执行一次
*/
(function($,wx){
window['jqwx'] = window['jqwx'] || {};
window['jqwx'].isWeixinInitComplete=(window['jqwx'].isWeixinInitComplete)||false;
initsign=function initsign(url){
var signObject;
var curr_url=location.href.split('#')[0];
$.ajax({
url : url,
type : "Post",
async:false,
data : {
'url':curr_url
},
error : function(msg) {
alert("微信接口加载失败,请重新进入!"+msg);
},
success : function(data) {
signObject=data;
}
});
return signObject;
}
//在某个div或者容器的光标位置插入图片
window.jqwx.insertImage =function(contentId,src) {
document.getElementById(contentId).focus();
var selection = window.getSelection ? window.getSelection() : document.selection;
var range = selection.createRange ? selection.createRange() : selection.getRangeAt(0);
if (!window.getSelection) {
range.pasteHTML(src);
range.collapse(false);
range.select();
} else {
range.collapse(false);
var hasR = range.createContextualFragment(src);
var hasLastChild = hasR.lastChild;
while (hasLastChild && hasLastChild.nodeName.toLowerCase() == "br" && hasLastChild.previousSibling && hasLastChild.previousSibling.nodeName.toLowerCase() == "br") {
var e = hasLastChild;
hasLastChild = hasLastChild.previousSibling;
hasR.removeChild(e);
}
//range.insertNode(range.createContextualFragment("<p><br></p>"));
range.insertNode(hasR);
if (hasLastChild) {
range.setEndAfter(hasLastChild);
range.setStartAfter(hasLastChild);
}
selection.removeAllRanges();
selection.addRange(range);
}
}
//获取图片后的光标
window.jqwx.addRange=function (o){
var event = window.event || arguments.callee.caller.arguments[0];
//target 就是这个对象
var target = event.srcElement||event.target;
var sel, range;
//var content = $("#"+o)[0].innerHTML;
// $("#bbsContent_div")[0].innerHTML=content+"</br><p> </p>";
document.getElementById(o).focus();
if (window.getSelection) {
range = document.createRange();
sel = window.getSelection();
//if (sel.getRangeAt && sel.rangeCount) {
//range.selectNodeContents(target);
//range.collapse(true);
//range = sel.getRangeAt(0);
//range.deleteContents();
// range = range.cloneRange();
range.setStartAfter(target);
range.collapse(true);
document.getElementById(o).focus();
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
// }
} else if (document.selection && document.selection.type != "Control") {
alert('浏览器不支持');
// IE < 9
//document.selection.createRange().pasteHTML(html);
}
}
window.jqwx.wxconfigure= function($id, options) {
// 微信服务器返回图片ID数组
var localIds = null;
// 上传序号
var idx = 0;
var serverIds='';
var config = $.extend({
//属性
signObject:{
appid:"",
timestamp:"",
noncestr:"",
signature:""
},
size:9,
isInitWx:false,//是否执行微信js-sdk的初始化
jsApiList:[],//用于保存需要微信初始化的接口
isInitSign:true,
wxdownloadurl:"",
wxsigniniturl:"",
debug:false,
//事件
initwinsign: initsign,
onWxready:$.noop,
onBefore: $.noop,//点击确定的按钮回调
//onCancel: $.noop,//点击取消的按钮回调
onSuccess: $.noop,//图片下载成功后需要完成的事情
onComplete: $.noop//弹窗关闭的回调,返回触发事件
}, options);
init();
function hiddenButton(){
wx.hideMenuItems({
menuList: [
'menuItem:openWithSafari', //在Safari中打开
'menuItem:openWithQQBrowser', //在QQ浏览器中打开
'menuItem:copyUrl' //复制链接
]
});
}
function init(){
if((!jqwx.isWeixinInitComplete)&&config.isInitWx){
if(config.isInitSign){
var currSignObject;
if(config.wxsigniniturl!=""){
currSignObject=config.initwinsign(config.wxsigniniturl);
}else{
currSignObject=config.initwinsign();
}
config.signObject=currSignObject;
}
wx.config({
debug: config.debug, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId:config.signObject.appid, // 必填,公众号的唯一标识
timestamp:config.signObject.timestamp, // 必填,生成签名的时间戳
nonceStr: config.signObject.noncestr, // 必填,生成签名的随机串
signature:config.signObject.signature,// 必填,签名,见附录1
jsApiList:config.jsApiList // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function(){
//设置微信js-sdk初始化已完成
jqwx.isWeixinInitComplete=true;
hiddenButton();
//微信初始化完成后,你可以对微信的分享链接做初始化,或者其他微信功能的初始化
config.onWxready();
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
}
$("#"+$id).click(onChooseClick);
}
function onChooseClick(){
//将参数置为初始化状态
localIds = null;
idx = 0;
serverIds='';
if(jqwx.isWeixinInitComplete){
wx.chooseImage({
count: config.size, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
localIds = res.localIds;//本地图片id数组,下标从0开始
//调用上传递归函数
if(config.wxdownloadurl!=""){
//禁用掉图片按钮和发布按钮
$("#"+$id).attr({"disabled":"disabled"});
config.onBefore();
wxUploadImg(localIds);
//$("#"+$id).removeAttr("disabled");//将按钮可用
//config.onComplete();
}else{
alert("请检查服务器微信图片下载url是否填写正确");
}
}
});
}else{
alert('微信接口正在初始化,请稍后重试!');
}
}
function wxUploadImg(localIds){
wx.uploadImage({//获取图片媒体ID
localId: localIds[idx].toString(), // 需要上传的图片的本地ID
isShowProgressTips: 0, // 默认为1,显示进度提示
success: function (res) {//获取成功
// 上传序号,上传一张 累计 +1
idx++
//存储图片媒体ID,用","号分割
serverIds+=res.serverId+',';
if(idx<localIds.length){//本地图片ID 还没全部获取完图片媒体ID
//调用上传递归函数
wxUploadImg(localIds);
}else{
//上传序号归零
idx=0;
//服务器csrf 验证字符串,如果后端框架没开启csrf,则不需要
//var csrf=$('meta[name="csrf-token"]').attr('content');
var sId=serverIds;
$.ajax({
url: config.wxdownloadurl,//服务器端根据图片媒体ID下载图片处理操作地址
type: 'POST',
async:false,
dataType: 'json',
data: {serverIds:serverIds},
}).done(function(data) {
alert("上传成功");
config.onSuccess(data,localIds,sId);
}).fail(function() {
//console.log("error");
}).always(function() {
//console.log("complete");
$("#"+$id).removeAttr("disabled");//将按钮可用
config.onComplete();
});
serverIds='';
return true;
}
},
fail: function(res){//获取多媒体id失败 返回错误代码
alert("上传失败,msg:"+JSON.stringify(res));
$("#"+$id).removeAttr("disabled");//将按钮可用
config.onComplete();
}
});
}
};
})(jQuery,wx);
使用例子:
$(document).ready(function() {
jqwx.wxconfigure("uploadButton",{
jsApiList:['chooseImage','previewImage','uploadImage'] ,
wxdownloadurl:"/ump/page/bbsindex/bbsWeixFileDownload",
isInitWx:true,
wxsigniniturl:"/ump/page/bbsindex/wxJsAuth",
onBefore:function(){
$("#loadgif").show();
$("#pubbbs").removeAttr("onclick");//所有验证通过之后禁用掉onclick事件
},
onSuccess:function(data,localIds,serverIds){
$("#loadgif").hide();
var contentId="bbsContent_div";
//图片下载成功后需要完成的事情
$.each(data, function (n, value) {
if(value&&value!=''){
var imgurl = '<img src="'+value+'" id="'+serverIds[n]+ '" style="max-width:100%;height:auto; " >' ;
window.jqwx.insertImage(contentId,imgurl);
$('#'+serverIds[n]).on("click",function (){
window.jqwx.addRange(contentId);
});
}
});
},
onComplete: function(){
//弹窗关闭的回调,返回触发事件
$("#pubbbs").attr("onclick","addbbs();");//将按钮可用
}
});
});
注意:一个页面值能初始化一次,如果有两个div需要用,图片上传,那就设置前面那个isinitwx=true,后面的为false.不行太困,我要睡觉,别拦着我!