share button is always beside

Append share button in all pages.

  1. // ==UserScript==
  2. // @name share button is always beside
  3. // @namespace http://www.sharkpp.net/
  4. // @version 0.2
  5. // @description Append share button in all pages.
  6. // @author sharkpp
  7. // @copyright 2016, sharkpp
  8. // @license MIT License
  9. // @include *
  10. // @exclude https://www.google.co.jp/_/chrome/newtab*
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. var NS = 'sns-share-button-for-all-pages-';
  17.  
  18. if (window != parent || // exit when if loaded in iframe
  19. NS+'share-popup' == window.name) { // exit when if call from popup windows
  20. return;
  21. }
  22.  
  23. var evaluate_ = function (xpath, resultOnce) {
  24. resultOnce = 'undefined' == typeof resultOnce ? false : resultOnce;
  25. var items = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  26. return resultOnce ? (items.snapshotLength ? items.snapshotItem(0) : null)
  27. : items;
  28. };
  29.  
  30. var applyStyles = function (elm, styles, overwriteStyles) {
  31. overwriteStyles = overwriteStyles || {};
  32. for (var name in styles) {
  33. elm.style[name] = overwriteStyles[name] || styles[name];
  34. }
  35. };
  36.  
  37. var baseElmStyles = {
  38. inital: {
  39. top: '10px',
  40. left: '-1px',
  41. width: '30px',
  42. height: '50px',
  43. borderRadius: '0 2px 2px 0',
  44. padding: '2px',
  45. opacity: '0.6',
  46. transition: ''
  47. },
  48. initalOpen: {
  49. left: '10px',
  50. width: 'auto',
  51. height: 'auto',
  52. borderRadius: '3px',
  53. padding: '6px',
  54. opacity: '1',
  55. transition: ''
  56. },
  57. stick: {
  58. top: '-1px',
  59. left: '-1px',
  60. width: '50px',
  61. height: '50px',
  62. borderRadius: '0 0 50px 0',
  63. padding: '2px',
  64. opacity: '0.6',
  65. transition: ''
  66. },
  67. stickOpen: {
  68. top: '10px',
  69. left: '10px',
  70. width: 'auto',
  71. height: 'auto',
  72. borderRadius: '3px',
  73. padding: '6px',
  74. opacity: '1',
  75. transition: ''
  76. },
  77. };
  78. var panelOpenElmStyles = {
  79. inital: {
  80. display: 'block',
  81. width: '100%',
  82. height: '44px',
  83. lineHeight: '44px',
  84. fontSize: '20px',
  85. transform: '',
  86. },
  87. initalOpen: {
  88. display: 'none',
  89. },
  90. stick: {
  91. display: 'block',
  92. width: '35px',
  93. height: '35px',
  94. lineHeight: '35px',
  95. fontSize: '30px',
  96. transform: 'rotate(45deg)',
  97. },
  98. stickOpen: {
  99. display: 'none',
  100. },
  101. };
  102. var panelCloseElmStyles = {
  103. inital: {
  104. display: 'none',
  105. },
  106. initalOpen: {
  107. display: 'block',
  108. width: '100%',
  109. height: '20px',
  110. lineHeight: '20px',
  111. fontSize: '20px',
  112. transform: '',
  113. },
  114. stick: {
  115. display: 'none',
  116. },
  117. stickOpen: {
  118. display: 'block',
  119. width: '100%',
  120. height: '20px',
  121. lineHeight: '20px',
  122. fontSize: '20px',
  123. transform: '',
  124. },
  125. };
  126. var shareElmStyles = {
  127. inital: {
  128. display: 'none',
  129. },
  130. initalOpen: {
  131. display: 'block',
  132. },
  133. stick: {
  134. display: 'none',
  135. },
  136. stickOpen: {
  137. display: 'block',
  138. },
  139. };
  140.  
  141. var baseElm = document.createElement('div');
  142. baseElm.id = NS + 'base';
  143. baseElm.style.cssText = [
  144. 'box-sizing: border-box;',
  145. 'width: 0;',
  146. 'height: 0;',
  147. 'position: fixed;',
  148. 'background-color: #fff;',
  149. 'border: 1px solid #ccc;',
  150. 'border-radius: 0 2px 2px 0;',
  151. 'z-index: 2147483647;', // for Youtube
  152. ].join(" ");
  153.  
  154. var panelOpenElm = document.createElement('div');
  155. panelOpenElm.innerHTML = '»';
  156. panelOpenElm.style.cssText = [
  157. 'display: block;',
  158. 'margin: 0;',
  159. 'padding: 0;',
  160. 'top: 0;',
  161. 'left: 0;',
  162. 'vertical-align: middle;',
  163. 'text-align: center;',
  164. 'pointer-events: none;'
  165. ].join(" ");
  166.  
  167. var panelCloseElm = document.createElement('div');
  168. panelCloseElm.innerHTML = '«';
  169. panelCloseElm.style.cssText = [
  170. 'display: none;',
  171. 'margin: 0;',
  172. 'padding: 0;',
  173. 'top: 0;',
  174. 'left: 0;',
  175. 'vertical-align: middle;',
  176. 'text-align: center;',
  177. 'pointer-events: none;'
  178. ].join(" ");
  179.  
  180. var shareElm = document.createElement('div');
  181. shareElm.style.cssText = [
  182. ].join(" ");
  183.  
  184. var overlayElm = document.createElement('div');
  185. overlayElm.id = NS+'overlay';
  186. overlayElm.style.cssText = [
  187. 'display: none;',
  188. 'position: fixed;',
  189. 'width: 100%;',
  190. 'height: 100%;',
  191. 'left: 0;',
  192. 'top: 0;',
  193. 'opacity: 1;',
  194. ].join(" ");
  195.  
  196. baseElm.appendChild(shareElm);
  197. baseElm.appendChild(panelOpenElm);
  198. baseElm.appendChild(panelCloseElm);
  199. document.body.appendChild(overlayElm);
  200.  
  201. var onDocumentScroll = function(){
  202. var prevTop = parseInt(baseElm.style.top);
  203. var top = Math.max(100 - document.body.scrollTop, 10);
  204. var isSticky = top <= 10;
  205. var state = isSticky?'stick':'inital';
  206. var transition = 10 == prevTop || 10 == top ? 'all 300ms 0s ease' : '';
  207. if (!isSticky) {
  208. applyStyles(baseElm, baseElmStyles[state], {
  209. top: ''+top+'px',
  210. transition: transition
  211. });
  212. }
  213. else {
  214. applyStyles(baseElm, baseElmStyles[state], {
  215. transition: transition
  216. });
  217. }
  218. applyStyles(panelOpenElm, panelOpenElmStyles[state]);
  219. applyStyles(panelCloseElm, panelCloseElmStyles[state]);
  220. applyStyles(shareElm, shareElmStyles[state]);
  221. overlayElm.style.display = 'none';
  222. };
  223.  
  224. var selectedText = '', selectedRange;
  225.  
  226. var onSharePanelShow = function () {
  227. if ((selectedText = window.getSelection().toString())) {
  228. selectedText = '『' + selectedText + '』 ';
  229. }
  230. var top = Math.max(100 - document.body.scrollTop, 10);
  231. var isSticky = top <= 10;
  232. var state = (isSticky?'stick':'inital')+'Open';
  233. applyStyles(baseElm, baseElmStyles[state], {
  234. transition: 'all 300ms 0s ease'
  235. });
  236. applyStyles(panelOpenElm, panelOpenElmStyles[state]);
  237. applyStyles(panelCloseElm, panelCloseElmStyles[state]);
  238. applyStyles(shareElm, shareElmStyles[state]);
  239. overlayElm.style.display = 'block';
  240. };
  241.  
  242. var onSharePanelHide = function () {
  243. var top = Math.max(100 - document.body.scrollTop, 10);
  244. var isSticky = top <= 10;
  245. var state = (isSticky?'stick':'inital');
  246. applyStyles(baseElm, baseElmStyles[state], {
  247. top: isSticky ? baseElmStyles.stick.top : ''+top+'px',
  248. transition: 'all 300ms 0s ease'
  249. });
  250. applyStyles(panelOpenElm, panelOpenElmStyles[state]);
  251. applyStyles(panelCloseElm, panelCloseElmStyles[state]);
  252. applyStyles(shareElm, shareElmStyles[state]);
  253. overlayElm.style.display = 'none';
  254. };
  255.  
  256. baseElm.addEventListener('mousedown', function () {
  257. selectedRange = 0 < window.getSelection().rangeCount ? window.getSelection().getRangeAt(0) : null;
  258. });
  259. baseElm.addEventListener('click', function () {
  260. if (selectedRange) {
  261. window.getSelection().removeAllRanges();
  262. window.getSelection().addRange(selectedRange.cloneRange());
  263. }
  264. ('none' != panelOpenElm.style.display ? onSharePanelShow : onSharePanelHide)();
  265. });
  266.  
  267. overlayElm.addEventListener('click', onSharePanelHide);
  268.  
  269. var title = (document.getElementsByTagName('title')[0]||{}).innerHTML||'';
  270.  
  271. var shareInfo = {
  272. twitter: { popup: true, caption: 'Twitter でつぶやく', url: 'http://twitter.com/share?text={seltext}{title}&amp;url={url}' },
  273. facebook: { popup: true, caption: 'Facebookで共有', url: 'http://www.facebook.com/sharer.php?u={url}&amp;t={title}' },
  274. hatena: { popup: true, caption: 'はてなブックマーク', url: 'http://b.hatena.ne.jp/entry/panel/?url={url}&amp;btitle={title}' },
  275. pocket: { popup: true, caption: 'Pocketに追加', url: 'http://getpocket.com/edit?url={url}&amp;title={title}' },
  276. googleplus: { popup: true, caption: 'Google+で共有', url: 'https://plus.google.com/share?url={url}' },
  277. mail: { popup: false, caption: 'メール送信', url: 'mailto:?subject={title}&amp;body={url}%0D%0A{seltext}' },
  278. };
  279.  
  280. for (var service in shareInfo) {
  281. var shareLink = shareInfo[service].url
  282. .replace('{url}', encodeURIComponent(location.href))
  283. .replace('{seltext}', encodeURIComponent(selectedText || ''))
  284. .replace('{title}', encodeURIComponent(title || ''));
  285. var button = document.createElement('div');
  286. button.style.cssText = [
  287. 'margin-bottom: 5px;',
  288. ].join(" ");
  289. var buttonLink = document.createElement('a');
  290. buttonLink.innerHTML = shareInfo[service].caption;
  291. if (!shareInfo[service].popup) {
  292. buttonLink.href = shareLink;
  293. }
  294. else {
  295. buttonLink.href = 'javascript:void(0);';
  296. buttonLink.onclick = function(shareLink){
  297. window.open(shareLink,
  298. NS+'share-popup',
  299. 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=640,height=480');
  300. }.bind(null, shareLink);
  301. }
  302. buttonLink.style.cssText = [
  303. 'position: relative;',
  304. 'display: inline-block;',
  305. 'box-sizing: border-box;',
  306. 'text-align: center;',
  307. 'background-color: #1a9cbc;',
  308. 'border-radius: 4px;',
  309. 'color: #fff;',
  310. 'line-height: 52px;',
  311. '-webkit-transition: none;',
  312. 'transition: none;',
  313. 'box-shadow: 0 3px 0 #0e738c;',
  314. 'text-shadow: 0 1px 1px rgba(0, 0, 0, .3);',
  315. 'width: 100%;',
  316. 'height: 100%;',
  317. 'line-height: 100%;',
  318. 'padding: 5px;',
  319. 'text-decoration: none;',
  320. ].join(" ");
  321. buttonLink.onmouseover = function () { this.style.top = '0px'; this.style.backgroundColor = '#31aac8'; this.style.boxShadow = '0 3px 0 #2388a1'; };
  322. buttonLink.onmouseout = function () { this.style.top = '0px'; this.style.backgroundColor = '#1a9cbc'; this.style.boxShadow = '0 3px 0 #0e738c'; };
  323. buttonLink.onmousedown = function () { this.style.top = '3px'; this.style.boxShadow = 'none'; };
  324. buttonLink.onmouseup = function () { this.style.top = '0px'; this.style.backgroundColor = '#1a9cbc'; this.style.boxShadow = '0 3px 0 #0e738c'; };
  325. button.appendChild(buttonLink);
  326. shareElm.appendChild(button);
  327. }
  328.  
  329. document.body.appendChild(baseElm);
  330.  
  331. document.addEventListener('scroll', onDocumentScroll);
  332. onSharePanelHide();
  333. onDocumentScroll();
  334.  
  335. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址