您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
This script allows a bulk delete of Last.fm scrobbles
// ==UserScript== // @name Last.fm Bulk Delete Scrobbles // @description This script allows a bulk delete of Last.fm scrobbles // @namespace http://tampermonkey.net/ // @version 1.0 // @author xXMrJackXx // @match https://*.last.fm/user/* // @exclude https://*.last.fm/user/*/loved // @require http://code.jquery.com/jquery-3.3.1.min.js // @grant GM_addStyle // @run-at document-end // ==/UserScript== GM_addStyle(` .batch-button { width: 100px; margin-right: 10px; border-radius: 6px; outline: none; } `); const observer = new MutationObserver(() => $('.chartlist') && process()); // clear localStorage on first load localStorage.clear(); process(); registerPJax(); function init() { var main = $(".col-main"); var div = $("<div id='batchDeleteButtons'>"); main.prepend(div); // add delete button var deleteButton = $('<input type="button" value="Delete" class="batch-button"/>'); deleteButton.click(function() { $('table.chartlist').find('input:checked').each(function() { // find delete button and simulate a click of every checked checkbox var del = this.closest('tr').querySelector('[data-ajax-form-sets-state="deleted"]'); del && del.click(); // remove from localStorage localStorage.removeItem(this.id); // remove checkbox this.remove(); }); }); div.prepend(deleteButton); // add check/uncheck all button var checkButton = $('<input type="button" value="Check all" data-type="check" class="batch-button"/>'); checkButton.click(function() { var cbs = $(main).find('input.batch-checkbox'); if($(this).attr('data-type') == 'check') { $(this).attr('data-type', 'uncheck'); $(this).val('Uncheck all'); cbs.prop('checked', true); // add every checkbox id to the localStorage cbs.each(function() { localStorage.setItem(this.id, this.id); }); } else { $(this).attr('data-type', 'check'); $(this).val('Check all'); cbs.prop('checked', false); // remove every checkbox id from the localStorage cbs.each(function() { localStorage.removeItem(this.id); }); } }); div.prepend(checkButton); } function process() { observer.disconnect(); // add checkboxes for every not already deleted entries $('tr[data-ajax-form-state!="deleted"] .chartlist-play').each(function() { var track = $(this).siblings('.chartlist-name').find('a.link-block-target').attr('title'); var timestamp = $(this).siblings('.chartlist-timestamp').find('span[title]').attr('title'); if (track != undefined && timestamp != undefined) { // combination of timestamp and track title should be unique var id = normalizeString(timestamp + track); var cb = $('<input type="checkbox" class="batch-checkbox" id="' + id + '"/>'); cb.click(function() { if (this.checked) { // add checkbox id to localStorage localStorage.setItem(id, id); } else { // remove checkbox id from localStorage localStorage.removeItem(id); } }); // add checkbox as new first column $('<td style="width: 50px;"/>').append(cb).insertBefore($(this)); } }); // reload localStorage items var keys = Object.keys(localStorage), i = keys.length; while (i--) { // check every checkbox that is contained in the localStorage var id = keys[i]; var cb = $('#' + id); if (cb.length) { cb.prop('checked', true); } } if ($('.chartlist tbody').length) { observer.takeRecords(); observer.observe($('.chartlist tbody')[0], {childList: true}); // add buttons only if not already present if ($('#batchDeleteButtons').length == 0) { init(); } } } function registerPJax() { document.addEventListener('pjax:end:batch-delete', process); window.addEventListener('load', function onLoad() { window.removeEventListener('load', onLoad); unsafeWindow.jQuery(unsafeWindow.document).on('pjax:end', exportFunction(() => document.dispatchEvent(new CustomEvent('pjax:end:batch-delete')), unsafeWindow)); }); } function normalizeString(str) { return str.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '-') }