Image & Video Hover Preview

Preview images and videos on hover with delay.

  1. // ==UserScript==
  2. // @name Image & Video Hover Preview
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description Preview images and videos on hover with delay.
  6. // @author You
  7. // @match *://*/*
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM_addStyle
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15. console.log('test 222');
  16.  
  17. const style = document.createElement("style");
  18. style.innerHTML = `
  19. #hover-preview {
  20. position: fixed;
  21. top: 0px;
  22. right: 0px;
  23. width: 600px;
  24. max-height: 100vh;
  25. overflow-y: auto;
  26. background: rgba(0, 0, 0, 0.8);
  27. padding: 10px;
  28. border-radius: 5px;
  29. z-index: 9999;
  30. display: none;
  31. }
  32. #hover-preview img, #hover-preview video {
  33. max-width: 100%;
  34. display: block;
  35. margin-bottom: 10px;
  36. }
  37. `;
  38. document.head.appendChild(style);
  39.  
  40. const previewBox = document.createElement("div");
  41. previewBox.id = "hover-preview";
  42. document.body.appendChild(previewBox);
  43.  
  44. let hoverTimeout;
  45.  
  46. async function fetchPageContent(url) {
  47. try {
  48. const response = await fetch(url);
  49. if (!response.ok) throw new Error("Network response was not ok");
  50. return await response.text();
  51. } catch (error) {
  52. console.error("Fetch error:", error);
  53. return "";
  54. }
  55. }
  56. const links = document.querySelectorAll('a.image-hover');
  57. console.log('links', links);
  58. links.forEach(link => {
  59. link.addEventListener("mouseenter", (event) => {
  60. console.log('link', link);
  61. if (!link) return;
  62.  
  63. hoverTimeout = setTimeout(async () => {
  64. const url = link.href;
  65. previewBox.innerHTML = "Loading...";
  66. previewBox.style.display = "block";
  67.  
  68. const pageContent = await fetchPageContent(url);
  69. if (!pageContent) {
  70. previewBox.innerHTML = "Failed to load content";
  71. return;
  72. }
  73.  
  74. previewBox.innerHTML = "";
  75. const tempDiv = document.createElement("div");
  76. tempDiv.innerHTML = pageContent;
  77.  
  78. // Extract videos
  79. tempDiv.querySelectorAll(".item-link:not(.fancybox-trigger)").forEach((videoSrc, index) => {
  80. console.log('video', videoSrc);
  81. const video = document.createElement("video");
  82. if (videoSrc.href.includes('javascript')) {
  83. video.src = videoSrc.getAttribute('data-trigger-href');
  84. } else {
  85. video.src = videoSrc.href;
  86. }
  87.  
  88. video.controls = true;
  89. video.autoPlay = true;
  90. video.style.width = '100%';
  91. previewBox.appendChild(video);
  92. if (index ===0) {
  93. video.play();
  94. } else {
  95. video.addEventListener('mouseenter', () => {
  96. video.play();
  97. })
  98. }
  99. });
  100.  
  101. // Extract images
  102. tempDiv.querySelectorAll("a.image-hover").forEach(imgLink => {
  103. console.log('jg-entry', imgLink);
  104. const imgSrc = imgLink.href;
  105. if (imgSrc.match(/(jpg|jpeg|png|gif|webp)$/)) {
  106. const img = document.createElement("img");
  107. img.src = imgSrc;
  108. previewBox.appendChild(img);
  109. }
  110. });
  111. }, 300); // 300ms delay before loading content
  112. });
  113.  
  114. link.addEventListener("mouseout", (event) => {
  115. if (!link) return;
  116. clearTimeout(hoverTimeout);
  117. //previewBox.style.display = "none";
  118. });
  119. });
  120.  
  121.  
  122. // call number
  123. setTimeout(() => {
  124. const isProfilePage = document.querySelectorAll('#profile-content').length > 0;
  125. console.log('is profile page', isProfilePage);
  126. if (!isProfilePage) {
  127. return;
  128. }
  129. const button = document.querySelector('button[data-target="#modal-ajax"]');
  130. console.log('call button', button);
  131.  
  132. button.addEventListener('click', function() {
  133. console.log('Button clicked!');
  134. });
  135. }, 2000);
  136.  
  137. })();