您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
打造行動裝置看91譜的最好體驗。
当前为
// ==UserScript== // @name 91 Plus M // @namespace https://github.com/DonkeyBear // @version 0.96.2 // @description 打造行動裝置看91譜的最好體驗。 // @author DonkeyBear // @match https://www.91pu.com.tw/m/* // @match https://www.91pu.com.tw/song/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none // ==/UserScript== let currentUrl = window.location.href; if (currentUrl.match(/\/song\//)) { let sheetId = currentUrl.match(/\/\d*\./)[0].slice(1, -1); let newUrl = `https://www.91pu.com.tw/m/tone.shtml?id=${sheetId}`; window.location.replace(newUrl); } document.querySelector("html").style.backgroundColor = "#f7f7f7"; let observerCheckList = { modifyTitle: false, modifyHeaderBackground: false, modifyHeaderFlex: false, modifyFunctionBarMargin: false, modifyTransposeButton: false } const observer = new MutationObserver(() => { /* 隱藏網頁元素 */ let elementShouldBlock = { // 需要倒數才能關閉的蓋版廣告 modalAd: document.querySelector("#viptoneWindow.window"), // 在頁面最底部的廣告 bottomAd: document.querySelector("#bottomad"), // 最上方提醒升級VIP的廣告 updateVipBar: document.querySelector(".update_vip_bar"), // 譜上的LOGO和浮水印 overlayLogo: document.querySelector(".wmask"), // 彈出式頁尾 footer: document.querySelector("footer"), // 自動滾動頁面捲軸 autoScroll: document.querySelector(".autoscroll"), // 頁首的返回列 headerBackplace: document.querySelector(".backplace"), // 頁首的Key選項 keys: document.querySelector(".set .keys"), // 其餘的Google廣告 adsByGoogle: document.querySelectorAll(".adsbygoogle") } for (let selected in elementShouldBlock) { // 將上述元素隱藏 if (elementShouldBlock[selected]) { if (elementShouldBlock[selected].length === undefined) { // Node elementShouldBlock[selected].style.display = "none"; } else { // NodeList for (let elem of elementShouldBlock[selected]) { elem.style.display = "none"; } } } } if (document.querySelectorAll(".setint .hr")) { // 隱藏頁首部分功能鈕 for (let i = 3; i < 6; i++) { if (document.querySelectorAll(".setint .hr")[i]) { document.querySelectorAll(".setint .hr")[i].style.display = "none"; } } } /* 更改網頁標題 */ if (!observerCheckList.modifyTitle) { if (document.querySelector("#mtitle")) { document.title = `${document.querySelector("#mtitle").innerText} | 91+ M`; observerCheckList.modify = true; } } /* 更改頁首背景樣式 */ if (!observerCheckList.modifyHeaderBackground) { if (document.querySelector("header")) { document.querySelector("header").style.backdropFilter = "blur(5px) saturate(80%)"; document.querySelector("header").style['-webkit-backdrop-filter'] = "blur(5px) saturate(80%)"; document.querySelector("header").style.backgroundColor = "rgba(25, 20, 90, 0.5)"; observerCheckList.modifyHeaderBackground = true; } } /* 更改頁首內容物排列方式 */ if (!observerCheckList.modifyHeaderFlex) { for (let elem of [ document.querySelector(".setint"), document.querySelector(".plays .capo") ]) { if (elem) { elem.style.display = "flex"; elem.style.justifyContent = "space-between"; if (elem.classList.contains("setint")) { elem.style.borderTop = "1px solid rgba(255, 255, 255, 0.2)"; } observerCheckList.modifyHeaderFlex = true; } } } /* 更改六線譜前奏功能列邊界留白 */ if (!observerCheckList.modifyFunctionBarMargin) { if (document.querySelector(".tfunc2")) { observerCheckList.modifyFunctionBarMargin = true; document.querySelector(".tfunc2").style.margin = "10px"; } } /* 刪除內建的移調鈕,建立自製的 */ if (!observerCheckList.modifyTransposeButton) { if (document.querySelector(".capo .select")) { let stringCapo = document.querySelector(".capo .select").innerText.split(" / ")[0]; // CAPO let stringKey = document.querySelector(".capo .select").innerText.split(" / ")[1]; // 調 for (let i of document.querySelectorAll(".capo span[play]")) { i.style.display = "none"; } // 建立降調鈕 let spanMinus = document.createElement("span"); spanMinus.innerText = "-"; spanMinus.className = "select"; spanMinus.onclick = () => { spanCapo.innerText = spanCapo.innerText.replace(/-?\d+/, match => { return Number(match) - 1; }); spanCapo.innerText = spanCapo.innerText.replace(/\(.+\)/, match => { return `(${transpose(match.slice(1, -1), 1)})`; }); for (let i of document.querySelectorAll("#tone_z .tf")) { i.innerHTML = transpose(i.innerText, 1).replace(/(#|b)/g, "<sup>$&</sup>"); } } // 當前調 let spanCapo = document.createElement("span"); spanCapo.innerText = `Capo: ${stringCapo} (${stringKey})`; // 建立降調鈕 let spanPlus = document.createElement("span"); spanPlus.innerText = "+"; spanPlus.className = "select"; spanPlus.onclick = () => { spanCapo.innerText = spanCapo.innerText.replace(/-?\d+/, match => { return Number(match) + 1; }); spanCapo.innerText = spanCapo.innerText.replace(/\(.+\)/, match => { return `(${transpose(match.slice(1, -1), -1)})`; }); for (let i of document.querySelectorAll("#tone_z .tf")) { i.innerHTML = transpose(i.innerText, -1).replace(/(#|b)/g, "<sup>$&</sup>"); } } // 放入功能列 for (let i of [spanMinus, spanCapo, spanPlus]) { document.querySelector(".plays .capo").appendChild(i); } observerCheckList.modifyTransposeButton = true; } } }); observer.observe(document.body, { childList: true, subtree: true }); function transpose(chord, transposeValue) { const keys = { "C": "[I]", "C#": "[I#]", "D": "[II]", "D#": "[II#]", "E": "[III]", "F": "[IV]", "F#": "[IV#]", "G": "[V]", "G#": "[V#]", "A": "[VI]", "A#": "[VI#]", "B": "[VII]" }; const pitchNameFix = { "#b": "", "b#": "", "E#": "F", "Fb": "E", "B#": "C", "Cb": "B", "C##": "D", "D##": "E", "F##": "G", "G##": "A", "A##": "B" }; let resultChord = chord; for (let i = 0; i < 12; i++) { // first, transpose to Roman number. resultChord = resultChord.replaceAll( Object.keys(keys)[i], Object.values(keys)[i] ); } for (let i = 0; i < 12; i++) { // transpose offset let fixedTransposeValue = (i + transposeValue) % 12; if (fixedTransposeValue < 0) { fixedTransposeValue += 12 } // second, transpose to pitch names. resultChord = resultChord.replaceAll( Object.values(keys)[i], Object.keys(keys)[fixedTransposeValue] ); } for (let i = 0; i < 11; i++) { // fix illegal pitch names. resultChord = resultChord.replaceAll( Object.keys(pitchNameFix)[i], Object.values(pitchNameFix)[i] ); } return resultChord; }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址