分享一款本身封裝的微信公衆號上使用微信API多圖片上傳的組件【此組件已用於***公衆號發帖回帖等等業務】,支持(bbs發帖)輸入框任意位置上傳,【***俱樂部】公衆號發帖回帖功能javascript
核心組件代碼:html
1.jqwximgupload.jsjava
/* * @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="https://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; } 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);
2.jqking.main.js(可用於pc端圖片任意位置插入jq.addRange、jq.insertImage方法)node
(function(jqr_obj) { var jquery = jqr_obj; //註冊命名空間jKing到window對象上 window['jKing'] = {}; //定義一個jKing函數 var version = "1.0.0"; jq = function(selector) { // The jKing object is actually just the init constructor 'enhanced' // Need init if jKing is called (just allow error to be thrown if not included) return new jq.fn.init(selector); }; //動態屬性方法 jq.fn = jq.prototype = { // The current version of jKing being used jKing : version, constructor : jq, // Start with an empty selector selector : "", // The default length of a jKing object is 0 length : 0, get : function() { if (typeof this.selector === "string" && this.selector.length > 0) { if (this.selector.startWith("#")) { this.element = document.getElementById(this.selector); return this; } else if (this.selector.startWith(".")) { var odiv = document.getElementsByTagName("*"); var a = []; for ( var i = 0; i < odiv.length; i++) { if (this.selector == "." + odiv[i].className) { a[a.length] = odiv[i]; } } this.element = a; return this; } } } }; //定義靜態支持擴展方法 jq.extend = function(namespace, _o1) { if (!arguments[1]) { // 開始遍歷 for ( var p in arguments[0]) { // 方法 //console.info(_o1); //console.info(p); if (typeof (arguments[0][p]) == "function") { jq[p] = arguments[0][p]; } } } else { if (namespace && typeof (namespace) === "object") { // 開始遍歷 for ( var p in arguments[1]) { // 方法 //console.info(_o1); //console.info(p); if (typeof (arguments[1][p]) == "function") { namespace[p] = arguments[1][p]; } } } } }; jq.extend({//內部使用的方法 "nspace" : function(arr, _obj, i) { if (i <= arr.length - 1) { var obj; if (typeof (_obj[arr[i]]) == "undefined") { obj = _obj[arr[i]] = {}; } else if (_obj[arr[i]] && typeof (_obj[arr[i]]) == "object") { obj = _obj[arr[i]]; } //alert(i); //_obj[arr[i]].b="1"; jq.nspace(arr, obj, i + 1); } else { //alert(arr.toString()); //alert(jq.json2str()); return; } } }); jq.ns = function(namespace) { var nsArray = new Array(); if (namespace && typeof (namespace) === "string") { nsArray = namespace.split("."); if (nsArray && nsArray.length > 0) { jq.nspace(nsArray, jq, 1); } } else { alert("命名空間必須是非空字符串!"); return; } } init = jq.fn.init = function(selector) { if (!selector) { return this; } if (typeof selector === "string" && selector.length > 0) { this.selector = selector; this.length = selector.length; return this; } }; init.prototype = jq.fn; //動態的load module jKing.load = function(_o1) { for ( var p in _o1) { if (typeof (_o1[p]) == "function") { window['jKing'][p] = _o1[p]; } } }; /* * addEventListener:監聽Dom元素的事件 * * target:監聽對象 * type:監聽函數類型,如click,mouseover * func:監聽函數 */ jq.extend({ "addEventHandler" : function(target, type, callback) { if (target.addEventListener) { //監聽IE9,谷歌和火狐 target.addEventListener(type, callback, false); } else if (target.attachEvent) { target.attachEvent("on" + type, callback); } else { target["on" + type] = callback; } } }); /* * removeEventHandler:移除Dom元素的事件 * * target:監聽對象 * type:監聽函數類型,如click,mouseover * func:監聽函數 */ jq.extend({ "removeEventHandler" : function(target, type, callback) { if (target.removeEventListener) { //監聽IE9,谷歌和火狐 target.removeEventListener(type, callback, false); } else if (target.detachEvent) { target.detachEvent("on" + type, callback); } else { delete target["on" + type]; } } }); String.prototype.startWith = function(compareStr) { return this.indexOf(compareStr) == 0; } /*中止冒事件*/ jq.stopEvent = function(event) { var e = event || window.event; if (e && e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; } }; //Json對象轉字符串的方法 jq.json2str = function(obj) { var s = []; for ( var i in obj) { obj[i] = typeof obj[i] == 'string' ? '"' + obj[i] + '"' : (typeof obj[i] == 'object' ? jq.json2str(obj[i]) : obj[i]); s.push(i + ':' + obj[i]); } return '{' + s.join(',') + '}'; } //將對象轉換成字符串的方法 jq.objConvertStr = function(o) { if (o == undefined) { return ""; } var r = []; if (typeof o == "string") return "\"" + o.replace(/([\"\\])/g, "\\$1") .replace(/(\n)/g, "\\n") .replace(/(\r)/g, "\\r") .replace(/(\t)/g, "\\t") + "\""; if (typeof o == "object") { if (!o.sort) { for ( var i in o) r.push("\"" + i + "\":" + jq.objConvertStr(o[i])); if (!!document.all && !/^\n?function\s*toString\(\)\s*\{\n?\s*\[native code\]\n?\s*\}\n?\s*$/ .test(o.toString)) { r.push("toString:" + o.toString.toString()); } r = "{" + r.join() + "}" } else { for ( var i = 0; i < o.length; i++) r.push(jq.objConvertStr(o[i])) r = "[" + r.join() + "]"; } return r; } return o.toString().replace(/\"\:/g, '":""'); } //將from表單序列化 jq.serializeObject = function(formId) { var form = $("#" + formId); var o = {}; $.each(form.serializeArray(), function(index) { if (o[this['name']]) { o[this['name']] = o[this['name']] + "," + this['value']; } else { o[this['name']] = this['value']; } }); return o; }; //將對象填入到表單中 jq.objectToForm = function setValue(obj, formId) { // 開始遍歷 for ( var p in obj) { // 方法 if (typeof (obj[p]) == "function") { obj[p](); } else { //console.log(document.getElementById("aa").getAttribute("field")); //console.log($("#aa").attr("value")); //console.log($("#admin_user_searchForm > #aa").get()); var field = $("#" + formId + " > #field_" + p); if (field && field.attr("field")) { field.val(obj[p]); } //p 爲屬性名稱,obj[p]爲對應屬性的值 } } }; jq.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); } } jq.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); } } //把jq函數註冊到jKing命名空間中 window['jKing']['$'] = jq; window['jKing']['jq'] = jquery; //window['jKing']['load']=jKing.load; })(jQuery);
效果圖以下:jquery