/** * social-share.js * * @author 52cik * @license mit * * @example *
 * socialshare('.share-components');
 *
 * // or
 *
 * socialshare('.share-bar', {
 *     sites: ['qzone', 'qq', 'weibo','wechat'],
 *     // ...
 * });
 * 
*/ ;(function (window, document, undefined) { // initialize a variables. var array$indexof = array.prototype.indexof; var object$assign = object.assign; var runninginwechat = /micromessenger/i.test(navigator.useragent); var ismobilescreen = document.documentelement.clientwidth <= 768; var image = (document.images[0] || 0).src || ''; var site = getmetacontentbyname('site') || getmetacontentbyname('site') || document.title; var title = getmetacontentbyname('title') || getmetacontentbyname('title') || document.title; var description = getmetacontentbyname('description') || getmetacontentbyname('description') || ''; var defaults = { url: location.href, origin: location.origin, source: site, title: title, description: description, image: image, imageselector: undefined, weibokey: '', wechatqrcodetitle: '扫一扫', wechatqrcodehelper: '

分享到你得朋友圈

', wechatqrcodesize: 100, sites: ['weibo', 'qq', 'wechat', 'douban', 'qzone', 'linkedin', 'facebook', 'twitter', 'google'], mobilesites: [], disabled: [], initialized: false }; var templates = { qzone: 'http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url={{url}}&title={{title}}&desc={{description}}&summary={{summary}}&site={{source}}&pics={{image}}', qq: 'http://connect.qq.com/widget/shareqq/index.html?url={{url}}&title={{title}}&source={{source}}&desc={{description}}&pics={{image}}&summary="{{summary}}"', weibo: 'https://service.weibo.com/share/share.php?url={{url}}&title={{title}}&pic={{image}}&appkey={{weibokey}}', wechat: 'javascript:', douban: 'http://shuo.douban.com/!service/share?href={{url}}&name={{title}}&text={{description}}&image={{image}}&starid=0&aid=0&style=11', linkedin: 'http://www.linkedin.com/sharearticle?mini=true&ro=true&title={{title}}&url={{url}}&summary={{summary}}&source={{source}}&armin=armin', facebook: 'https://www.facebook.com/sharer/sharer.php?u={{url}}', twitter: 'https://twitter.com/intent/tweet?text={{title}}&url={{url}}&via={{origin}}', google: 'https://plus.google.com/share?url={{url}}' }; /** * expose api to the global * * @param {string|element} elem * @param {object} options */ window.socialshare = function (elem, options) { elem = typeof elem === 'string' ? queryselectoralls(elem) : elem; if (elem.length === undefined) { elem = [elem]; } each(elem, function (el) { if (!el.initialized) { share(el, options); } }); }; // domready after initialization already(function () { socialshare('.social-share, .share-component'); }); /** * initialize a share bar. * * @param {object} $options globals (optional). * * @return {void} */ function share(elem, options) { var data = mixin({}, defaults, options || {}, dataset(elem)); if (data.imageselector) { data.image = queryselectoralls(data.imageselector).map(function(item) { return item.src; }).join('||'); } addclass(elem, 'share-component social-share'); createicons(elem, data); createwechat(elem, data); elem.initialized = true; } /** * create site icons * * @param {element} elem * @param {object} data */ function createicons(elem, data) { var sites = getsites(data); var isprepend = data.mode == 'prepend'; each(isprepend ? sites.reverse() : sites, function (name) { var url = makeurl(name, data); var link = data.initialized ? getelementsbyclassname(elem, 'icon-' + name) : createelementbystring(''); if (!link.length) { return true; } link[0].href = url; if (name === 'wechat') { link[0].tabindex = -1; } else { link[0].target = '_blank'; } if (!data.initialized) { isprepend ? elem.insertbefore(link[0], elem.firstchild) : elem.appendchild(link[0]); } }); } /** * create the wechat icon and qrcode. * * @param {element} elem * @param {object} data */ function createwechat (elem, data) { var wechat = getelementsbyclassname(elem, 'icon-wechat', 'a'); if (wechat.length === 0) { return false; } var elems = createelementbystring('

' + data.wechatqrcodetitle + '

' + data.wechatqrcodehelper + '
'); var qrcode = getelementsbyclassname(elems[0], 'qrcode', 'div'); new qrcode(qrcode[0], {text: data.url, width: data.wechatqrcodesize, height: data.wechatqrcodesize}); wechat[0].appendchild(elems[0]); } /** * get available site lists. * * @param {object} data * * @returns {array} */ function getsites(data) { if (!data['mobilesites'].length) { data['mobilesites'] = data['sites']; } var sites = (ismobilescreen ? data['mobilesites'] : data['sites']).slice(0); var disabled = data['disabled']; if (typeof sites == 'string') { sites = sites.split(/\s*,\s*/); } if (typeof disabled == 'string') { disabled = disabled.split(/\s*,\s*/); } if (runninginwechat) { disabled.push('wechat'); } // remove elements disabled.length && each(disabled, function (it) { sites.splice(inarray(it, sites), 1); }); return sites; } /** * build the url of icon. * * @param {string} name * @param {object} data * * @returns {string} */ function makeurl(name, data) { if (! data['summary']){ data['summary'] = data['description']; } return templates[name].replace(/\{\{(\w)(\w*)\}\}/g, function (m, fix, key) { var namekey = name + fix + key.tolowercase(); key = (fix + key).tolowercase(); return encodeuricomponent((data[namekey] === undefined ? data[key] : data[namekey]) || ''); }); } /** * supports queryselectorall, jquery, zepto and simple selector. * * @param str * * @returns {*} */ function queryselectoralls(str) { return (document.queryselectorall || window.jquery || window.zepto || selector).call(document, str); } /** * simple selector. * * @param {string} str #id or .class * * @returns {array} */ function selector(str) { var elems = []; each(str.split(/\s*,\s*/), function(s) { var m = s.match(/([#.])(\w+)/); if (m === null) { throw error('supports only simple single #id or .class selector.'); } if (m[1]) { var elem = document.getelementbyid(m[2]); if (elem) { elems.push(elem); } } elems = elems.concat(getelementsbyclassname(str)); }); return elems; } /** * add the classnames for element. * * @param {element} elem * @param {string} value */ function addclass(elem, value) { if (value && typeof value === "string") { var classnames = (elem.classname + ' ' + value).split(/\s+/); var setclass = ' '; each(classnames, function (classname) { if (setclass.indexof(' ' + classname + ' ') < 0) { setclass += classname + ' '; } }); elem.classname = setclass.slice(1, -1); } } /** * get meta element content value * * @param {string} name * * @returns {string|*} */ function getmetacontentbyname(name) { return (document.getelementsbyname(name)[0] || 0).content; } /** * get elements by classname for ie8- * * @param {element} elem element * @param {string} name classname * @param {string} tag tagname * * @returns {htmlcollection|array} */ function getelementsbyclassname(elem, name, tag) { if (elem.getelementsbyclassname) { return elem.getelementsbyclassname(name); } var elements = []; var elems = elem.getelementsbytagname(tag || '*'); name = ' ' + name + ' '; each(elems, function (elem) { if ((' ' + (elem.classname || '') + ' ').indexof(name) >= 0) { elements.push(elem); } }); return elements; } /** * create element by string. * * @param {string} str * * @returns {nodelist} */ function createelementbystring(str) { var div = document.createelement('div'); div.innerhtml = str; return div.childnodes; } /** * merge objects. * * @returns {object} */ function mixin() { var args = arguments; if (object$assign) { return object$assign.apply(null, args); } var target = {}; each(args, function (it) { each(it, function (v, k) { target[k] = v; }); }); return args[0] = target; } /** * get dataset object. * * @param {element} elem * * @returns {object} */ function dataset(elem) { if (elem.dataset) { return json.parse(json.stringify(elem.dataset)); } var target = {}; if (elem.hasattributes()) { each(elem.attributes, function (attr) { var name = attr.name; if (name.indexof('data-') !== 0) { return true; } name = name.replace(/^data-/i, '') .replace(/-(\w)/g, function (all, letter) { return letter.touppercase(); }); target[name] = attr.value; }); return target; } return {}; } /** * found element in the array. * * @param {array|object} elem * @param {array} arr * @param {number} i * * @returns {number} */ function inarray(elem, arr, i) { var len; if (arr) { if (array$indexof) { return array$indexof.call(arr, elem, i); } len = arr.length; i = i ? i < 0 ? math.max(0, len + i) : i : 0; for (; i < len; i++) { // skip accessing in sparse arrays if (i in arr && arr[i] === elem) { return i; } } } return -1; } /** * simple each. * * @param {array|object} obj * @param {function} callback * * @returns {*} */ function each(obj, callback) { var length = obj.length; if (length === undefined) { for (var name in obj) { if (obj.hasownproperty(name)) { if (callback.call(obj[name], obj[name], name) === false) { break; } } } } else { for (var i = 0; i < length; i++) { if (callback.call(obj[i], obj[i], i) === false) { break; } } } } /** * dom ready. * * @param {function} fn * * @link https://github.com/jed/already.js */ function already ( fn ) { var add = 'addeventlistener'; var pre = document[ add ] ? '' : 'on'; ~document.readystate.indexof( 'm' ) ? fn() : 'load domcontentloaded readystatechange'.replace( /\w+/g, function( type, i ) { ( i ? document : window ) [ pre ? 'attachevent' : add ] ( pre + type, function(){ if ( fn ) if ( i < 6 || ~document.readystate.indexof( 'm' ) ) fn(), fn = 0 }, !1 ) }) } })(window, document);