github L6zt前端
<script> window.$shareInformation = { title: '....', desc: '.....', link: '.....', } </script>
前端還要獲取全局變量裏的值,初始化分享
2.分享功能沒有進行統一的合併,因此每一個頁面都須要重寫分享邏輯,很low低效的很,並且不利於維護。
3.每次都須要 引入 釘釘 和 微信 分享的 sdk js 感受浪費流量,並且 影響頁面加載速度, 這個兩個js都須要同時引入。git
對以上問題解決方案,我採用: 端對端懶加載 不一樣平臺的 sdk, 分享邏輯 統一由後端控制 即 頁面裏 只須要引入一個js腳本。
整體引用方法github
// data-ajax 放置獲取分享信息 ajax的入參 //data-exclud 排除 不須要 那種分享 <script src="/js/share.js" data-ajax="{'a': '1', 'b': '2'}" data-exclud="['wx', 'dd']" data-slector="share"></script>
。。。。。。部分代碼
公共函數ajax
var noop = function() {}; var hasOwnP = function(obj, prop) { return Object.hasOwnProperty.call(obj, prop); }; var toString = function(obj) { return Object.prototype.toString.call(obj); }; var isHardVar = function(obj) { var result = toString(obj); return result === '[object Object]' || result === '[object Array]'; } var merge = function() { var lg = arguments.length; var result = {}; if (lg < 2) { return arguments[0] }; for (var i = 0; i < lg; i++) { for (var key in arguments[i]) { console.log(hasOwnP(arguments[i], key), key); if (hasOwnP(arguments[i], key)) { var value = arguments[i][key]; result[key] = value; } } } return result; };
對異步處理 本身模擬的promise實現json
var JcPromise = (function() { function JcPromise(fn) { fn = fn || noop; var statusList = ['start', 'pending', 'succeed', 'err']; var cbStatus = [0, 1]; var status = statusList[0]; var data = null; var err = null; var that = this; var successFn = []; var errFn = []; function resolve(d) { data = d; that._changeStatus(2); }; function reject(e) { err = e; that._changeStatus(3); }; this.getData = function() { return data; }; this.getErr = function() { return err }; this.getStatus = function() { return status }; this._changeStatus = function(idx) { switch (status) { case statusList[2]: case statusList[3]: { return false } }; status = statusList[idx]; if (status === statusList[3]) { setTimeout(function() { that._triggerCatch(); }, 0) } if (status === statusList[2]) { setTimeout(function() { that._triggerThen(); }, 0) } }; this._pushThenCb = function(cb) { successFn.push({ status: cbStatus[0], cb: cb }); if (status === statusList[2]) { this._triggerThen(); } }; this._pushCatchCb = function(cb) { errFn.push({ status: cbStatus[0], cb: cb }); if (status === statusList[3]) { this._triggerCatch(); } }; this._triggerThen = function() { successFn.map(function(item) { if (item.status === cbStatus[0]) { item.cb(data); item.status = cbStatus[1]; } }) }; this._triggerCatch = function() { errFn.map(function(item) { if (item.status === cbStatus[0]) { item.cb(err); item.status = cbStatus[1]; } }) }; this._changeStatus(1); this.uuid = uuid++; try { fn(resolve, reject); } catch (e) { reject(e) } return this }; JcPromise.fn = JcPromise.prototype; // 返回一個promise JcPromise.fn.then = function(cb) { var promiseR = null; var promiseJ = null; var result = null; var that = this; var fn = function() { setTimeout(function() { try { var data = that.getData(); result = cb(data); if (typeof result === 'object' && result !== null && result.constructor === JcPromise) { result.then(function(data) { promiseR(data) }).catch(function(e) { promiseJ(e) }) } else { promiseR(result) } } catch (e) { promiseJ(e) } }, 0); }; this._pushThenCb(fn); // 觸發promise return new JcPromise(function(r, j) { promiseR = r; promiseJ = j; }); }; // 返回一個promise JcPromise.fn.catch = function(cb) { var promiseR = null; var promiseJ = null; var result = null; var that = this; var fn = function() { setTimeout(function() { try { var data = that.getErr(); result = cb(data); if (typeof result === 'object' && result !== null && result.constructor === JcPromise) { result.then(function(data) { promiseR(data) }).catch(function(e) { promiseJ(e) }) } else { promiseR(result) } } catch (e) { promiseJ(e) } }, 0) }; this._pushCatchCb(fn); // 觸發promise return new JcPromise(function(r, j) { promiseR = r; promiseJ = j; }); }; return JcPromise })();
懶加載加載js方法後端
function loadScript(src) { return new JcPromise(function(r, j) { var el = document.createElement('script'); el.onload = function() { r(el); }; el.onerror = function() { j(); }; el.src = src; document.body.appendChild(el); }); };
判斷 是釘🆙仍是微信api
function checkIsWx() { var userAgent = global.navigator.userAgent; var checkWx = /MicroMessenger/i; var splitWxVersion = /MicroMessenger\/([\d\.]+)/i; var version = 0; var flag = false; if (checkWx.test(userAgent)) { flag = true; version = splitWxVersion.exec(userAgent)[1]; version = parseFloat(version.replace('.', '')); } return { type: 'wx', flag: flag, version: version } }; // 檢查是否是釘釘 function checkIsDd() { var userAgent = global.navigator.userAgent; var checkDd = /DingTalk/i; var splitDdVersion = /DingTalk\/([a-zA-Z0-9.-]+)/; var version = 0; var flag = false; if (checkDd.test(userAgent)) { flag = true; version = splitDdVersion.exec(userAgent)[1]; } return { type: 'dd', flag: flag, version: version } };
// 本身照着 mdn 和其餘文檔 寫的 ajaxpromise
var jcAjax = (function() { /* @data @type @url @setHeader @createXhr */ function jcAjax(options) { var defaultHeaders = { 'X-Requested-With': 'XMLHttpRequest' }; var type = options.type, headers = options.headers, data = options.data, cb = options.cb, url = options.url, data = options.data; this.defaultHeaders = defaultHeaders; this.type = (type || 'get').toUpperCase(); this.headers = options.headers || {}; this.cb = cb || noop; this.url = url; this.data = data || {}; this.init(); }; jcAjax.fn = jcAjax.prototype; jcAjax.fn.setRequestHeader = function() { var headers = this.headers; var defaultHeaders = this.defaultHeaders; var xhr = this.xhr; var type = this.type; this.headers = headers = merge(defaultHeaders, headers); type === 'POST' && !headers['Content-Type'] && (headers['Content-Type'] = 'application/x-www-form-urlencoded'); if (headers) { for (var key in headers) { if (hasOwnP(headers, key)) { xhr.setRequestHeader(key, headers[key]); } } } }; jcAjax.fn.createXhr = function() { this.xhr = new XMLHttpRequest(); }; jcAjax.fn.listenAjax = function() { var xhr = this.xhr; var cb = this.cb; xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { var data = JSON.parse(xhr.responseText); cb(data) } }; }; jcAjax.fn.openHttp = function(type, url) { var xhr = this.xhr; xhr.open(type, url); }; jcAjax.fn.sendData = function(data) { var xhr = this.xhr; var type = this.type; data = data || null; type === 'GET' && (data === null) xhr.send(data); }; jcAjax.fn.transSendData = function() { var result = null; var headers = this.headers; var contentType = headers['Content-Type']; var data = this.data; switch (contentType) { case 'multipart/form-data': { result = new FormData(); for (var key in data) { var value = data[key]; if (hasOwnP(data, key)) { result.append(key, value) } } return result; } case 'application/json': { result = data; return result } default: { result = ''; for (var key in data) { var value = data[key]; if (hasOwnP(data, key)) { isHardVar(value) && (value = JSON.stringify(value)) result = result + key + '=' + value + '&' } } result = result.replace(/&$/, '') return result } } }; jcAjax.fn.get = function() { var data = this.data; var url = this.url; var mdUrl = ''; for (var key in data) { var value = data[key]; if (hasOwnP(data, key)) { mdUrl = mdUrl + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&' } } mdUrl.replace(/&$/, ''); this.createXhr(); this.openHttp('GET', mdUrl); this.setRequestHeader(); this.listenAjax(); this.sendData(); }; jcAjax.fn.post = function() { var sendData = null; var url = this.url; console.log(url); this.createXhr(); this.openHttp('POST', url); this.setRequestHeader(); this.listenAjax(); sendData = this.transSendData(); this.sendData(sendData); }; jcAjax.fn.init = function() { var type = this.type.toLowerCase(); this[type](); } return function(options) { return new jcAjax(options); } })()
微信分享 釘🆙分享具體 api微信
// 微信分享 由版本問題兼容問題 function wxShare(baseConfig, shareData, wxJsVersion) { function findWxSupportApi(wxJsVersion) { var jsApiList = null; var bindEvent = null; var api = null; switch (wxJsVersion) { case 1.3: { api = 'onMenuShareTimeline|onMenuShareAppMessage|onMenuShareQQ|onMenuShareWeibo|onMenuShareQZone'; jsApiList = api.split('|'); bindEvent = api.split('|'); break; } case 1.4: { api = 'updateAppMessageShareData|updateTimelineShareData|onMenuShareWeibo'; jsApiList = api.split('|'); bindEvent = api.split('|'); break; } }; return { jsApiList: jsApiList, bindEvent: bindEvent } }; var wxSupport = findWxSupportApi(wxJsVersion); var jsApiList = wxSupport.jsApiList; var bindEvent = wxSupport.bindEvent; var title = shareData.title; var desc = shareData.desc; var link = shareData.link; var imgUrl = shareData.imgUrl; wx.config({ appId: baseConfig.appId, timestamp: baseConfig.timestamp, nonceStr: baseConfig.nonceStr, signature: baseConfig.signature, jsApiList: jsApiList }); wx.ready(function() { bindEvent.forEach(function(key) { console.log(key); wx[key] && wx[key]({ title, desc, link, imgUrl, success() { var fnKey = key + 'TriggerSuccess'; var cb = wxShareTriggerCb[fnKey]; cb && cb(); }, error() { var fnKey = key + 'TriggerError'; var cb = wxShareTriggerCb[fnKey]; cb && cb(); } }) }) }) }; function ddShare(shareMsgData) { dd.ready(function() { var title = shareMsgData.title; var desc = shareMsgData.desc; var link = shareMsgData.link; var imgUrl = shareMsgData.imgUrl; dd.biz.navigation.setRight({ show: true, control: true, onSuccess: function(result) { dd.biz.util.share({ url: link, title: title, content: desc, image: imgUrl }); } }) }); };
初始化分享app
function initShare() { try { ajaxData = eval('(' + getAttr(scriptElem, 'data-ajax') + ')'); excludeUa = eval('(' + getAttr(scriptElem, 'data-exclude') + ')') || []; } catch (e) { console.log(e) } if (isWx.flag && excludeUa.indexOf('wx') === -1) { var wxVersion = isWx.version; var wxUrl = null; var wxJsVersion = 0; if (wxVersion >= 672) { wxUrl = '//res.wx.qq.com/open/js/jweixin-1.4.0.js'; wxJsVersion = 1.4; } else { wxUrl = '//res.wx.qq.com/open/js/jweixin-1.3.0.js'; wxJsVersion = 1.3; } loadScript(wxUrl).then(function(data) { // 獲取 微信簽名 --- 不知本公司那個屌絲想 return loadScript(getWxShareSignatureApi) }).then(function(baseConfig) { getShareUserMsg(ajaxData).then(function(data) { var shareFrom = data.shareH5Form; var shareData = { title: shareFrom.title, link: shareFrom.link, imgUrl: shareFrom.msgImg, desc: shareFrom.desc }; wxShare(global.weixinConfigInfo, shareData, wxJsVersion); hadGetShareMsgHook(data); }) }) } if (isDd.flag && excludeUa.indexOf('dd') === -1) { loadScript(ddUrl).then(function(data) { //獲取分享信息 getShareUserMsg(ajaxData).then(function(data) { var shareFrom = data.shareH5Form; var shareData = { title: shareFrom.title, link: shareFrom.link, imgUrl: shareFrom.msgImg, desc: shareFrom.desc }; ddShare(shareData) hadGetShareMsgHook(data) }) }) } }