WhatsApp Right-Click Dropdown with Blink

Opens the options menu of a message on right click in WhatsApp Web.

目前为 2025-03-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name WhatsApp Right-Click Dropdown with Blink
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @license CC BY-NC-SA 4.0
  6. // @description Opens the options menu of a message on right click in WhatsApp Web.
  7. // @author Dan
  8. // @match *://web.whatsapp.com/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. function attachContextMenuHandler(node) {
  16. if (node.classList && (node.classList.contains('message-out') || node.classList.contains('message-in'))) {
  17. node.addEventListener('contextmenu', function(event) {
  18. event.preventDefault();
  19.  
  20. // Try to find the contextual menu button for the message
  21. let menuButton = node.querySelector('._ahkm'); // Selector for the contextual menu button
  22.  
  23. // If it's not found, try another selector (in case of changes in the structure)
  24. if (!menuButton) {
  25. menuButton = node.querySelector('[role="button"][aria-label="Context menu"]');
  26. }
  27.  
  28. if (menuButton) {
  29. menuButton.click(); // Open the options menu
  30. }
  31.  
  32. // Make the message blink
  33. blinkMessage(node);
  34. });
  35. }
  36. }
  37.  
  38. function blinkMessage(node) {
  39. // Add the class that causes the blinking effect
  40. node.classList.add('blink');
  41.  
  42. // Remove the class after a short period (blinking)
  43. setTimeout(function() {
  44. node.classList.remove('blink');
  45. }, 500); // The message will blink for 500ms
  46. }
  47.  
  48. // CSS style for blinking
  49. const style = document.createElement('style');
  50. style.innerHTML = `
  51. .blink {
  52. animation: blink 0.5s alternate;
  53. }
  54.  
  55. @keyframes blink {
  56. 0% {
  57. opacity: 1;
  58. }
  59. 50% {
  60. opacity: 0;
  61. }
  62. 100% {
  63. opacity: 1;
  64. }
  65. }
  66. `;
  67. document.head.appendChild(style);
  68.  
  69. // Observe the chat container for new messages
  70. const observer = new MutationObserver(mutations => {
  71. mutations.forEach(mutation => {
  72. mutation.addedNodes.forEach(node => {
  73. if (node.nodeType === 1) { // Ensure it's an element
  74. attachContextMenuHandler(node);
  75. node.querySelectorAll('.message-out, .message-in').forEach(attachContextMenuHandler);
  76. }
  77. });
  78. });
  79. });
  80.  
  81. observer.observe(document.body, { childList: true, subtree: true });
  82. })();