// ==UserScript== // @name CSS 样式注入 // @namespace https://diaoqi.gitee.io/blog/ // @version 0.5 // @description 插入自定义 CSS 样式到任意网址 // @author 掉漆 // @license MIT // @match * // @include * // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @grant GM_registerMenuCommand // @grant GM_setClipboard // @downloadURL none // ==/UserScript== (function () { 'use strict'; // 代码来源于Youth霖,原地址:https://gist.github.com/youthlin/c4c08ffe4273ca7ebbf759289cef9964 // 本代码简化源代码部分功能、优化部分展示逻辑、以及添加部分功能。 const SETTING_KEY = 'cssMap' const RAND = (Math.random() * 100000).toFixed(0) // 实现类似jQuery中的on方法 const on = function (eventName, selector, handler) { // http://youmightnotneedjquery.com/ document.addEventListener(eventName, function (e) { for (let target = e.target; target && target !== this; target = target.parentNode) { if (target.matches !== undefined && target.matches(selector)) { handler.call(target, e); break; } if (target.tagName === 'HTML') { break; } } }, false); } function start() { const cssMap = cssValue() const html = document.getElementsByTagName('html')[0] const inject = `
` html.insertAdjacentHTML('beforeend', inject) const wrapper = document.getElementById(`inject-css-${RAND}`) // 点击设置按钮事件 GM_registerMenuCommand('设置CSS规则', function (e) { wrapper.style.display = 'flex' }, 's') // 渲染当前规则 render(cssMap, wrapper) // 编辑规则详情 on('click', '.inject-css-edit', function (e) { // GM.setClipboard(e.target.dataset.key, "text"); document.querySelector('#inject-css-url').value = e.target.dataset.key document.querySelector('#inject-css-value').value = e.target.dataset.value }) // 删除规则 on('click', '.inject-css-delete', function (e) { const res = confirm(`确认删除${e.target.dataset.key}吗?`); if (res === true) { const deleteKey = e.target.dataset.key cssMap.delete(deleteKey) save(cssMap) render(cssMap, wrapper) } }) // 添加规则 on('click', '.inject-css-add', function (e) { e.preventDefault() const k = document.querySelector('#inject-css-url').value.trim() const v = document.querySelector('#inject-css-value').value.trim() if (k !== '' && v !== '') { try { new RegExp(k) } catch (e) { alert('`' + k + '`: 不是有效的正则表达式. error=' + e) return } cssMap.set(k, v) save(cssMap) render(cssMap, wrapper) } }) // 关闭按钮 on('click', '.inject-css-hide', function () { wrapper.style.display = 'none' }) // 键盘退出按钮 on('keyup', 'html', function (e) { if (e.code === 'Escape') { wrapper.style.display = 'none' } }) // 默认隐藏界面 document.querySelector('.inject-css-hide').click() } // 获取保存的规则信息 function cssValue() { const settingValue = GM_getValue(SETTING_KEY, '{}'); let cssMap = JSON.parse(settingValue) // url regex -> css value cssMap = new Map(Object.entries(cssMap)) // to Map return cssMap } // 保存规则 function save(cssMap) { const s = JSON.stringify(Object.fromEntries(cssMap));// Map 需要先转为 Object 才能序列化为 JSON GM_setValue(SETTING_KEY, s) } // 渲染当前CSS规则 渲染配置的表格 function render(cssMap, wrapper) { const url = window.location.href let injectCss = `` let tableBody = '' // 遍历所有规则,渲染整个表格。若找到当前页规则,保存在injectCss中,最后统一渲染。 for (const entry of cssMap) { try { let active = '' if (new RegExp(entry[0]).test(url)) { injectCss += entry[1] + "\n" active = 'active' } tableBody += `${entry[0]}
${entry[1]}
URL 正则 | 注入 CSS | 操作 |
---|---|---|