您需要先安装一个扩展,例如 篡改猴、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);
- })();