Skip to content

Instantly share code, notes, and snippets.

@Yang03
Created August 9, 2018 09:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Yang03/bb54abea2154f1e431799f2a3915ed59 to your computer and use it in GitHub Desktop.
Save Yang03/bb54abea2154f1e431799f2a3915ed59 to your computer and use it in GitHub Desktop.
share.js
void function(){
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9+/=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
var Config = {
bxLogo: location.protocol + 'a.png',
appList: {
sinaweibo: ["kSinaWeibo", "SinaWeibo", 11, "\u65B0\u6D6A\u5FAE\u535A"],
wechatfriends: ["kWeixin", "WechatFriends", 1, "\u5FAE\u4FE1\u597D\u53CB"],
wechattimeline: ["kWeixinFriend", "WechatTimeline", "8", "\u5FAE\u4FE1\u670B\u53CB\u5708"],
qq: ["kQQ", "QQ", "4", "QQ\u597D\u53CB"],
qzone: ["kQZone", "QZone", "3", "QQ\u7A7A\u95F4"]
},
shareList: {
'wechatfriends': '微信好友',
'wechattimeline': '朋友圈',
'qq': 'QQ好友',
'qzone': 'QQ空间',
'sinaweibo': '新浪微博',
'baidu': '百度贴吧',
'copy': '复制链接'
}
}
var Util = {
loadScript: function(src, callback){
var script = document.createElement("script");
var body = document.getElementsByTagName("body")[0];
script.setAttribute("src", src),
script.onload = script.onreadystatechange = function() {
this.readyState && "loaded" != this.readyState && "complete" != this.readyState || (callback && callback(),
script.onload = script.onreadystatechange = null ,
script.parentNode.removeChild(script))
};
body.appendChild(script);
},
addParams: function(url, params) {
var query, key, value;
for (key in params){
value = params[key],
query = new RegExp("(" + key + "=)[^&]+","i"),
url.match(query) ? url = url.replace(query, "$1" + value) : url += url.indexOf("?") === -1 ? "?" + key + "=" + value : "&" + key + "=" + value;
}
return url
},
addIframe: function(url){
var div = document.createElement("div");
div.style.visibility = "hidden";
div.innerHTML = '<iframe src="' + url + '" scrolling="no" width="1" height="1"></iframe>';
document.body.appendChild(div);
setTimeout(function() {
div && div.parentNode && div.parentNode.removeChild(div)
}, 5000);
}
}
var Share = function(selector, options){
this.selector = selector
// 设置基本的分享属性
var defaultOptions = {
title: $("title").text() || "",
desc: $("meta[name=description]").attr("content") || $("title").text(),
url: document.location.href || "",
image: Config.bxLogo,
from: "\u767e\u59d3\u7f51", // 百姓网
useDefaultPanel: true,
tag: 'default' // 用于打点标记
}
if(options && $.isPlainObject(options)){
$.extend(this, defaultOptions, options)
}
this.getDevice()
if(this.useDefaultPanel){
this.addPanelAndMask()
this.bindBtnClickEvent()
}else{
var browser = this.device.browser
if(!(browser.isQQ || browser.isSogou || browser.isUC)){
$('[data-app="wechatfriends"], [data-app="wechattimeline"]').parents('li').hide()
}
}
this.bindSnsClickEvent()
this.init()
}
Share.prototype.bindBtnClickEvent = function(){
$(this.selector).css({cursor: 'pointer'});
$(document).on("click", this.selector, function(){
var $container = Share.$container
var $mask = Share.$mask
$container && $container.show();
$mask.show();
});
}
Share.prototype.bindSnsClickEvent = function(){
var that = this;
$(document).on("click", '.sns', function(){
var type = $(this).attr("data-app");
window.tracker && tracker.evt('wap_share_component', {src: that.tag, type: type})
if(type === 'copy'){
that.useDefaultPanel && that.openCopyPanel();
}else{
that.shareto(type);
}
});
}
Share.prototype.addPanelAndMask = function(){
// 如果已经生成过一次分享组件的dom, 就不需要再执行以下的步骤了
if(Share.$mask) return;
if(!this.selector) return;
var $mask = $('<div id="share-mask" class="hide page-mask"></div>')
var $container = null
var isWechat = this.device.browser.isWechat
if(isWechat) {
$mask = $mask.append('<div id="weixin-leading-img">')
$('body').append($mask)
} else {
$container = $('<div class="hide share-pop"></div>')
var $list = $('<ul></ul>')
var listStr = ''
var $copyPanel = $(
'<div id="copy-panel" class="hide">' +
'<div id="copy-return">返回</div>' +
'<p class="copy-hint">长按复制下方链接,粘贴给好友吧!</p>' +
'<div id="copy-link">' +
'<p>' +
Util.addParams(this.url, {shareWay: 'copy', sharePlatform: 'wap'}) +
'</p>' +
'</div>' +
'</div>')
for(var key in Config.shareList){
// safari中不显示微信朋友圈和微信好友
if((key === 'wechatfriends' || key === 'wechattimeline')){
var browser = this.device.browser
var hasOriginalApi = browser.isQQ || browser.isSogou || browser.isUC
if(!hasOriginalApi) continue
}
listStr += '<li><a class="sns" href="javascript:;" data-app="' + key + '"><i class="share-component-icon share-component-icon-' + key + '"></i>' + Config.shareList[key] + '</a></li>'
}
$list.append(listStr);
$container.append($list).append($copyPanel).append('<div class="close">×</div>')
$('body').append($container).append($mask);
}
Share.$mask = $mask;
Share.$container = $container;
isWechat && $mask.on('click', function(){
$(this).hide()
})
$('.close').on('click', function(){
$container && $container.hide();
$mask.hide();
})
}
Share.prototype.getDevice = function(){
var ua = this.ua = navigator.userAgent.toLowerCase();
this.device = {
os: {
version: 0,
isiOS: ua.indexOf("iphone") > -1 || ua.indexOf("ipad") > -1 || ua.indexOf("ios") > -1,
isAndroid: ua.indexOf("android") > -1 || ua.indexOf("adr") > -1 || ua.indexOf("linux;") > -1
},
browser: {
version: 0,
isQQ: ua.indexOf("mqqbrowser/") > -1,
isUC: ua.indexOf("ucbrowser/") > -1,
isWechat: ua.indexOf("micromessenger") > -1,
isSamsung: ua.indexOf("samsungbrowser/") > -1,
isSogou: ua.indexOf("sogoumobilebrowser/") > -1,
isFirefox: ua.indexOf("firefox/") > -1,
isBaidu: ua.indexOf("baiduboxapp/") > -1,
isSafari: ua.indexOf("safari") > -1 && ua.indexOf("chrome") == -1,
isWeChat: ua.indexOf("micromessenger") > -1
},
brand: {
isOppo: ua.indexOf("oppo") > -1
}
}
}
Share.prototype.getVersion = function(version){
var versionNum = version.split(".");
return parseFloat(versionNum[0] + "." + versionNum[1])
}
Share.prototype.init = function(){
var device = this.device;
if(device.browser.isQQ){
if(typeof browser == "undefined"){
Util.loadScript("//jsapi.qq.com/get?api=app.setShareInfo,app.share", function() {
this.shareWechatByQQBrowser()
}.bind(this))
}else{
this.shareWechatByQQBrowser()
}
device.browser.version = this.getVersion(this.ua.split("mqqbrowser/")[1])
}else{
device.browser.isUC && (device.browser.version = this.getVersion(this.ua.split("ucbrowser/")[1]))
device.os.isiOS && (device.os.version = parseInt(this.ua.match(/\s*os\s*\d\d?/gi)[0].split(" ")[2], 10))
}
}
Share.prototype.openCopyPanel = function(){
var $container = Share.$container
if(!$container) return;
var $list = $container.find('ul')
var $copy = $container.find('#copy-panel')
$list.hide();
$copy.show().find('#copy-return').on('click', function(){
$list.show()
$copy.hide()
});
}
Share.prototype.shareWechatByQQBrowser = function(){
var app = window.location.href.match(/shareApp=(\w+)/i);
if (app) {
var type = app[1];
if($.isFunction(history.replaceState)){
history.replaceState(null , document.title, location.href.replace(/shareApp=wechatfriends/g, ""))
history.replaceState(null , document.title, location.href.replace(/shareApp=wechattimeline/g, ""))
}
this.shareto(type)
}
}
Share.prototype.shareto = function(type){
var device = this.device,
title = this.title,
desc = this.desc,
url = Util.addParams(this.url, {shareWay: type, sharePlatform: 'wap'}),
image = this.image,
from = this.from,
encodedUrl = Base64.encode(url),
encodedImage = Base64.encode(image),
encodedTitle = Base64.encode(title),
encodedDesc = Base64.encode(desc),
encodedFrom = Base64.encode(from),
timestamp = Date.now();
switch(type){
case 'qzone':
var config = {
android: "mqqapi://share/to_qzone?src_type=app&version=1&file_type=news&req_type=1",
ios: "mqqapi://share/to_fri?file_type=news&src_type=app&version=1&generalpastboard=1&shareType=1&cflag=1&objectlocation=pasteboard&callback_type=scheme&callback_name=QQ41AF4B2A&"
}
if(device.os.isAndroid){
if(device.brand.isOppo || device.browser.isBaidu){ // OPPO手机 以及 手机百度无法唤醒, 所以强制使用web share
this.shareWebQzone()
break
}
device.browser.isUC ? Util.addIframe(Util.addParams(config.android, {
url: encodedUrl,
image_url: encodedImage,
title: encodedTitle,
description: encodedDesc,
app_name: encodedFrom
})) : window.location.href = Util.addParams(config.android, {
url: encodedUrl,
previewimageUrl: encodedImage,
title: encodedTitle,
description: encodedDesc,
thirdAppDisplayName: encodedFrom
})
}else{
window.location.href = Util.addParams(config.ios, {
url: encodedUrl,
previewimageUrl: encodedImage,
title: encodedTitle,
description: encodedDesc,
thirdAppDisplayName: encodedFrom
})
}
setTimeout(function() {
var offset = Date.now() - timestamp;
offset < 2100 && this.shareWebQzone()
}.bind(this), 2000)
break;
case 'qq':
window.location.href = Util.addParams("mqqapi://share/to_fri?src_type=web&version=1&file_type=news", {
title: encodedTitle,
description: encodedDesc,
thirdAppDisplayName: encodedFrom, // 百姓网
share_id: 100584285,
url: encodedUrl
})
break;
case 'baidu':
var openUrl = function(){
window.location.href = Util.addParams("http://tieba.baidu.com/f/commit/share/openShareApi", {
url: encodeURIComponent(url),
title: encodeURIComponent(title)
//desc: encodeURIComponent(desc),
//comment: '',
//pic: encodeURIComponent(image)
});
};
if(device.browser.isFirefox){
setTimeout(openUrl,0)
}else{
openUrl()
}
break;
case 'wechatfriends':
case 'wechattimeline':
case 'sinaweibo':
if (device.browser.isUC){
var uctype;
if(device.os.isiOS && typeof ucbrowser != "undefined"){
uctype = Config.appList[type][0];
ucbrowser.web_share(title, title, url, uctype, "", " @" + desc + " ", "")
}else{
if(typeof ucweb != "undefined"){
uctype = Config.appList[type][1];
ucweb.startRequest("shell.page_share", [title, title + " @" + desc + " ", url, uctype, "", "", ""]);
}else{
console.log("UCBrowser native share bypass.")
}
}
}else if(device.browser.isQQ) {
var qqtype = Config.appList[type][2];
var data = {
url: url,
title: title,
img_url: image,
to_app: qqtype,
cus_txt: title + " @\u767e\u59d3\u7f51 "
};
browser && browser.app && browser.app.share ? browser.app.share(data) : console.log("QQBrowser native share bypass.")
}else if(device.browser.isSogou) {
var data = {
shareTitle: title,
shareContent: desc,
shareImageUrl: image,
shareUrl: url,
shareSnapshotTab: "",
shareType: null
};
if(type == "wechatfriends" || type == "wechattimeline"){
if(type == "wechatfriends"){
data.shareType = 2
}
if(type == "wechattimeline"){
data.shareType = 4
}
SogouMse && SogouMse.Utility && SogouMse.Utility.shareWithInfo ? SogouMse.Utility.shareWithInfo(data) : console.log("sogouBrowser native share error.");
}else{
window.location.href = Util.addParams("http://v.t.sina.com.cn/share/share.php", {
title: encodeURIComponent(title),
url: encodeURIComponent(url),
appkey: "217550396",
pic: encodeURIComponent(image),
source: '',
sourceUrl: '',
content: 'gb2312'
//ralateUid: "1934323297",
//count: "n",
//size: "middle"
})
}
}else if(type == "wechatfriends"|| type == "wechattimeline") {
url = Util.addParams(url, {
shareApp: type
});
if(device.os.isiOS && device.os.version > 8){
window.location.href = "mttbrowser://url=" + url;
}else{
Util.addIframe("mttbrowser://url=" + url);
}
}else{
if(type == "sinaweibo"){
window.location.href = Util.addParams("http://v.t.sina.com.cn/share/share.php", {
title: encodeURIComponent(title),
url: encodeURIComponent(url),
appkey: "217550396",
pic: encodeURIComponent(image),
source: '',
sourceUrl: '',
content: 'gb2312'
//ralateUid: "1934323297",
//count: "n",
//size: "middle"
})
}
}
break;
}
}
Share.prototype.shareWebQzone = function(){
var api = "//openmobile.qq.com/api/check2?page=qzshare.html&loginpage=loginindex.html&logintype=qzone"
var desc = this.desc.substring(0, 200)
var query = ["title=" + encodeURIComponent(this.title), "imageUrl=" + encodeURIComponent(this.image), "desc=" + encodeURIComponent(desc), "url=" + this.url, "successUrl=" + this.url].join("&");
window.location.href = api + "&" + query
}
window.Share = Share;
}()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment