需求来源
有些网站的广告元素很容易找,想直接把它
display:none 掉,或者把某些带背景图像的元素隐藏或更换背景图片。
然后找到了一个 Chrome 插件
Stylus 也能用但感觉没有必要单独装一个插件,还很复杂的样子。
想着油猴脚本应该有很多类似的,结果搜了一下都是针对特定网站的(比如百度/B站/知乎美化),于是就自己写了这个油猴插件。
使用方式
需要先安装用户脚本管理器
Tampermonkey (即俗称的油猴插件)或者
Violentmonkey (中文名
暴力猴 ),然后点击
这里 安装脚本,点击
这里 预览脚本(见
Gist 地址 )。
对油猴脚本开发感兴趣的同学,可以参考之前的文章:
如何编写一个油猴脚本
实现原理
一个 URL 正则表达式对应一条 CSS 规则,将所有规则保存起来(油猴提供了两个 API
GM_getValue /
GM_setValue 供存取设置内容)。
然后在每个页面加载后,遍历所有规则,找到所有对本页适用的规则,直接注入到页面中。
本着一个脚本做一件事的原则,这个脚本只提供注入 CSS 功能,而不提供注入 JS 的功能。
局限性
在浏览 GNU 的
ftp 站点 时发现规则没有生效。然后认识了一个 HTTP 响应头
Content-Security-Policy 。
该站点的此响应头是这样设置的:
1
|
Content-Security-Policy: <span>default</span>-src <span>'self'</span>; img-src data: <span>'self'</span> https:<span>//</span>static.fsf.org https:<span>//g</span>nu.org; object-src <span>'none'</span>; frame-ancestors <span>'none'</span>; child-src <span>'self'</span> https:<span>//</span>static.gnu.org https:<span>//</span>static1p.gnu.org https:<span>//</span>static1p.fsf.org;script-src <span>'unsafe-eval'</span> <span>'self'</span>
|
报错信息如下:
1
|
Refused to apply inline style because it violates the following Content Security Policy directive: <span>"default-src 'self'"</span>. Either the <span>'unsafe-inline'</span> keyword, a hash (<span>'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='</span>), <span>or</span> a nonce (<span>'nonce-...'</span>) <span>is</span> required to enable inline execution. Note also that <span>'style-src'</span> was <span>not</span> explicitly set, so <span>'default-src'</span> <span>is</span> used <span>as</span> a fallback.
|
这个 header 对应的值是多个分号分隔的部分,指定了页面支持哪些来源的资源。
第一个
default-src 指定默认的资源来源是
self 即当前域名。
根据报错信息提示,浏览器拒绝应用注入的样式,因为内容安全策略设置的
default-src 指定了只接受同域名的样式,而没有接受行内样式
unsafe-inline ,也没有指定可执行的样式的 hash, nonce 值。
因为没有指定
style-src 所以使用的是
default-src 规则。
更多内容安全策略的相关知识,大家可以参考 MDN 文章
内容安全策略( CSP ) 、
Content-Security-Policy ,以及阮一峰的博文
Content Security Policy 入门教程 。
分享一些规则
找到了广告元素后,可以直接使用
display: none 将其隐藏,另外插件还注入了一个水印层, class 是
.inject-watermark ,也可以用来添加自定义水印~
1
2
3
4
5
6
7
8
9
|
<span>body</span> > <span>div</span><span>:empty</span> {
<span>/* body 的空的子元素去除背景 */</span>
<span>background</span>: transparent <span>!important</span>;
}
<span>.inject-watermark</span> {
<span>/* 插件注入的元素,覆盖整个页面。可以添加自定义水印 */</span>
<span>background-image</span>: <span>url</span>(<span>"data:image/svg+xml,%3Csvg width='100' height='100' xmlns='http://www.w3.org/2000/svg'%3E%3Ctext x='50%25' y='50%25' font-size='14' fill='%23a2a9b6' fill-opacity='0.5' font-family='system-ui, sans-serif' text-anchor='middle' dominant-baseline='middle' transform='rotate(-45 50 50)'%3Eyouthlin.com%3C/text%3E%3C/svg%3E"</span>)
}
|
svg 可以作为背景水印,如何将文本写在 svg 上,可以参考菜鸟教程
SVG <text> 。 从教程的
尝试一下 按钮可以进入 svg 在线编辑器。
另外再推荐张鑫旭的几篇相关文章:
如何让文字作为CSS背景图片显示? ;
如果想要将文字倾斜,还可以看下 svg 中如何旋转
理解SVG transform坐标变换 ;
最后为了把 svg 放在背景上,通常可以使用 base64 编码 svg 后放在
background-image 的 url 中,
不过,还有另一种可读性更好的方式
学习了,CSS中内联SVG图片有比Base64更好的形式 。
Reader Echoes
1 comment