您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
给CSS适配人员用的辅助工具函数
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/439632/1015907/CSS%E6%94%B9%E7%BC%96%E7%BD%91%E9%A1%B5%E5%93%8D%E5%BA%94%E5%BC%8F%20%E9%80%82%E9%85%8D%E5%B7%A5%E4%BD%9C%E8%80%85.js
// ==UserScript== // @name CSS改编/网页响应式 适配工作者 // @version 0.89 // @description 给CSS适配人员用的辅助工具函数 // @description:en Helper functions for adaptation developers // @match *://*/* // @license The Unlicense // @namespace https://gf.qytechs.cn/users/871942 // ==/UserScript== const CSSA = unsafeWindow.CSSA = { elemsWithInlineStyles, extractCssOfModifiedInPage, findOverflowedElems, unsetStyles, removeSelectorsThose: { tooBroad: true } } const warnSelectorsThose = { tooBroad: '/*⚠*/' } const rxSelectorsThose = { tooBroad: /^\/\*⚠\*\/[^.#]+ {[^\n]+\n*/gm } function elemsWithInlineStyles(doc = document, filterAttr) { const elems = [] if (!doc) return elems elems.push(...[...doc.all].filter(el => (!filterAttr || el.hasAttribute(filterAttr)) && !/\b(a|img|span)\b/.test(el.localName) && (el.localName === 'iframe' ? elems.push(...elemsWithInlineStyles(el.contentDocument, filterAttr)) && false : el.attributes.style?.value ) )) return elems } function extractStyleToCssForm(elem) { let { localName, attributes: { id = '', class: className = '', style } } = elem if (specTags.has(localName)) id = className = '' else { localName = id || className ? '' : `${warnSelectorsThose.tooBroad}${localName}` if (className) className = className.value.replace(/ |^/g, '.') if (id) { id = /[-]|auto|\bid\b/.test(id.value) ? '' : `#${id.value}` if (id) className = '' } } return `${localName}${id}${className} { ${style.value .replace(/(:) /g, '$1') .replace(/;\b/g, '$& ') .replace(/;$/, '')} }` } const specTags = new Set('html body'.split(' ')) function extractCssOfModifiedInPage(rootNode = document, { filterAttr = '', existing = 'user-custom' } = {}) { rootNode = rootNode.getRootNode() // `rootNode` can be an arbitrarily selected leaf node without having to pay attention to selecting `HTMLDocument` let orig = existing && rootNode instanceof Node && rootNode.querySelector(`style[${existing}]`)?.innerText || '' , new_ = elemsWithInlineStyles(rootNode, filterAttr).map(extractStyleToCssForm).join('\n') return { modified: mergeCommonCss(new_), merged: mergeCommonCss(orig + new_) } } function mergeCommonCss(css = '') { const re = { node: [/^(\s*)([^{}}]+)\s*\{([^}]+?)\s*\}(.*?)\2\{([^}]+?)\s*\}/ms, '$1$2{$3;$5 }$4'], nodes: [/([^{\n]+?)(\s*\{[^}]+\})(.*?)\s*([^{\n]+?)\2/s, '$1, $4$2$3'] } let merged Object.values(re).forEach(([mat, pla]) => { const merge = str => str.replace(mat, pla) merged = merge(css) while (css !== merged) merged = merge(css = merged) }) Object.keys(CSSA.removeSelectorsThose).forEach(k => CSSA.removeSelectorsThose[k] && ( merged = merged.replace(rxSelectorsThose[k], '') ) ) return merged.trim() } function findOverflowedElems(rootElem = document.body, { echo = false } = {}) { if (!(rootElem instanceof HTMLElement)) throw TypeError('An entry element is required to be specified.') if (echo) console.log(`The width of the rootElem`, rootElem, `is ${rootElem.clientWidth}px.`) return [...rootElem.querySelectorAll('*')].filter(el => el.clientWidth > rootElem.clientWidth) } function unsetStyles(elem = CSSA.$0, props = [], { echo = true } = {}) { if (!(elem instanceof HTMLElement)) throw TypeError('An element is required to be specified.') if (typeof props === 'string') props = props.split(/[\s;]+/).filter(Boolean) elem.style.cssText += props.map(prop => `${prop}:unset`).join('; ') if (echo) console.log('The style value of', elem, `has been set to: {\n ${elem.attributes.style.value}\n}`) }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址