您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
1-click "add user to [xyz] list" button next to usernames while scrolling your x (twitter) feed (be sure to edit the variable "lists")
当前为
// ==UserScript== // @name x-twitter-add-to-list-button // @name:ja x-twitter-add-to-list-button // @namespace x-twitter // @version 0.2.1 // @description 1-click "add user to [xyz] list" button next to usernames while scrolling your x (twitter) feed (be sure to edit the variable "lists") // @description:ja リストにワンクリックで追加するボタンを表示します(変数"lists"を必ず編集してください) // @author fuwawascoco // @match https://twitter.com/* // @match https://mobile.twitter.com/* // @match https://x.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=twitter.com // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; const lists = ['waitlist', 'illustrators', 'animators']; // be sure to change to the NAME of your lists (not IDs) const checkInterval = 512; // ms const tryInterval = 64; // ms function retryUntilSuccess(newTab, selector, innerText, callback) { const intervalID = setInterval(() => { const element = newTab.document.querySelector(selector); if (innerText != ''){ const elements = newTab.document.querySelectorAll(selector); element = Array.from(elements).find(el => el.textContent.trim() === innerText); } if (element && element.offsetParent != null) { // Check if element is visible clearInterval(intervalID); callback(element); } }, tryInterval); } function onClick(userProfile, list) { const newTab = open(userProfile); newTab.addEventListener('beforeunload', () => clearInterval(intervalID)); retryUntilSuccess(newTab, 'button[aria-label="More"][data-testid="userActions"]', '', moreButton => { moreButton.click(); retryUntilSuccess(newTab, 'a[href="/i/lists/add_member"][role="menuitem"]', '', listButton => { listButton.click(); retryUntilSuccess(newTab, '[aria-modal="true"]', '', modal => { const listSpan = Array.from(modal.getElementsByTagName('span')).find(span => span.textContent === list); if (!listSpan) { newTab.alert(`"${list}" was not found, please edit the script to update the variable "lists" with your own names.`); newTab.close(); return; } const checkbox = listSpan.closest('[role="checkbox"]'); if (checkbox && checkbox.getAttribute('aria-checked') === 'false') { checkbox.click(); } }); }); }); } function createButton(userProfile, list) { const button = document.createElement('button'); button.style.fontSize = '90%'; button.style.margin = '0 0.25em'; button.textContent = list; button.addEventListener('click', () => onClick(userProfile, list)); return button; } function createButtonContainer(userProfile) { const container = document.createElement('div'); container.style.position = 'relative'; container.style.left = '2%'; container.style.opacity = 0.5; lists.forEach(list => container.appendChild(createButton(userProfile, list))); container.classList.add('listButtons'); return container; } function addButtons() { const nodes = document.querySelectorAll('[data-testid="User-Name"]:not(:has(.listButtons))'); nodes.forEach(node => { const userProfile = node.querySelector('a')?.href || ''; if (userProfile) { node.appendChild(createButtonContainer(userProfile)); } }); } setInterval(addButtons, checkInterval); })();