您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
adds "add to list" buttons (be sure to edit the variable "lists")
当前为
// ==UserScript== // @name twitter-add-to-list-button // @name:ja twitter-add-to-list-button // @namespace NegUtl // @version 0.1.0 // @description adds "add to list" buttons (be sure to edit the variable "lists") // @description:ja リストにワンクリックで追加するボタンを表示します(変数"lists"を必ず編集してください) // @author You // @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'; // Your code here... const lists = ['list1','list2','list3']; // be sure to change to the name of your lists (not IDs) const checkInterval = 512; // ms const tryInterval = 64; // ms function onClick(userProfile, list) { const newTab = open(userProfile); const intervalID = setInterval(()=>{ const menuButton = newTab.document.querySelector('[data-testid="userActions"]'); if (menuButton === null) return; clearInterval(intervalID); menuButton.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: 'absolute', left: '50%', transform: 'translateX(-50%)', }; 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="UserCell"]: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) })();