YouTube - Button Container (@require)

Creates a button container, under the video, onto which buttons can be added

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/9004/44606/YouTube%20-%20Button%20Container%20%28%40require%29.js

  1. // ==UserScript==
  2. // @name YouTube - Button Container (@require)
  3. // @namespace https://gf.qytechs.cn/en/users/10166-moriarty
  4. // @description Creates a button container, under the video, onto which buttons can be added
  5. // @include http://*.youtube.com/*
  6. // @include http://youtube.com/*
  7. // @include https://*.youtube.com/*
  8. // @include https://youtube.com/*
  9. // @copyright CodeFelony
  10. // @author Moriarty
  11. // @version 1.0.0
  12. // @license LGPL version 3 or any later version; http://www.gnu.org/copyleft/lgpl.html
  13. // @grant GM_addStyle
  14. // ==/UserScript==
  15.  
  16. var addButtonToContainer = (function () {
  17. 'use strict';
  18.  
  19. var rYoutubeWhitelistedUrls = /^https?:\/\/([^\.]+\.)?youtube\.com\/(watch|user\/|channel\/)/;
  20.  
  21. var TEST_MODE = false; // if true, will replace the current style with this one
  22.  
  23. // helper functions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  24. function addStyle(contents) {
  25. var head = document.head || query('html > head'),
  26. style = document.createElement('style');
  27.  
  28. style.id = 'underMovieDivStyle';
  29. style.type = 'text/css';
  30. style.appendChild( document.createTextNode(contents) );
  31.  
  32. if (head) {
  33. head.appendChild(style);
  34. }
  35. }
  36. function id(name) {
  37. return document.getElementById(name);
  38. }
  39. function query(name) {
  40. return document.querySelector(name);
  41. }
  42. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  43.  
  44. function waitForHeadReady() {
  45. if ( document.head || query('html > head') ) {
  46. window.setTimeout(handleStyleCreation, TEST_MODE === true ? 3000 : 0);
  47. } else {
  48. window.setTimeout(waitForHeadReady, 200);
  49. }
  50. }
  51.  
  52. function handleStyleCreation() {
  53. var umdv = id('underMovieDivStyle'),
  54. obs = new MutationObserver(function (mutations) {
  55. mutations.forEach(function (mutation) {
  56. if (mutation.target.id === 'underMovieDivStyle') {
  57. handleStyleCreation();
  58. }
  59. });
  60. });
  61.  
  62. if (TEST_MODE === true || !umdv) {
  63. if (umdv) {
  64. umdv.parentNode.removeChild(umdv);
  65. }
  66.  
  67. addStyle('' +
  68. '#under-movie-div { ' +
  69. 'background: transparent !important; ' +
  70. 'display: block; ' +
  71. 'padding-top: 4px; ' +
  72. 'padding-bottom: 8px; ' +
  73. 'text-align: left; ' +
  74. 'z-index: 999999; ' +
  75. '}\n\n' +
  76. '.under-movie-div-button { ' +
  77. 'background-image: linear-gradient(to top, #F6F6F6 0px, #FCFCFC 100%) !important; ' +
  78. 'border: 1px solid #CCCCCC; ' +
  79. 'border-radius: 2px; ' +
  80. 'color: #666666 !important; ' +
  81. 'font-size: 12px !important; ' +
  82. 'font-family: arial, sans-serif !important; ' +
  83. 'font-weight: 400 !important; ' +
  84. 'height: auto !important; ' +
  85. 'line-height: 20px !important; ' +
  86. 'margin-right: 6px; ' +
  87. 'padding: 2px 10px !important; ' +
  88. '}\n\n' +
  89. // - - - - - - - - - - - - - - - - - - -
  90. '#watch7-headline { ' +
  91. 'padding: 4px 0 !important; ' +
  92. '}\n\n' +
  93. '#watch7-headline h1 { ' +
  94. 'text-align: center; ' +
  95. 'width: 100%; ' +
  96. '}\n\n' +
  97. '#upsell-video { ' +
  98. 'overflow: visible !important; ' + // allow the button container to show on non-video pages
  99. '}' +
  100. '');
  101.  
  102. // observe the style for changes if test mode enabled
  103. if (TEST_MODE === true) {
  104. obs.observe(id('underMovieDivStyle'), {
  105. childList : true,
  106. attributes : true,
  107. characterData : true
  108. });
  109. }
  110. }
  111. }
  112.  
  113. function handleContainerCreation() {
  114. var holder = query('#watch7-headline, #gh-overviewtab div.c4-spotlight-module-component'),
  115. container = id('under-movie-div');
  116.  
  117. if (container == null) {
  118. container = document.createElement('div');
  119. container.id = 'under-movie-div';
  120.  
  121. if (holder) {
  122. holder.appendChild(container);
  123. }
  124. }
  125.  
  126. return container;
  127. }
  128.  
  129. function add(text, onclick, ID) {
  130. var upsellVideo = id('upsell-video'),
  131. container = handleContainerCreation(),
  132. button = document.createElement('button'),
  133. span = document.createElement('span');
  134. ID = ID || text.replace(/[^a-zA-Z0-9-_]/, '');
  135.  
  136. if ( !location.href.match(rYoutubeWhitelistedUrls) || id(ID) ) { return; }
  137. if (typeof text !== 'string' || typeof onclick !== 'function') { return; }
  138.  
  139. span.setAttribute('class', 'yt-uix-button-content');
  140. span.appendChild( document.createTextNode(text) );
  141.  
  142. button.id = ID;
  143. button.addEventListener('click', function () {
  144. window.setTimeout(onclick, 0);
  145. }, false);
  146.  
  147. button.type = 'button';
  148. button.setAttribute('class', 'under-movie-div-button yt-uix-button yt-uix-button-text yt-uix-tooltip');
  149. button.appendChild(span);
  150.  
  151. return container.appendChild(button);
  152. }
  153.  
  154. waitForHeadReady();
  155.  
  156. return add;
  157. }());
  158.  
  159. /* EXAMPLE BUTTON
  160. addButtonToContainer('A Test Button', function () { alert('Test.'); }, 'test-button');
  161. */

QingJ © 2025

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