YouTube Float Player

Place the YouTube video in a small window at the bottom right corner when scrolling.

  1. // ==UserScript==
  2. // @name YouTube Float Player
  3. // @namespace YouTube Float Player
  4. // @version 1.0.0
  5. // @description Place the YouTube video in a small window at the bottom right corner when scrolling.
  6. // @author DumbGPT
  7. // @match *://www.youtube.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. var doc = document;
  15. var win = window;
  16. var floatheight = 0;
  17.  
  18. function docsearch(query) {
  19. return doc.evaluate(query, doc, null, 7, null);
  20. }
  21.  
  22. function insertStyle(str, id) {
  23. var styleNode = null;
  24. if (id != null) {
  25. styleNode = doc.getElementById(id);
  26. }
  27. if (styleNode == null) {
  28. styleNode = document.createElement("style");
  29. styleNode.id = id;
  30. styleNode.setAttribute("type", "text/css");
  31. doc.head.appendChild(styleNode);
  32. }
  33. if (styleNode.textContent != str)
  34. styleNode.textContent = str;
  35. }
  36.  
  37. function reset_float() {
  38. var page = docsearch("//ytd-page-manager/ytd-watch-flexy").snapshotItem(0);
  39. if (!page) return;
  40.  
  41. if (page.getAttribute("float") != null) setTimeout(function () { win.dispatchEvent(new Event('resize')) }, 100);
  42. page.removeAttribute("float");
  43. page.parentNode.parentNode.removeAttribute("float");
  44. insertStyle("", "ytpc_style_float");
  45. floatheight = 0;
  46. }
  47.  
  48. function float() {
  49. if (win.location.href.indexOf("watch?") == -1) {
  50. reset_float();
  51. return;
  52. }
  53.  
  54. var page = docsearch("//ytd-page-manager/ytd-watch-flexy").snapshotItem(0);
  55. if (!page) return;
  56.  
  57. var intheater = page.getAttribute("theater") != null;
  58. var fullscreen = page.getAttribute("fullscreen") != null;
  59.  
  60. if (fullscreen) {
  61. reset_float();
  62. return;
  63. }
  64.  
  65. var vid = intheater ? docsearch("//*[@id='full-bleed-container']").snapshotItem(0)
  66. : docsearch("//*[@id='primary-inner']/*[@id='player']").snapshotItem(0);
  67. if (!vid) return;
  68.  
  69. var val = vid.getBoundingClientRect();
  70. var vheight = val.bottom - val.top;
  71.  
  72. var W = doc.body.clientWidth || doc.documentElement.clientWidth;
  73. var H = doc.body.clientHeight || doc.documentElement.clientHeight;
  74. var height = 240;
  75. var width = 427;
  76.  
  77. var infloat = page.getAttribute("float") != null;
  78.  
  79. if (!infloat) {
  80. floatheight = vheight;
  81. }
  82.  
  83. var thres = -1;
  84. if (floatheight > 0) thres = floatheight - 220;
  85.  
  86. var scrollY = win.pageYOffset;
  87.  
  88. if (scrollY >= thres && thres > 0) {
  89. page.setAttribute("float", "");
  90. page.parentNode.parentNode.setAttribute("float", "");
  91.  
  92. var hoff = W - width;
  93. var voff = H - height;
  94. var rtl = (doc.body.getAttribute('dir') == 'rtl');
  95. var lroff = rtl ? "right:0px !important;" : "left:" + hoff + "px !important;";
  96.  
  97. insertStyle("\
  98. ytd-watch-flexy[float] #player-container {position: fixed !important; top: " + voff + "px !important; " + lroff + " width: " + width + "px !important; height: " + height + "px !important; z-index:1000 !important;}\
  99. ytd-watch-flexy[float] .html5-main-video {width: " + width + "px !important; height: " + height + "px !important;}\
  100. ", "ytpc_style_float");
  101. }
  102. else {
  103. reset_float();
  104. }
  105. }
  106.  
  107. win.addEventListener("focus", float, false);
  108. win.addEventListener("blur", float, false);
  109. win.addEventListener("resize", float, false);
  110. win.addEventListener("scroll", float, false);
  111.  
  112. setInterval(float, 1000);
  113. float();
  114. })();

QingJ © 2025

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