微信公众号多图片上传组件封装(BBS论坛完整版)

    分享一款自己封装的微信公众号上使用微信API多图片上传的组件【此组件已用于***公众号发帖回帖等等业务】,支持(bbs发帖)输入框任意位置上传,【***俱乐部】公众号发帖回帖功能

核心组件代码:

1.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="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>&nbsp;</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方法)

(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>&nbsp;</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);

 

效果图如下:

fe3befc862bdab27ef5f6558d19177bc738.jpg

2125d18513021cfef3f79a9afb7c3bfa67c.jpg

4b8a0f940ef88eb02ee68061f9502b9c3f1.jpg

d8406bf7f683a7f1a1a257bc54bccb02bc6.jpg2fb9c9188eb07ab079973eb63f875c0e8b9.jpg

转载于:https://my.oschina.net/u/2371923/blog/1837930

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值