您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show all the SVG symbols on the page.
// ==UserScript== // @name SVG Symbol Exhibitor // @name:zh SVG 图标展示器 // @namespace https://github.com/pansong291/ // @version 0.1.5 // @description Show all the SVG symbols on the page. // @description:zh 显示页面上的所有 SVG 图标。 // @author paso // @license Apache-2.0 // @match *://*/* // @icon https://www.w3.org/Graphics/SVG/svglogo.svg // @grant none // @run-at context-menu // @require https://update.gf.qytechs.cn/scripts/473443/1374764/popup-inject.js // ==/UserScript== ;(function () { 'use strict' const namespace = `paso-svg-symbol-exhibitor-${Date.now()}` function loadJs(src) { return new Promise(resolve => { const jsEl = document.createElement('script') jsEl.src = src jsEl.onload = resolve document.head.appendChild(jsEl) }) } function getId(elm) { return elm?.id ? `#${elm.id}` : '' } function getClassNames(elm) { let name = '' elm?.classList?.forEach((v) => name += '.' + v) return name } loadJs('https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/3.2.31/vue.global.prod.min.js').then(() => window.paso.injectPopup({ namespace, actionName: 'SVG Symbol Exhibitor', collapse: '70%', location: '40%', content: `<div id="${namespace}-app"></div>`, style: ` <style> #${namespace}-app { display: flex; flex-direction: column; gap: 16px; max-width: 80vw; } .input { min-width: 280px; } .action-row { display: flex; justify-content: flex-end; gap: 8px; } .svg-display { display: flex; flex-direction: column; gap: 16px; } .svg-wrap { display: flex; flex-direction: column; background-color: white; border-radius: 8px; transition: box-shadow .3s; } .svg-wrap:hover { box-shadow: 0 8px 12px 4px rgba(0,0,0,0.06); } .svg-name { padding: 8px; font-size: 16px; font-weight: bold; user-select: none; cursor: pointer; } .svg-symbols { display: none; flex-wrap: wrap; padding: 8px; } .svg-wrap.open .svg-symbols { display: flex; } .svg-collapse-handle { display: flex; justify-content: center; align-items: center; padding: 4px; user-select: none; cursor: pointer; } .collapse-char { transform: rotate(-90deg); transition: transform .3s; } .svg-wrap.open .collapse-char { transform: rotate(90deg); } .icon-wrap { display: flex; flex-direction: column; align-items: center; padding: 8px; gap: 4px; border-radius: 4px; transition: background-color .3s; } .icon-wrap:hover { background-color: rgba(0,0,0,0.08); } .icon-wrap svg { font-size: 36px; fill: #666; color: #666; } </style>` }) ).then(() => { const Icon = { props: { type: String }, computed: { innerAttrs() { return { 'xlink:href': `#${this.type}` } } }, template: ` <div class="icon-wrap"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1em" height="1em" focusable="false"> <use v-bind="innerAttrs" /> </svg> <div class="monospace">{{type}}</div> </div>` } const SvgWrap = { components: { Icon }, props: { svg: Object }, emits: ['collapseChange'], methods: { onCollapseClick() { this.$emit('collapseChange', !this.svg.collapse) } }, template: ` <div class="svg-wrap" :class="{open: !svg.collapse}"> <div class="svg-name monospace" @click="onCollapseClick">{{svg.name}}</div> <div class="svg-symbols"> <Icon v-for="symbol in svg.symbols" :type="symbol" /> </div> <div class="svg-collapse-handle" @click="onCollapseClick"><span class="collapse-char"><</span></div> </div>` } window.Vue.createApp({ components: { SvgWrap }, data() { return { selector: 'svg', search: '', svgs: [] } }, computed: { result() { if (!this.search) return this.svgs const svgList = [] for (let i = 0; i < this.svgs.length; i++) { const svg = this.svgs[i] const s = { id: svg.id, name: svg.name, collapse: svg.collapse, symbols: svg.symbols.filter(symbol => this.textSearch(symbol, this.search)) } if (s.symbols.length) svgList.push(s) } return svgList } }, methods: { onDisplayClick() { const svgElems = document.querySelectorAll(this.selector) const svgs = [] for (let i = 0; i < svgElems.length; i++) { const svgElem = svgElems[i] const symbolsElems = svgElem.querySelectorAll(`${this.selector} > symbol`) if (symbolsElems.length) { const svg = { id: i, name: `${svgElem.localName}${getId(svgElem)}${getClassNames(svgElem)}`, collapse: false, symbols: [] } for (let i = 0; i < symbolsElems.length; i++) { svg.symbols.push(symbolsElems[i].id) } svgs.push(svg) } } this.svgs = svgs }, textSearch(source, target) { if (!source || !target) return false source = source.toLowerCase() target = target.toLowerCase() if (source.indexOf(target) >= 0) return true try { return new RegExp('\\b' + Array.from(target).join('([a-z0-9]*[^a-z0-9]+)?')).test(source) } catch (e) { return false } } }, template: ` <div class="action-row"> <input class="input monospace" v-model="selector" placeholder="please enter a css selector"> <button class="button" @click="onDisplayClick">Display</button> <input v-if="svgs.length" class="input monospace" v-model="search" placeholder="search"> </div> <div class="svg-display"> <SvgWrap v-for="svg in result" :svg="svg" @collapse-change="c => svgs[svg.id].collapse = c"/> </div>` }).mount(`#${namespace}-app`) }) })()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址