对于分享插件来说,大家肯定都很熟悉,最常用的就是百度分享、jiathis分享等,可分享的媒体也非常多,当然最常用的需求无非也就新浪微博、QQ空间、QQ好友、微信朋友圈、微信好友,其他什么乱七八糟的人人网、猫扑、豆瓣就不多做考虑了,插件内的更多选项列出来有20多个。。。
既然插件功能已经这么完善了,那还有什么好说的,看看文档就能解决了还有什么好总结的?
但是,问题来了,以上的插件在微信分享时,都是生成一个二维码供用户手机扫一扫,如下图:
这在pc端没问题,但是在移动端的时候,如果浏览器不支持长按识别二维码功能。。。(我能怎么扫啊,我也很绝望啊),而且即使支持也会感觉用户体验很差,分享很费劲。。。
所以,本篇总结的是 如何尽可能的在移动端浏览器中使用微信分享功能(尽可能。。。。有的地方真的,臣妾做不到啊。),本文中主要是对网上个方法的总结,个人使用经验,没有什么原创干货。
开始进入正题:
需求:需要在微信、各种移动端浏览器、QQ内置浏览器中实现将页面分享至微信好友、朋友圈、新浪微博、QQ好友、QQ空间。
分析:常用插件(百度、jiathis等)对于移动端的微信分享会出现上面刚开始讨论的问题,手机上弹出二维码无法使用,其他的媒体分享方式倒是正常,所以就移动端微信分享的问题进一步学习。
经过一番资料查找发现:
- 微信中,只能通过提示点击右上角进行分享
- QQ浏览器、UC浏览器可通过开放的API调用微信分享
- 其他的浏览器没有明确的分享接口,但是大都可以手动通过设置菜单进行分享到微信中
- 其他的浏览器没有明确的分享接口,可以通过URL scheme调整至QQ浏览器(前提是要安装了QQ浏览器)
参考资料:
soshm.js 一个具有中国特色的社交分享组件 demo
经过一番查找,最后使用soshm.js进行功能开发,因为soshm.js使用webpack把图标、css、js等都打包成一个soshm.js,引用方便,而且样式也不错,也能达到需要的配置功能,所以。。。。。
使用后。。。。测试后。。。。
根据自己的需求对源码做了一些修改,总结下该插件的几个问题:
- UC浏览器使用分享时,自定义图片无效,直接截屏,会截取到分享的弹窗遮罩(这个是UC浏览器的问题)
- QQ内置浏览器中无法使用分享功能,测试就分享到腾讯微博有跳转(暂定解决办法:同微信提示右上角菜单分享)
- QQ内置浏览器使用右上角自带分享功能如何自定义标题图片链接等的问题 QQ对外分享组件接口文
- 除QQ、UC浏览器之外的浏览器对于分享至微信好友、微信朋友圈的处理
好了,现在就对问题一个一个来修改吧:
问题一:UC浏览器使用分享时,自定义图片无效,直接截屏,会截取到分享的弹窗遮罩(这个是UC浏览器的问题);
查看soshm.js中关于UC浏览器操作代码:
1 if (device.isUCBrowser) { //判断是uc浏览器 2 if (nativeShareApps[site]) { //判断选择的分享方式是否支持 3 app = device.isIOS ? nativeShareApps[site][0] : nativeShareApps[site][1]; //区分IOS和安卓不同的方法名称 4 } 5 6 if (app !== undefined) { 7 shareInfo = [data.title, data.digest, data.url, app, '', '@'+data.from, '']; //配置分享信息 8 9 // android 10 if (window.ucweb) { 11 ucweb.startRequest && ucweb.startRequest('shell.page_share', shareInfo); 12 } 13 14 // ios 15 if (window.ucbrowser) { 16 ucbrowser.web_share && ucbrowser.web_share.apply(null, shareInfo); 17 } 18 return; 19 } 20 }
从第7行中发现配置的shareInfo数据第二项为自定义图片路径,但是实际使用时会发现 data.digest 会显示在 简介 中,而图片是截屏,
网上找了很久,没有找到对应的UC浏览器的分享接口,这就很尴尬了,也试着改变 data.digest的位置,没有收效,所以。。。最后只能选择一个折中的办法:
图片使用截屏,但要隐藏分享插件的遮罩层,尽量显示页面的内容,所以,继续改soshm.js咯
下方代码为 点击分享按钮,弹窗分享遮罩,并给按钮绑定事件,点击空白处关闭遮罩的方法;
1 soshm.popIn = function(options) { 2 var popDelegation; 3 var pop = doc.querySelector('.soshm-pop'); 4 if (!pop) { 5 pop = doc.createElement('div'); 6 pop.className = 'soshm-pop'; 7 body.appendChild(pop); 8 } 9 10 options = extend({}, defaults, options); 11 pop.innerHTML = 12 '<div class="soshm-pop-sites">' + 13 getSitesHtml(options.sites, 3) + 14 '</div>'; 15 16 var popDelegation = delegate(pop, '.soshm-item', 'click', function(e) { 17 var site = e.delegateTarget.dataset.site; 18 pop.style.display = 'none'; 19 setTimeout(function() { 20 shareTo(site, options); 21 }, 50); 22 });
要想在UC浏览器截屏之前关闭遮罩,想法是在点击具体分享功能后,执行shareTo之前,执行pop.style.display = 'none';关闭遮罩层,实现起来好像很简单,但是为什么要在加一个setTimeout,延迟50毫米来执行shareTo呢?
这也是无奈,如果直接使用pop.style.display = 'none';紧跟着执行shareTo(site, options); 你会发现没有效果,遮罩层还是会被截取到,起初以为是pop元素上有 transition 0.6S过渡的原因,结果使用 pop.parentNode.removeChild(pop)直接删除pop元素,
发现也是无效的,这是为什么呢???? 还没搞明白, 后来只能使用setTimeout进行延迟处理,50毫米即可,还可以更小。。。。 DOM操作为什么不会在shareTo之前完成,有没大神知道的。。
23 pop.classList.remove('soshm-pop-hide'); 24 pop.style.display = 'block'; 25 setTimeout(function() { 26 pop.classList.add('soshm-pop-show'); 27 }.bind(this), 0); 28 29 pop.addEventListener('click', function() { 30 pop.classList.remove('soshm-pop-show'); 31 pop.classList.add('soshm-pop-hide'); 32 setTimeout(function() { 33 pop.style.display = 'none'; 34 popDelegation.destroy(); 35 }, 1100); 36 }, false); 37 };
问题二:QQ内置浏览器中无法使用分享功能,测试就分享到腾讯微博有跳转(暂定解决办法:同微信提示右上角菜单分享);
原因:通过在代码中添加alert()调试,发现QQ内置浏览器打开分享时,运行到了 QQ浏览器APP中,使用了QQ浏览器APP的接口进行分享就无效了,两者不知道怎么共通,这些都没有相关文档查看,一头雾水,
所以,又是一个折中的办法 判断如果是QQ内置浏览器中,则同微信提示右上角菜单分享;效果如下:
这时候,问题又来了(蛋疼。。。),怎么区分微信、QQ浏览器APP、QQ内置浏览器这三者呢?三个本来同根生,就是尼玛非的长得不一样。。。
判断浏览器类型最常用的办法肯定就是 用户代理(user agent),获取方式:window.navigator.userAgent,然后你就会获得一长串比如下方的 安卓中对于三个兄弟的userAgent:
之前是通过MicroMessenger 判断是否是微信中打开,
通过MQQBrowser判断 是否是QQ浏览器APP中打开,
但是要判断是否是QQ内置浏览器打开的就有点尴尬了,经过暗中观察发现一些区别:
1、微信和QQ内置中代由mobile前缀, 而QQ浏览器APP只有MQQBrowser
2、QQ内置浏览器会出现 V1_AND_SQ_6.7.1_YYB_D QQ这些字段;
最后:使用 'Mobile MQQBrowser' && ! 'MicroMessenger' 来判断QQ内置浏览器,由于手上没什么测试机,暂时在本人安卓上是能正确判断的,可能对于不同系统、不同版本软件或存在问题,这个待日后测试;
满心欢喜的又以为弄好了QQ内置浏览器分享,可是。。。。他喵的,一使用,分享到QQ好友 微信好友等,发现尼玛 标题、简介、图片 什么都没有,微信中直接一个null,贼尴尬,这也就引发了第三个问题;
问题三:QQ内置浏览器使用右上角自带分享功能如何自定义标题图片链接等的问题
又他喵的一番苦问,苦找,发现原来要想自定义QQ内置浏览器右上角分享需要像微信中分享一样,载入官方JS,才能进行相应的配置;
官方链接:QQ对外分享组件接口 手机QQ内置网页,微信内置网页中进行分享到QQ和微信的操作
这下终于能好点了吧:
if (deviceDetect('Mobile MQQBrowser') && !deviceDetect('MicroMessenger')) { //判断是QQ内置浏览器 loadScript('http://qzonestyle.gtimg.cn/qzone/qzact/common/share/share.js', function() { setShareInfo({ title: '{$goods.goods_name}', summary: '{$goods.goods_name}', pic:"图片路径", url: “页面url” }); }) }
//loadScript 用于插入官方js function loadScript(url, done) { var script = document.createElement('script'); script.src = url; script.onload = onreadystatechange = function() { if (!this.readyState || this.readyState === 'load' || this.readyState === 'complete') { done && done(); script.onload = onreadystatechange script.parentNode.removeChild(script); } }; document.body.appendChild(script); }
问题四:除QQ、UC浏览器之外的浏览器对于分享至微信好友、微信朋友圈的处理;
各种款式各种版本的浏览器多不胜数,无法一一对应写出分享调用,况且也拿不到分享接口(这个最蛋疼,UC和QQ也都是前人留下的不懂哪里查看,哪天要是不爽给改了,那就。。。。),
所以对于其他类型的浏览器处理办法:
1、隐藏微信相关的分享;
2、点击微信分享,弹窗提示用户手动使用浏览器菜单中的分享功能,现在的手机浏览器大都支持分享到微信中;
综合考虑,选择第二种方式比较适合,修改:
1 // 在普通浏览器里点击微信分享,通过QQ浏览器当桥梁唤起微信客户端 2 // 如果没有安装QQ浏览器则点击无反应 3 if (site.indexOf('weixin') !== -1) { 4 layer.open({content:'请使用浏览器菜单中分享按钮,选择分享至微信', skin:'msg', time:5}); 这里使用了layer插件进行弹窗提示,大家可以根据自己的情况修改;
5 // var mttbrowserURL = appendToQuerysting(location.href, {__soshmbridge: site}); 6 // openAppByScheme('mttbrowser://url=' + mttbrowserURL);
上面是原来的代码,使用的是URL scheme调用QQ浏览器APP,但是前提是你安装了QQ浏览器,即使按照了QQ浏览器,也只能在QQ浏览器中打开该页面,还是得手动再次点击分享,个人感觉有点鸡肋。。。。
7 }
一个移动端分享插件,磕磕绊绊,虽然没有真正的解决所有浏览器的分享问题,但也达到了能较好的使用,感谢soshm.js作者 https://github.com/calledT/soshm
后续继续改进。。