您需要先安装一个扩展,例如 篡改猴、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.1.0
- // @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==
- // original script from https://greasyfork.org/en/scripts/485053-twitter-add-to-list-button
- (function() {
- 'use strict';
- const lists = ['test','illustrators','animators']; // be sure to change to the NAME of your lists (not IDs)
- // too many lists or too long names will look ugly so you can either
- // 1) shorten list names
- // 2) limit to few lists
- // 3) fix css below
- const checkInterval = 512; // ms
- const tryInterval = 64; // ms
- function onClick(userProfile, list) {
- const newTab = open(userProfile);
- const intervalID = setInterval(()=>{
- const moreButton = newTab.document.querySelector('div[aria-label="More"]');
- if (moreButton === null) return;
- clearInterval(intervalID);
- moreButton.click();
- const listButton = newTab.document.querySelector('[href="/i/lists/add_member"]');
- listButton.click();
- const listIntervalID = setInterval(()=>{
- const modal = newTab.document.querySelector('[aria-modal="true"]');
- if (modal === null) return;
- const spans = modal.getElementsByTagName('span');
- let theListNameSpan = null;
- for (let i = 0; i < spans.length; ++i) {
- if (spans[i].textContent !== list) continue;
- theListNameSpan = spans[i];
- break;
- }
- if (theListNameSpan === null) {
- const checkbox = modal.querySelector('[aria-checked]');
- if (checkbox === null) return;
- newTab.alert(`"${list}" was not found`);
- newTab.close();
- clearInterval(listIntervalID);
- return;
- }
- clearInterval(listIntervalID);
- let checkbox = theListNameSpan;
- while (!checkbox.hasAttribute('aria-checked')) {
- checkbox = checkbox.parentElement;
- }
- if (checkbox.ariaChecked === 'false') {
- checkbox.click();
- const saveButton = spans[2];
- saveButton.click();
- }
- newTab.close();
- }, tryInterval);
- }, tryInterval);
- }
- function ListButton(userProfile, list) {
- const button = document.createElement('button');
- const styles = {
- fontSize: '90%',
- margin: '0 0.25em',
- };
- for (const prop in styles) {
- button.style[prop] = styles[prop];
- }
- button.textContent = list;
- button.addEventListener('click', onClick.bind(null, userProfile, list));
- return button;
- }
- function ListButtons(userProfile) {
- const buttons = document.createElement('div');
- const styles = {
- position: 'relative',
- left: '2%',
- opacity: 0.5,
- };
- for (const prop in styles) {
- buttons.style[prop] = styles[prop];
- }
- lists.forEach(list => {
- buttons.appendChild(ListButton(userProfile, list));
- });
- buttons.classList.add('listButtons');
- return buttons;
- }
- function addButtons() {
- const selector = '[data-testid="User-Name"]:not(:has(.listButtons))';
- const nodes = document.querySelectorAll(selector);
- nodes.forEach(node => {
- let userProfile = '';
- function rec(children) {
- for (const child of children) {
- if (child.nodeName === 'A') {
- userProfile = child.href;
- return;
- }
- rec(child.childNodes);
- if (userProfile !== '') return;
- }
- }
- rec(node.childNodes);
- node.appendChild(ListButtons(userProfile));
- });
- }
- setInterval(addButtons, checkInterval)
- })();