您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
pixivイラストページのタグに作者マーカーと百科事典アイコン、ユーザー名の列に作品タグを復活させます
当前为
// ==UserScript== // @name pixivイラストページ改善 // @description pixivイラストページのタグに作者マーカーと百科事典アイコン、ユーザー名の列に作品タグを復活させます // @namespace Aime // @match https://www.pixiv.net/* // @version 1.1.2 // @grant none // @run-at document-end // @noframes // @note 2018/06/22 1.0.1 作者アイコンを大サイズに差し替え // @note 2018/07/18 1.0.2 pixiv側のclass変更に対応 // @note 2018/07/26 1.0.3 アイコン差し替えを修正 // @note 2018/09/23 1.1.0 新プロフィールページのサムネイルをトリミングなしに差し替え。作品タグをapiから取得 // @note 2018/10/03 1.1.1 サムネイル差し替え修正 // @note 2018/12/28 1.1.2 アイコン差し替え修正 // ==/UserScript== // jshint esversion:6 (() => { "use strict"; const pixivService = { enablePixpediaIcon : true, // 百科事典アイコンを付けるか? enableTagCloud : true, // 作品タグを表示するか? tagCloudDisplayCount : 30, // 作品タグの表示数(目安) tagCloudSortByName : true, // 作品タグのソート順 (true:名前順, false:多い順) enableReplaceAuthorIcon : true, // 作者アイコンを大サイズに差し替える? enableReplaceThumbnail : true, // サムネイルをトリミングなしに差し替える? _existPixpedia : {}, _illustTags : {}, _currenAuthorId : -1, _tagCloud : null, _delayTimer : null, run: function() { const root = document.getElementById("root"); if (!root) return; const style = this.$C("style"); style.textContent = this._style; document.querySelector("head").appendChild(style); root.addEventListener("click", this, true); new MutationObserver(records => { let thumbs = [], tagModified = false; records.forEach(record => { if (record.type === "attributes") { const target = record.target; if (target.classList.contains("_2lyPnMP")) { this.replaceAuthorIcon(); } if (this.enableReplaceThumbnail && /1200\.jpg/.test(target.style.backgroundImage)) { thumbs.push(target); } } else { record.addedNodes.forEach(node => { if (!node.querySelectorAll) return; // 増えたタグに百科事典アイコンを付ける const tags = node.querySelectorAll("a.gtm-new-work-tag-event-click:not([pixpedia]"); if (tags.length) { if (this.enablePixpediaIcon) tags.forEach(node => this.insertPixpedia(node)); tagModified = true; return; } // タグが減ったか変わらない場合は画像が変わったかで判断 // イラスト:img.sc-hMrMfs img.sc-fjhmcy, うごイラ:div._2UMFAz4, 閲覧注意:div.sc-jkCMRl, 閲覧注意解除:div.sc-erNlkL if (node.classList.contains("sc-fjhmcy") || node.classList.contains("_2UMFAz4") || node.classList.contains("sc-bbkauy") || node.classList.contains("sc-jkCMRl")) { this.stopDelayTimer(); this._delayTimer = setTimeout(this.illustChanged.bind(this), 1000); } }); } }); if (thumbs.length) { this.replaceThumbnail(thumbs); } if (tagModified) { this.authorTags(); } }).observe(root, { childList : true, subtree : true, attributes : true, attributeFilter : [ "style" ] }); }, stopDelayTimer: function() { if (this._delayTimer) { clearTimeout(this._delayTimer); this._delayTimer = null; } }, illustChanged: function() { this.stopDelayTimer(); this.authorTags(); }, insertPixpedia: async function(node) { if (node.hasAttribute("pixpedia")) return; node.setAttribute("pixpedia", "true"); node.addEventListener("mouseover", this, true); try { const eTag = encodeURIComponent(node.textContent.trim()); if (!(eTag in this._existPixpedia)) this._existPixpedia[eTag] = !!await this.fetchJSON("https://www.pixiv.net/ajax/tag/" + eTag + "/info"); node.parentElement.appendChild(this.$C("a", { class: "pixpedia-icon" + (this._existPixpedia[eTag]? "": " pixpedia-icon-no-item"), href: "https://dic.pixiv.net/a/" + eTag })); } catch (e) { console.error(e); } }, handleEvent: function(event) { switch (event.type) { case "mouseover": event.stopPropagation(); break; case "click": if (event.target.classList.contains("gm-profile-work-list-tag-filter-click")) { this.openTagPage(event); } break; } }, openTagPage: function(event) { const url = location.href; [ { re: /member_illust\.php\?id=(\d+)/, url: "https://www.pixiv.net/member_tag_all.php?id=" }, { re: /novel\/member\.php\?id=(\d+)/, url: "https://www.pixiv.net/novel/member_tag_all.php?id=" }, ].forEach(p => { const match = p.re.exec(url); if (match) { event.stopPropagation(); event.preventDefault(); location.href = p.url + match[1]; return; } }); }, authorTags: async function() { this.replaceAuthorIcon(); const match = /illust_id=(\d+)/.exec(location.href); if (!match) return; const illustId = match[1]; let authorId; try { if (!(illustId in this._illustTags)) this._illustTags[illustId] = await this.fetchJSON("https://www.pixiv.net/ajax/tags/illust/" + illustId); const tagData = this._illustTags[illustId]; if (!tagData) return; authorId = tagData.authorId; document.querySelectorAll("figcaption footer > ul > li").forEach(elem => { let isOwn = false; const a = elem.querySelector("a.gtm-new-work-tag-event-click"); if (a) { const tag = a.textContent.trim(); const find = tagData.tags.find(t => t.tag == tag); isOwn = find && find.userId === authorId; } if (isOwn) elem.classList.add("author-tag-marker"); else elem.classList.remove("author-tag-marker"); }); } catch (e) { console.error(e); } if (this.enableTagCloud && authorId && (this._currenAuthorId !== authorId || !document.getElementById("author-tags"))) { this.authorTagCloud(authorId); } }, authorTagCloud: async function(authorId) { const aside = document.querySelector("article + aside"); if (!aside) return; const tagAllUrl = "https://www.pixiv.net/member_tag_all.php?id=" + authorId; if (this._currenAuthorId !== authorId) { this._currenAuthorId = authorId; try { let tags = await this.fetchJSON("https://www.pixiv.net/ajax/user/" + authorId + "/illustmanga/tags"); tags.sort(this.compareTagByCount); // 多い順にソート const dispCnt = this.tagCloudDisplayCount; if (tags.length > dispCnt) { // とりあえず目安位置以下の値を破棄 const lastCnt = tags[dispCnt - 1].cnt; tags = tags.filter(v => v.cnt >= lastCnt); const tags2 = tags.filter(v => v.cnt > lastCnt); // 目安位置と同数とそれより多いのがどちらが目安位置に近いか if (dispCnt - tags2.length < tags.length - dispCnt && tags2.length > 5) { tags = tags2; } } if (tags.length > 0) { let lv = 1, cur = tags[0].cnt; tags.forEach(tag => { // レベル付け if (lv < 6 && cur !== tag.cnt) { cur = tag.cnt; lv++; } // <li class="level1"><a href="/member_illust.php?id=${authorId}&tag=${tag.tag}">${tag.tag}<span class="cnt">(${tag.cnt})</span></a></li> tag.dom = this.$C("li", { class: "level" + lv, "data-cnt": tag.cnt, "data-tag": tag.tag }); const a = this.$C("a", { href: "/member_illust.php?id=" + authorId + "&tag=" + encodeURIComponent(tag.tag) }); a.textContent = tag.tag; const span = this.$C("span", { class: "cnt" }); span.textContent = "(" + tag.cnt + ")"; a.appendChild(span); tag.dom.appendChild(a); }); } if (this.tagCloudSortByName) { tags.sort(this.compareTagByName); } const tagCloud = this.$C("ul", { class: "tagCloud" }); tags.forEach(tag => tagCloud.appendChild(tag.dom)); this._tagCloud = tagCloud; } catch (e) { console.error(e); this._tagCloud = null; } } let container = document.getElementById("author-tags"); if (container) { container.parentElement.removeChild(container); } if (this._tagCloud) { container = this.$C("div", { id: "author-tags", class: "_34Uqb-T" }); aside.insertBefore(container, document.querySelector("._3M6FtEB")); const header = this.$C("div", { class: "tags-header" }); header.innerHTML = `<h2><a href="${tagAllUrl}">作品タグ</a></h2>`; const sortBtn = this.$C("button", { class: "sort-button" }); sortBtn.textContent = "▼"; sortBtn.addEventListener("click", event => { const tags = document.querySelector("#author-tags .tagCloud"); if (tags) { const byName = this.tagCloudSortByName = !this.tagCloudSortByName; Array.from(tags.querySelectorAll("li")) .map(v => { return { dom: v, cnt: v.dataset.cnt, tag: v.dataset.tag }; }) .sort(byName? this.compareTagByName: this.compareTagByCount) .forEach(v => tags.appendChild(v.dom)); } }); header.appendChild(sortBtn); container.appendChild(header); container.appendChild(this._tagCloud); } }, compareTagByCount: function(a, b) { const r = b.cnt - a.cnt; return r? r: pixivService.compareTagByName(a, b); }, compareTagByName: function(a, b) { return a.tag.localeCompare(b.tag, {}, { numeric: true }); }, replaceAuthorIcon: function() { if (!this.enableReplaceAuthorIcon) return; const icon = document.querySelector("article + aside section ._2lyPnMP"); if (icon) { const img = icon.style.backgroundImage.replace("_50.", "_170.").replace("_s.", "."); if (icon.style.backgroundImage !== img) { icon.style.backgroundImage = img; let p = icon.parentElement; if (p.nodeName === "A") { p = p.parentElement; } p.classList.add("icon170"); } } }, replaceThumbnail: function(nodes) { if (!nodes || nodes.length <= 0) return; nodes.forEach(elem => { let img = elem.style.backgroundImage; let img_r = img.replace(/(?:250x250_80_a2|360x360_70)(.+)_square1200/, "240x240$1_master1200"); if (/240x240.+_master1200/.test(img_r)) { elem.classList.add("non-trim-thumb"); if (img !== img_r) { elem.style.backgroundImage = img_r; } } }); }, fetchSameOrigin: function (url) { return fetch(url, { mode: "same-origin", credentials: "same-origin" }); }, fetchJSON: async function(url) { const response = await this.fetchSameOrigin(url); const data = await response.json(); if (data.error) throw new Error(data.message); return data.body; }, $C: function(tag, attrs) { const elem = document.createElement(tag); if (attrs) Object.keys(attrs).forEach(key => elem.setAttribute(key, attrs[key])); return elem; }, _style: ` #n-overlay { position: fixed; z-index: 10000; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, .7); } #n-tag-list { color: #333; background-color: #eee; border: 1px solid #999; margin: 20px 40px; padding: 8px 16px; line-height: 1.3; overflow-y: auto; height: calc(100vh - 90px); } #n-tag-list dt { width: 8ch; clear: left; float: left; margin: 0; padding: 2px 0; text-align: right; font-weight: bold; } #n-tag-list dt::after { content: " : "; margin-inline-end: 1ch; } #n-tag-list dd { margin: 0; padding: 2px 0; } .n-inline-list { list-style: none; padding: 0; margin: 0; } .n-inline-list li { display: inline-block; padding: 0; margin: 0; } .n-inline-list li:nth-last-of-type(n+2)::after { content: " /"; margin-inline-end: 1ch; } .n-inline-list li > a { text-decoration: none; } /* 百科事典 */ .pixpedia-icon { display: inline-block; margin-left: 2px; width: 15px; height: 14px; vertical-align: -2px; text-decoration: none; background: url(https://s.pximg.net/www/images/inline/pixpedia.png) no-repeat; } .pixpedia-icon-no-item { background: url(https://s.pximg.net/www/images/inline/pixpedia-no-item.png) no-repeat; } .pixpedia-icon::before { display: none; } /* 作者タグ */ .author-tag-marker::before { content: "*" !important; color: #E66; } /* "#"を消す */ figcaption footer > ul > li a.gtm-new-work-tag-event-click::before { display: none !important; } /* tag cloud */ #author-tags { padding: 8px; background-color: #FFF; border-radius: 8px; } #author-tags .tags-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } #author-tags h2 { color: #333; font-size: 14px; margin: 0; } #author-tags h2 a { color: inherit; text-decoration: none; } #author-tags .sort-button { padding: 0; font-size: 14px; background: none; border: none; color: inherit; cursor: pointer; } .tagCloud { font-size: 12px; line-height: 1.6; padding: 0; margin: 0; word-break: break-all; } .tagCloud li { display: inline; font-size: 12px; padding: 0px 2px; margin: 0px; } .tagCloud li a { color: inherit; text-decoration: none; } .tagCloud li.level1 { font-size: 20px; font-weight: bold; } .tagCloud li.level1 a { color: #3E5B71; } .tagCloud li.level2 { font-size: 18px; font-weight: bold; } .tagCloud li.level2 a { color: #3E5B71; } .tagCloud li.level3 { font-size: 17px; font-weight: bold; } .tagCloud li.level3 a { color: #587C97; } .tagCloud li.level4 { font-size: 16px; font-weight: bold; } .tagCloud li.level4 a { color: #587C97; } .tagCloud li.level5 { font-size: 14px; font-weight: bold; } .tagCloud li.level5 a { color: #587C97; } .tagCloud li.level6 a { color: #5E9ECE; } .tagCloud li a:hover { background-color: #3E5B71; color: #FFF; } .tagCloud li .cnt { font-size: 11px; font-weight: normal; color: #999999; } /* 作者アイコンを大きく */ article + aside section { margin-top: 0; } .icon170 { display: block !important; text-align: center !important; } .icon170 ._2lyPnMP { width: 170px !important; height: 170px !important; margin: 0 auto 4px !important; border-radius: 4px !important; background-position: center !important; background-repeat: no-repeat !important; background-size: contain !important; } /* トリミングなしサムネイル */ .non-trim-thumb { background-size: contain; } ` }; pixivService.run(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址