override-missav-js

override missav js

  1. // ==UserScript==
  2. // @name override-missav-js
  3. // @namespace https://missav.com
  4. // @version v0.0.16
  5. // @description override missav js
  6. // @author You
  7. // @match https://missav.com/*
  8. // @exclude /^https:\/\/missav\.com\/.*-\d+.*$/
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. // 节流
  13. function throttle(func, wait) {
  14. let timeout;
  15. return function () {
  16. let context = this;
  17. let args = arguments;
  18. if (!timeout) {
  19. timeout = setTimeout(() => {
  20. timeout = null;
  21. func.apply(context, args);
  22. }, wait);
  23. }
  24. };
  25. }
  26.  
  27. // 防抖
  28. function debounce(func, wait, immediate) {
  29. let timeout;
  30. return function () {
  31. let context = this;
  32. let args = arguments;
  33. let later = function () {
  34. timeout = null;
  35. if (!immediate) {
  36. func.apply(context, args);
  37. }
  38. };
  39. let callNow = immediate && !timeout;
  40. clearTimeout(timeout);
  41. timeout = setTimeout(later, wait);
  42. if (callNow) {
  43. func.apply(context, args);
  44. }
  45. };
  46. }
  47.  
  48. const onMouseEnter = () => {
  49. // 获取页面中所有拥有 .thumbnail 类的元素
  50. const thumbnails = document.querySelectorAll(".thumbnail");
  51.  
  52. // 遍历所有的 .thumbnail 元素
  53. thumbnails.forEach(function (thumbnail) {
  54. // 在每个 .thumbnail 元素下找到符合条件的 a 元素
  55. const link = thumbnail.querySelector("div:first-child > a:last-child");
  56.  
  57. if (link == null) {
  58. return;
  59. }
  60.  
  61. // 检查 link 是否已经有监听器或者已经被触发过点击
  62. if (!link.hasAttribute("data-click-triggered")) {
  63. // 创建一个监听函数,它可以被解除绑定
  64. function hoverTriggerClick(event) {
  65. // 触发点击事件
  66. link.click();
  67. // 在触发点击后解除 mouseenter 事件监听
  68. link.removeEventListener("mouseenter", hoverTriggerClick);
  69. }
  70.  
  71. // 标记 link 已添加事件监听器
  72. link.setAttribute("data-click-triggered", "true");
  73. // 为该 a 元素添加鼠标悬停的事件监听器
  74. link.addEventListener("mouseenter", hoverTriggerClick);
  75. }
  76. });
  77. };
  78.  
  79. const onVideo = () => {
  80. // 获取页面中所有拥有 .thumbnail 类的元素
  81. const thumbnails = document.querySelectorAll(
  82. ".thumbnail > div:first-child > a:first-child"
  83. );
  84.  
  85. // 遍历所有的 .thumbnail 元素
  86. thumbnails.forEach(function (thumbnail) {
  87. // 在每个 .thumbnail 元素下找到符合条件的 a 元素
  88. const video = thumbnail.querySelector(
  89. "div:first-child > a:first-child > video"
  90. );
  91.  
  92. if (video == null){
  93. return;
  94. }
  95.  
  96. if (video.getAttribute("play") === "true" && video.src.indexOf("https") != -1) {
  97. // video.play();
  98. // video.className = "preview";
  99. return;
  100. }
  101.  
  102. // const id = video.id.replace("preview-", "");
  103. // console.log(id, video.dataset.src);
  104. // video.src = video.dataset.src.replace("undefined", id);
  105.  
  106. // console.log(video.id, video.dataset.src);
  107.  
  108. if (video.dataset.src.indexOf("undefined") > -1) {
  109. return;
  110. }
  111.  
  112. video.setAttribute("costom-src", "true");
  113. video.setAttribute("play", "true");
  114. video.src = video.dataset.src;
  115. // video.play();
  116. // video.className = "preview";
  117. });
  118. };
  119.  
  120. const playVideo = () => {
  121. onVideo();
  122. const videos = document.querySelectorAll("video[costom-src=true]");
  123. videos.forEach((video) => {
  124. video.play();
  125. video.className = "preview";
  126. });
  127. }
  128.  
  129. const addSettingIcon = () => {
  130. const div = document.createElement("div");
  131. div.style.position = "fixed";
  132. div.style.right = "20px";
  133. div.style.bottom = "20px";
  134. div.style.padding="10px";
  135. div.style.zIndex = "50";
  136. div.style.width = "30px";
  137. div.style.height = "30px";
  138. div.style.color = "white";
  139. div.style.backgroundColor = "black";
  140. div.style.borderRadius = "50%";
  141. div.style.opacity = "1";
  142. div.style.cursor = "pointer";
  143. div.style.display = "flex";
  144. div.style.justifyContent = "center";
  145. div.style.alignItems = "center";
  146. div.style.userSelect = "none";
  147. div.innerText = "⚙️";
  148.  
  149. div.addEventListener("mouseenter", function () {
  150. div.style.opacity = "1";
  151. });
  152. div.addEventListener("mouseleave", function () {
  153. div.style.opacity = "0.5";
  154. });
  155.  
  156. div.addEventListener("click", function () {
  157. playVideo();
  158. });
  159.  
  160. document.body.appendChild(div);
  161. }
  162.  
  163. const addTriggerAutoPlay = () => {
  164. const div = document.createElement("div");
  165. div.style.position = "fixed";
  166. div.style.left = "20px";
  167. div.style.bottom = "20px";
  168. div.style.padding="10px";
  169. div.style.zIndex = "50";
  170. div.style.width = "30px";
  171. div.style.height = "30px";
  172. div.style.color = "white";
  173. div.style.backgroundColor = "black";
  174. div.style.borderRadius = "50%";
  175. div.style.opacity = "1";
  176. div.style.cursor = "pointer";
  177. div.style.display = "flex";
  178. div.style.justifyContent = "center";
  179. div.style.alignItems = "center";
  180. div.style.userSelect = "none";
  181. div.innerText = "🚫";
  182.  
  183. if (localStorage.getItem("autoPlay") === "1") {
  184. div.innerText = "♨️";
  185. }
  186.  
  187. div.addEventListener("mouseenter", function () {
  188. div.style.opacity = "1";
  189. });
  190. div.addEventListener("mouseleave", function () {
  191. div.style.opacity = "0.5";
  192. });
  193.  
  194. div.addEventListener("click", function () {
  195. const autoPlay = localStorage.getItem("autoPlay");
  196. if (autoPlay === "1") {
  197. div.innerText = "🚫";
  198. localStorage.setItem("autoPlay", "0");
  199. return;
  200. }
  201. div.innerText = "♨️";
  202. localStorage.setItem("autoPlay", "1");
  203. });
  204.  
  205. document.body.appendChild(div);
  206. }
  207.  
  208. (function () {
  209. "use strict";
  210.  
  211. addSettingIcon();
  212. addTriggerAutoPlay();
  213.  
  214. document.addEventListener("keydown", function (event) {
  215. playVideo();
  216. });
  217.  
  218. const timer = setInterval(() => {
  219. if (window.player != null) {
  220. return;
  221. }
  222.  
  223. const autoPlay = localStorage.getItem("autoPlay");
  224. if (autoPlay === "1") {
  225. setTimeout(() => {
  226. playVideo();
  227. }, 2000);
  228.  
  229. const observer = new MutationObserver(function (mutations) {
  230. mutations.forEach(function (mutation) {
  231. if (mutation.addedNodes.length > 0) {
  232. // onMouseEnter();
  233. debounce(playVideo, 1000)();
  234. }
  235. });
  236. });
  237.  
  238. observer.observe(document.body, {
  239. attributes: false,
  240. childList: true,
  241. subtree: true,
  242. });
  243. }
  244.  
  245. clearInterval(timer);
  246.  
  247. }, 1000)
  248.  
  249. })();