背景
前段时间有小伙伴提了个烦恼,说是 CSDN和知乎的博客在未登录状态下无法复制代码,必须登录才能复制,不像博客园、掘金能直接复制,很不方便。为了解决一个问题我决定做一个浏览器插件——codebox。
对于那些对此插件感兴趣的用户,可以轻松地通过谷歌、火狐、Edge扩展商店进行下载和安装。使用这个插件,他们将能够更加高效地获取所需的代码,无论是学习还是工作中。
在此基础上,小编根据自身需要,另外加了几个功能,还支持解除关注博主即可阅读全文的提示、去除了登陆弹窗、自动展开代码块。并且还只支持了知乎/脚本之家/博客园/博客园/51CTO博客/php中文网等网站。
这里先介绍下如何使用和基本原理。
安装
安装方式一:插件商店(推荐)
直接下载安装:
- 进入应用商店
- 搜索:
codebox
安装方式二:直接安装
安装方式三:源码安装
- clone源码
git clone https://github.com/027xiguapi/code-box.git - 安装和打包
pnpm install pnpm dev pnpm build - 谷歌浏览器,从右上角菜单->更多工具->扩展程序可以进入插件管理页面,也可以直接在地址栏输入 chrome://extensions 访问
- 勾选开发者模式,即可以文件夹的形式直接加载插件
功能
自定义
- 插入自定义样式(css代码)
CSDN
- 打开任意一个
CSDN博客即可开始复制代码 - 未登录
CSDN状态下,支持选中代码 - 未登录
CSDN状态下,代码右上角按钮一键复制 - 未登录
CSDN状态下,不会再出现强制登录弹窗 - 未关注博主状态下,不再提示关注博主即可阅读全文,且完整展示文章
- 自动展开代码块
- 移动端屏蔽跳转APP
知乎
- 一键复制代码
- 未登录
知乎状态下,不再提示展开阅读全文,且完整展示文章 - 未登录
知乎状态下,不会再出现强制登录弹窗
简书
- 移动端,一键复制代码
- 不再提示展开阅读全文,且完整展示文章
- 不会再出现强制登录弹窗
脚本之家
- 打开任意一个
脚本之家博客即可开始复制代码 - 未登录
脚本之家状态下,支持选中代码 - 屏蔽广告
- 移动端未登录
脚本之家状态下,代码右上角按钮一键复制
博客园
- 一键复制代码
51CTO博客
- 未登录
51CTO博客状态下,支持选中代码 - 未登录
51CTO博客状态下,代码右上角按钮一键复制 - 未登录
51CTO博客状态下,不会再出现强制登录弹窗 - 移动端未登录
51CTO博客状态下,代码右上角按钮一键复制
php中文网
- 未登录
php中文网状态下,支持选中代码 - 未登录
php中文网状态下,代码右上角按钮一键复制 - 未登录
php中文网状态下,不会再出现强制登录弹窗 - 未登录
php中文网状态下,移动端代码右上角按钮一键复制
原理
这里简要介绍下实现原理。
复制功能
首先不能框选代码的问题比较好解决,因为我发现是 CSS 控制的,我们把代码pre和code标签的user-select样式修改掉。
#content_views pre,
#content_views pre code {
-webkit-touch-callout: auto !important;
-webkit-user-select: auto !important;
-khtml-user-select: auto !important;
-moz-user-select: auto !important;
-ms-user-select: auto !important;
user-select: auto !important;
}
然后处理代码块右上角的复制按钮,在未登陆状态下点击这个复制按钮后会触发登陆弹窗,所以我们从控制 js 入手。
- 找到所有的复制按钮
- 将按钮上的点击事件移除掉,克隆按钮再替回去
- 重新添加点击事件
下面贴一段核心代码
buttons.forEach((btn) => {
// 更改标题
btn.dataset.title = "复制";
// 移除点击事件
btn.setAttribute("onclick", "");
// 克隆按钮
elClone = btn.cloneNode(true);
// 替回按钮
btn.parentNode.replaceChild(elClone, btn);
// 重新添加点击事件
elClone.addEventListener("click", (e) => {
// 实现复制
const parentPreBlock = e.target.closest("pre");
const codeBlock = $$("code", parentPreBlock);
copy(codeBlock.innerText);
e.target.dataset.title = "复制成功";
setTimeout(() => {
e.target.dataset.title = "复制";
}, 1000);
e.stopPropagation();
e.preventDefault();
});
});
去除登陆弹窗
直接将登陆弹窗通过 CSS 隐藏
.passport-login-container {
display: none !important;
}
去除阅读更多提示
- 首先将关注博主即可阅读全文所在的容器去除掉,隐藏或者降低层级都行,我这里用的是降低层级。因为还有个 VIP 文章的拦截容器和这个阅读全文类似,这里需要排除下,所以这里用 js 去添加 CSS 代码
let readMore = document.querySelector(".btn-readmore");
let style = `
.hide-article-box{
z-index: -1 !important;
}
`;
if (readMore) {
addCSS(style);
}
- 再设置
CSS将文章的高度放开
/* 关注博主才能查看文章,开放文章 */
#article_content {
height: auto !important;
}
自动展开代码块
- 首先将查看更多的容器去除掉
- 再设置
CSS将文章的高度放开
const pres = Array.from(
document.querySelectorAll<HTMLElement>(
"main div.blog-content-box pre.set-code-hide"
)
)
const presBox = Array.from(
document.querySelectorAll<HTMLElement>(".hide-preCode-box")
)
const readallBox = document.querySelector<HTMLElement>(".readall_box")
pres.forEach((pre) => {
pre.style.height = "unset"
pre.style.maxHeight = "unset"
})
presBox.forEach((box) => {
box.style.display = "none"
})
if (readallBox) {
const articleContent =
document.querySelector<HTMLElement>(".article_content")
articleContent.style.height = "unset"
readallBox.style.display = "none"
}
总结
因为这款插件的源代码是开放的,完整代码大家可以直接看我的 Github 仓库:
本浏览器插件可以用于CSDN/知乎/脚本之家/博客园/博客园/51CTO博客/php中文网等网站,实现无需登录一键复制代码;支持选中代码;或者代码右上角按钮的一键复制;解除关注博主即可阅读全文提示;去除登录弹窗;去除跳转APP弹窗。功能上已经可以满足要求。可能还有很多不足的地方,大家发现了问题或者有其他需求的话,欢迎向我反馈。