TikTok Expand All Comments

Don't want to spam that "View More" button? Expand all comments with one click!

  1. // ==UserScript==
  2. // @name TikTok Expand All Comments
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description Don't want to spam that "View More" button? Expand all comments with one click!
  6. // @author LL-Studio
  7. // @match *://*.tiktok.com/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=tiktok.com
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. const INTERVAL_TIME = 500;
  17. const MAX_TIME = 1e4;
  18.  
  19. // Styles
  20. // CSS styling for the "Expand All" button
  21. var style = document.createElement('style');
  22. style.innerHTML = `
  23. .expand-button {
  24. color: rgba(22, 24, 35, 0.5);
  25. font-family: TikTokFont, Arial, Tahoma, PingFangSC, sans-serif;
  26. font-weight: 600;
  27. font-size: 14px;
  28. line-height: 18px;
  29. cursor: pointer;
  30. }
  31. .expand-button:hover {
  32. text-decoration: underline;
  33. }
  34. `;
  35. document.head.appendChild(style);
  36.  
  37. // Elements
  38. // Add custom elements to the webpage
  39. const waitForElement = (parent, selector) => {
  40. return new Promise((resolve, reject) => {
  41. const results = parent.querySelector(selector);
  42. if (results) return resolve(results);
  43. const observer = new MutationObserver((mutationsList, observer) => {
  44. const element = parent.querySelector(selector);
  45. if (element) {
  46. observer.disconnect();
  47. resolve(element);
  48. }
  49. });
  50. observer.observe(parent, { childList: true, subtree: true });
  51. });
  52. };
  53.  
  54. const hydrateActionContainer = (container) => {
  55. // Create button
  56. var expandButton = document.createElement("p");
  57. expandButton.setAttribute("role", "button");
  58. expandButton.style.color = "rgba(22, 24, 35, 0.5)";
  59. expandButton.style.fontFamily = "TikTokFont, Arial, Tahoma, PingFangSC, sans-serif";
  60. expandButton.style.fontWeight = "600";
  61. expandButton.style.fontSize = "14px";
  62. expandButton.style.lineHeight = "18px";
  63. expandButton.style.cursor = "pointer";
  64.  
  65. expandButton.innerText = "Expand All";
  66. expandButton.onclick = () => {
  67. expandButton.innerText = "Expanding...";
  68. expandButton.style.pointerEvents = "none";
  69.  
  70. let time = 0;
  71. const id = setInterval(() => {
  72. const paragraphs = Array.from(container.querySelectorAll('p'));
  73. const viewMoreButton = paragraphs.find(p => /^View/.test(p.textContent));
  74. if (viewMoreButton) {
  75. time = 0;
  76. viewMoreButton.click();
  77. } else if (time <= MAX_TIME) {
  78. time += INTERVAL_TIME;
  79. } else {
  80. clearInterval(id);
  81. expandButton.innerText = "Expand All";
  82. expandButton.style.pointerEvents = "auto";
  83. }
  84. }, INTERVAL_TIME);
  85. };
  86.  
  87. // Update element when container changes
  88. const updateElement = () => {
  89. if (expandButton.parentNode) expandButton.parentNode.removeChild(expandButton);
  90. if (container.childNodes.length > 1) container.insertBefore(expandButton, container.childNodes[1]);
  91. };
  92.  
  93. var observer = new MutationObserver(() => {
  94. observer.disconnect();
  95. updateElement();
  96. observer.observe(container, { childList: true });
  97. });
  98. updateElement();
  99. observer.observe(container, { childList: true });
  100. }
  101.  
  102. waitForElement(document.body, 'div[data-e2e="search-comment-container"]').then((element) => {
  103. // Observe and add button to all action containers
  104. const actionContainers = new Set();
  105. const onContainer = (container) => {
  106. if (actionContainers.has(container)) return;
  107. hydrateActionContainer(container);
  108. actionContainers.add(container);
  109. };
  110. const observer = new MutationObserver((mutationsList) => {
  111. for (const mutation of mutationsList) {
  112. if (mutation.addedNodes.length) {
  113. const container = document.querySelectorAll("div.css-1for4nf-DivReplyActionContainer");
  114. container.forEach((container) => onContainer(container));
  115. }
  116. }
  117. });
  118. element.querySelectorAll("div.css-1for4nf-DivReplyActionContainer").forEach((container) => onContainer(container));
  119. observer.observe(element, { childList: true, subtree: true });
  120. });
  121. })();

QingJ © 2025

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