您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add Touchfriendly TOC and next and previous link variant
- // ==UserScript==
- // https://gf.qytechs.cn/scripts/380720-toc-touchbutton
- // @name TOC TouchButton
- // @namespace Touchfriendly TOC Variant
- // @match https://*.wordpress.com/*
- // @version 0.8
- // @description Add Touchfriendly TOC and next and previous link variant
- // @grant none
- // ==/UserScript==
- //Known Bug: look for a way to detect readerview/android page reload
- // onreload with active reader view(firefox) -> loads original version with longText link
- const SELECTORTOC = 'p > a';
- const MEDIAQUERYMAXWIDTH = '480px';
- const DEFAULTSHORTTOC = "ToC";
- const DEFAULTSHORTPREV = "-1←";
- const DEFAULTSHORTNEXT = "→+1";
- /**
- * Setting to Pair ["Longtext", "ShortText"]
- * ShortText will be shown as button
- * @param {String} LongText longer String which should be replaced
- * @param {Array} ShortText replacement for longText
- */
- const LINKVARIANTS = [
- {
- "shortVersion": DEFAULTSHORTTOC,
- "longVariants": ["Table of Contents", "Index", "ToC"]
- },
- {
- "shortVersion": DEFAULTSHORTPREV,
- "longVariants": ["Previous Chapter", "Prev", "<- Previous Chapter"]
- },
- {
- "shortVersion": DEFAULTSHORTNEXT,
- "longVariants": ["Next Chapter", "Next", "Next Chapter ->"]
- }];
- //"<- Previous Chapter" or "<- Previous Chapter" possible
- //"Next Chapter ->" same as before
- // ↥ front UI ↥ for adjustment for different sites copy script and adjust SELECTORTOC and LINKVARIANTS and metas(@match, @namespace)
- // ↧ script ↧
- var nodesArray = [];
- function readCssStyle(element, attribute) {
- let style = window.getComputedStyle ? getComputedStyle(element, null) : element.currentStyle;
- return style[attribute]
- }
- /**
- * toggle Hidden attributes depending on css value (set by mediaquery)
- *
- * without active javascript attribute toggling -> the longT Version would get read by Firefox Reader View and maybe other readability plugins
- */
- function checkHidden() {
- let shortT = document.querySelectorAll('.shortTOC');
- let longT = document.querySelectorAll('.longTOC');
- //console.log("checkHidden","checkHidden shortT length: "+shortT.length +" # "+ readStyle(shortT[0],"display") );
- //http://john.foliot.ca/aria-hidden/
- for (var i = 0; i < shortT.length; i++) {
- //console.log("checkHidden","checkHidden shortT setAttribute aria-hidden + " + i);
- if (readCssStyle(shortT[i], "display") === "none") {
- //console.log("checkHidden","checkHidden shortT setAttribute aria-hidden display none");
- shortT[i].setAttribute('aria-hidden', 'true');
- shortT[i].setAttribute('hidden', "true");
- shortT[i].setAttribute('role', 'presentation');
- }
- else if (readCssStyle(shortT[i], "display") == "inline-block") {
- shortT[i].setAttribute('aria-hidden', 'false')
- shortT[i].removeAttribute('role');
- shortT[i].removeAttribute('hidden');
- }
- }
- for (let i = 0; i < longT.length; i++) {
- if (readCssStyle(longT[i], "display") == "none") {
- longT[i].setAttribute('aria-hidden', 'true');
- longT[i].setAttribute('hidden', "true");
- longT[i].setAttribute('role', 'presentation');
- }
- else if (readCssStyle(longT[i], "display") == "inline-block") {
- longT[i].setAttribute('aria-hidden', 'false')
- longT[i].removeAttribute('role');
- longT[i].removeAttribute('hidden');
- }
- }
- }
- //https://stackoverflow.com/questions/23683439/gm-addstyle-equivalent-in-tampermonkey
- function addGlobalStyle(css) {
- let head, style;
- head = document.getElementsByTagName('head')[0];
- if (!head) { return; }
- style = document.createElement('style');
- style.type = 'text/css';
- style.innerHTML = css;
- head.appendChild(style);
- }
- //https://stackoverflow.com/questions/1686571/greasemonkey-how-to-apply-a-css-rule-only-for-media-print
- //https://stackoverflow.com/questions/8624210/getting-jquery-and-gm-addstyle-to-work-in-a-chrome-userscript-based-off-of-a-wor
- //multiline for better readability add at end of line -> \
- //https://stackoverflow.com/questions/23608346/how-to-style-a-div-like-the-button-element
- addGlobalStyle('\
- .shortTOC{ display:none;visiblity:hidden;}\
- .longTOC{ display:inline-block;visiblity:visible;} \
- @media (max-width: '+ MEDIAQUERYMAXWIDTH + ') { \
- .shortTOC { display: inline-block;visiblity:visible;\
- width: 23%;\
- text-align: center;\
- line-height:3.5em;\
- font-size:6vw;\
- -ms-touch-action: manipulation;\
- touch-action: manipulation;\
- cursor: pointer;\
- -webkit-user-select: none;\
- -moz-user-select: none;\
- -ms-user-select: none;\
- user-select: none;\
- background-image: none;\
- border: 1px solid transparent;\
- border-radius: 4px;\
- border-color: #ccc;\
- }\
- .longTOC { display:none;visiblity:hidden;}\
- }\
- ');
- /**
- * results has only Nodes which match filterString
- * @param {Array} Nodes
- * @param {String} filterString
- */
- function getNodes(Nodes, filterString) {
- //filter both HTML entity character and pure text
- //innerHTML:characters as is (example %nbsp; kept as space) ; textContent: example converted to space character
- let TOCFilter = Nodes.filter(e => (e.innerHTML == filterString || e.textContent == filterString));
- /*
- let TOCNodes = TOCFilter.map((e, i) => {
- //console.log("elementcontent: " +e + " at index: "+i +" nodeValueOuterhtml: " + e.outerHTML + " nodeValueinnerhtml: " + e.innerHTML );
- return e
- });
- */
- return TOCFilter
- }
- /**
- * add custom classes to link text
- * @param {array} Nodes linkarray
- * @param {string} shortText
- */
- function setClasses(Nodes, shortText) {
- Nodes.forEach(element => {
- let TOCButton = document.createElement("a")
- TOCButton.href = element;
- TOCButton.setAttribute("class", "shortTOC")
- TOCButton.textContent = shortText
- element.setAttribute("class", "longTOC")
- element.parentNode.insertBefore(TOCButton, element.nextSibling);
- });
- }
- /**
- * Compare long link text and replace with shortText version
- * @param {Array} nodes link array
- * @param {String} longText longer String which should be replaced and is used as filter for the linkarray
- * @param {String} shortText replacement for longText
- */
- function addTouchfriendlyVariant(nodes, longText, shortText) {
- let TOCNodes = getNodes(nodes, longText)
- setClasses(TOCNodes, shortText);
- //console.log('Toc element: ' + TOCNodes);
- }
- function main() {
- let getSelectedLinks = function () {
- let links = Array.from(
- document.querySelectorAll(SELECTORTOC)
- );
- return links;
- };
- const links = getSelectedLinks();
- /*
- addTouchfriendlyVariant(links, "Table of Contents", "ToC");
- addTouchfriendlyVariant(links, "Previous Chapter", "-1←");
- addTouchfriendlyVariant(links, "Next Chapter", '→+1');
- */
- LINKVARIANTS.forEach(key => {
- key.longVariants.forEach(variant => {
- //console.log("LINKVARIANTS: " + key.shortVersion + " # " + variant);
- addTouchfriendlyVariant(links, variant, key.shortVersion);
- });
- });
- }
- main()
- //https://www.sitepoint.com/jquery-document-ready-plain-javascript/
- var callback = function () {
- // Handler when the DOM is fully loaded
- checkHidden();
- };
- //https://stackoverflow.com/questions/2720658/how-to-detect-when-a-tab-is-focused-or-not-in-chrome-with-javascript
- var focusCheckCallback = function () {
- //console.log("onvisibilityState reaction: " + document.visibilityState);
- if (document.visibilityState == "visible") //hidden -> readerview rebuild?
- checkHidden();
- }
- if (
- document.readyState === "complete" ||
- (document.readyState !== "loading" && !document.documentElement.doScroll)
- ) {
- callback();
- } else {
- document.addEventListener("DOMContentLoaded", callback);
- }
- window.addEventListener("resize", function () {
- checkHidden();
- });
- window.addEventListener("visibilitychange", focusCheckCallback);
- //window.addEventListener("blur",focusCheckCallback);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址