移动安卓端的有些功能藏在菜单里,要划来划去.
就抄了个 js 代码片段放在页面两边,点击弹出对应菜单(太懒了).
不会 js,只能照板煮碗.
本来想抄个按钮代码的,不会改 >_<.
如果用 ai,估计能唰唰就完成了,可惜也不会.
20250316 更新:
一,PC 端在顶栏添加两个按钮,
一个是重载页面.
一个是半成品的复制正文文字内容.
由于个人能力问题,复制正文内容有以下缺点:
1.不知道怎样定位之前打开的页面,只能复制最新打开的页面.如果想复制已打开的页面,请关闭它再重新打开.
2.复制的正文文字内容只能复制已加载的部分,太长的内容由于懒加载原因而未加载的部分请手动加载后再复制.
二,安卓端其中一个按钮也更改为半成品的复制正文文字内容
原代码:
[js] [仅适用于手机端] 一个在锁定编辑旁边可以隐藏一些图标的 js
相关注意项:
1.右边复选框开关我点击的菜单是右边的菜单第一层,
可以自行修改为想运行的代码或相关菜单的 id.
如:#plugin_siyuan-plugins-index_0
2.左边复选框开关我点击的是左边顶层工具栏的插件工具栏里面的一项.
找不到菜单第一层和第二层的 id 和类名,只好用最粗旷的模拟点击.
这个就和主题的按钮大小相关了.
默认主题按钮大概是 43px,
所以插件工具栏(第七个)的 Y 坐标取 280.
43*6=258, 43*7=301
需要修改为你自己想点击的菜单的坐标.
当然,各位大佬直接修改为想运行的代码更直接.
3.坐标也可以用这个小代码来获取.
打开思源浏览器安卓端,按下 F12,在控制台粘贴以下代码,按 Enter
然后点击网页你想点击的地方,就可以得到坐标, ID(如果有)和类名(如果有).
document.addEventListener('click', (e) => {
console.log(e.target);
// 获取点击的坐标
const x = e.clientX;
const y = e.clientY;
// 输出坐标
console.log(`坐标: (${x}, ${y})`);
});
4.左边工具栏第二层菜单生成需要时间,我添加了延时,默认 1500.
你可以根据自己手机性能来调整大小.
第三次点击是根据菜单名字搜索的,
这条代码由 JeffreyChen 大大 请问类名相同, 如何根据文本内容获取元素, 谢谢. 提供,谢谢.
var button003 = Array.from(document.querySelectorAll('span.b3-menu__label')).find(label => label.textContent.includes('基于文档搜索 Dock'));
可以修改自己想点击的菜单名字
如"基于文档搜索 Dock"
5.上面 1,2,4 点在代码里面都有注释.
PC 端复制正文文字内容录屏 gif:
浏览器移动端录屏 gif:
20250316 新版代码:
// 插入开关功能
function insertSwitchBeforeButton() {
// 循环查找目标按钮,直到找到为止
function findAndInsert() {
// 尝试查找目标按钮,仅在符合指定选择器时插入
let barforward_desktop = document.querySelector("#barForward");
let drag_desktop = document.querySelector("#drag");
let spacebar_mobile = document.querySelector('#editor > div.protyle-breadcrumb > span.protyle-breadcrumb__space');
let unlock_mobile = document.querySelector('#editor > div.protyle-breadcrumb > button.protyle-breadcrumb__icon.ariaLabel');
let toolbar = document.querySelector('.toolbar.toolbar--border'); // 查找需要控制的工具栏
let css1 = document.querySelector('#editor > div.protyle-content.protyle-content--transition > div.protyle-top');
if ( barforward_desktop || spacebar_mobile ) {
// 如果找到了目标按钮和工具栏,且符合选择器
let switchElement_desktop01 = document.createElement('input');
switchElement_desktop01.type = 'checkbox'; // 创建一个复选框作为开关
switchElement_desktop01.style.marginRight = '8px'; // 添加样式,调整位置
switchElement_desktop01.checked = false; // 默认是未选中状态,工具栏显示
let switchElement_desktop02 = document.createElement('input');
switchElement_desktop02.type = 'checkbox'; // 创建一个复选框作为开关01
switchElement_desktop02.style.marginLeft = '8px'; // 添加样式,调整位置
switchElement_desktop02.checked = false; // 默认是未选中状态,工具栏显示
let switchElement_mobile01 = document.createElement('input');
switchElement_mobile01.type = 'checkbox'; // 创建一个复选框作为开关
switchElement_mobile01.style.marginRight = '8px'; // 添加样式,调整位置
switchElement_mobile01.checked = false; // 默认是未选中状态,工具栏显示
let switchElement_mobile02 = document.createElement('input');
switchElement_mobile02.type = 'checkbox'; // 创建一个复选框作为开关01
switchElement_mobile02.style.marginLeft = '8px'; // 添加样式,调整位置
switchElement_mobile02.checked = false; // 默认是未选中状态,工具栏显示
// 桌面端开关01的点击事件,用来控制工具栏和按钮的显示和隐藏
switchElement_desktop01.addEventListener('change', () => {
if (switchElement_desktop01.checked) {
//下面可以修改为想运行的代码
copyAreaContent();
//上面是想运行的代码
setTimeout(() => {
switchElement_desktop01.checked = false;
}, 500);
}
});
// 桌面端开关02的点击事件,用来控制工具栏和按钮的显示和隐藏
switchElement_desktop02.addEventListener('change', () => {
if (switchElement_desktop02.checked) {
//下面可以修改为想运行的代码
refresh01();
//上面是想运行的代码
setTimeout(() => {
switchElement_desktop02.checked = false;
}, 500);
}
});
// 移动端开关01的点击事件,用来控制工具栏和按钮的显示和隐藏
switchElement_mobile01.addEventListener('change', () => {
if (switchElement_mobile01.checked) {
//下面可以修改为想运行的代码
copyAreaContent();
//上面是想运行的代码
setTimeout(() => {
switchElement_mobile01.checked = false;
}, 500);
}
});
// 移动端开关02的点击事件,用来控制工具栏和按钮的显示和隐藏
switchElement_mobile02.addEventListener('change', () => {
if (switchElement_mobile02.checked) {
//下面可以修改为想运行的代码
small_notes_sidebar();
//上面是想运行的代码
setTimeout(() => {
switchElement_mobile02.checked = false;
}, 500);
}
});
// 插入开关到按钮前面
if (barforward_desktop) {
// 桌面端
barforward_desktop.parentNode.insertBefore(switchElement_desktop01, drag_desktop);
console.log("桌面端开关01已成功插入到目标按钮前面");
barforward_desktop.parentNode.insertBefore(switchElement_desktop02, barforward_desktop);
console.log("桌面端开关02已成功插入到目标按钮前面");
} else {
// 移动端
spacebar_mobile.parentNode.insertBefore(switchElement_mobile01, unlock_mobile);
console.log("移动端开关01已成功插入到目标按钮前面");
spacebar_mobile.parentNode.insertBefore(switchElement_mobile02, spacebar_mobile);
console.log("移动端开关02已成功插入到目标按钮前面");
}
// 停止查找
clearInterval(searchInterval);
} else {
console.warn("目标按钮或工具栏未找到,继续尝试...");
}
}
// 每隔 1000 毫秒查找一次目标按钮和工具栏
let searchInterval = setInterval(findAndInsert, 1000);
// 如果超过 10 秒仍未找到,停止查找并提示
setTimeout(() => {
clearInterval(searchInterval);
console.error("超过 2 秒仍未找到目标按钮或工具栏,请检查选择器或页面是否正确加载");
}, 2000); // 2 秒后停止查找
}
// 启动插入开关功能
insertSwitchBeforeButton();
//以下是点击按钮实现的4个效果
//效果1,重置刷新页面
function refresh01() {
//重置刷新页面
window.location.reload();
}
//效果2,小记弹出新建窗口(安卓端)
function small_notes() {
这里是点击右边的顶层菜单项
window.location.reload(); //这个是重置页面
获取元素
let button001 = document.querySelector('#plugin_quick-notes_0');
触发点击事件
button001.click();
console.log("小记弹出新建窗口成功");
}
//效果3,显示小记侧边栏(安卓端)
function small_notes_sidebar() {
//这里是运行左边顶部工具栏插件按钮第二层的显示侧边栏
//第二次点击的坐标x2,y2要根据主题来修改
// 定义我们要点击的坐标1
const x1 = 10;
const y1 = 10;
// 获取指定坐标上的元素
const el = document.elementFromPoint(x1, y1);
const click01 = (x1, y1) => {
const ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x1,
'screenY': y1
});
// 分发点击事件
el.dispatchEvent(ev);
};
// 调用点击函数
click01(x1, y1);
console.log(el);
setTimeout(() => {
// 定义我们要点击的坐标2
const x2 = 260; //默认主题顶部工具栏插件按钮的坐标为280
const y2 = 20;
// 获取指定坐标上的元素
const e2 = document.elementFromPoint(x2, y2);
const click02 = (x2, y2) => {
const ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x2,
'screenY': y2
});
// 分发点击事件
e2.dispatchEvent(ev);
};
// 调用点击函数
click02(x2, y2);
console.log(e2);
}, 500);
setTimeout(() => {
var button003 = Array.from(document.querySelectorAll('span.b3-menu__label')).find(label => label.textContent.includes('显示小记侧边栏'));
button003.click();
console.log("小记侧边栏已显示");
}, 1500); //这里的延迟时间看手机性能,性能不够的可以调大一些
}
//效果4,半成品复制正文文字
function copyAreaContent() {
// 1. 获取目标元素
let targetElement_mobile = document.querySelector('#editor > div.protyle-content.protyle-content--transition > div.protyle-wysiwyg.protyle-wysiwyg--attr');
let targetElement_desktop = Array.from(document.getElementsByClassName('protyle-wysiwyg--attr'));
let i001 = targetElement_desktop.length-1;
let targetElement = (targetElement_desktop[i001] || targetElement_mobile);
// 2. 创建选区(Range)
const range = document.createRange();
range.selectNodeContents(targetElement);
// 3. 将选区添加到 Selection 对象
const selection = window.getSelection();
selection.removeAllRanges(); // 清除现有选区
selection.addRange(range);
try {
// 4. 复制内容到剪贴板(现代浏览器推荐 Clipboard API)
//if (navigator.clipboard) {
let textArea = document.createElement("textarea");
str01 = selection.toString().replace(//g,"");
textArea.value = str01;
// 使text area不在viewport,同时设置不可见
textArea.style.position = "absolute";
textArea.style.opacity = 0;
textArea.style.left = "-999999px";
textArea.style.top = "-999999px";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
return new Promise((res, rej) => {
// 执行复制命令并移除文本框
document.execCommand('copy') ? res() : rej();
textArea.remove();
console.log("内容已复制");
});
//} else {
// // 旧浏览器回退到 execCommand
// document.execCommand("copy");
// console.log("内容已复制(旧浏览器方式)");
//}
} catch (err) {
console.error("复制失败:", err);
}
// 5. 清除选区(可选)
selection.removeAllRanges();
}
旧版代码:
// 插入开关功能
function insertSwitchBeforeButton() {
// 循环查找目标按钮,直到找到为止
function findAndInsert() {
// 尝试查找目标按钮,仅在符合指定选择器时插入
let targetButton = document.querySelector('#editor > div.protyle-breadcrumb > button.protyle-breadcrumb__icon.ariaLabel');
let targetButton01 = document.querySelector('#editor > div.protyle-breadcrumb > span.protyle-breadcrumb__space');
let toolbar = document.querySelector('.toolbar.toolbar--border'); // 查找需要控制的工具栏
let css1 = document.querySelector('#editor > div.protyle-content.protyle-content--transition > div.protyle-top');
if (targetButton && toolbar) {
// 如果找到了目标按钮和工具栏,且符合选择器
let switchElement = document.createElement('input');
switchElement.type = 'checkbox'; // 创建一个复选框作为开关
switchElement.style.marginRight = '8px'; // 添加样式,调整位置
switchElement.checked = false; // 默认是未选中状态,工具栏显示
let switchElement01 = document.createElement('input');
switchElement01.type = 'checkbox'; // 创建一个复选框作为开关01
switchElement01.style.marginLeft = '8px'; // 添加样式,调整位置
switchElement01.checked = false; // 默认是未选中状态,工具栏显示
// 开关的点击事件,用来控制工具栏和按钮的显示和隐藏
switchElement.addEventListener('change', () => {
if (switchElement.checked) {
//下面可以修改为想运行的代码
//这里是点击右边的顶层菜单项
//window.location.reload(); //这个是重置页面
// 获取元素
let button001 = document.querySelector('#plugin_siyuan-plugins-index_0');//修改为想点击的菜单id
// 触发点击事件
button001.click();
//上面是想运行的代码
switchElement.checked = false;
console.log("文档目录已更新");
}
});
// 开关01的点击事件,用来控制工具栏和按钮的显示和隐藏
switchElement01.addEventListener('change', () => {
if (switchElement01.checked) {
//下面可以修改为想运行的代码
//这里是运行左边顶部工具栏插件按钮第二层的显示侧边栏
//第二次点击的坐标x2,y2要根据主题来修改
// 定义我们要点击的坐标1
const x1 = 10;
const y1 = 10;
// 获取指定坐标上的元素
const el = document.elementFromPoint(x1, y1);
const click01 = (x1, y1) => {
const ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x1,
'screenY': y1
});
// 分发点击事件
el.dispatchEvent(ev);
};
// 调用点击函数
click01(x1, y1);
console.log(el);
setTimeout(() => {
// 定义我们要点击的坐标2
const x2 = 280; //默认主题顶部工具栏插件按钮的坐标为280
const y2 = 20;
// 获取指定坐标上的元素
const e2 = document.elementFromPoint(x2, y2);
const click02 = (x2, y2) => {
const ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x2,
'screenY': y2
});
// 分发点击事件
e2.dispatchEvent(ev);
};
// 调用点击函数
click02(x2, y2);
console.log(e2);
}, 500);
setTimeout(() => {
var button003 = Array.from(document.querySelectorAll('span.b3-menu__label')).find(label => label.textContent.includes('基于文档搜索 Dock'));
button003.click();
}, 1500); //这里的延迟时间看手机性能,性能不够的可以调大一些
//上面是想运行的代码
switchElement01.checked = false;
console.log("文档搜索");
}
});
// 插入开关到按钮前面
targetButton.parentNode.insertBefore(switchElement, targetButton);
console.log("开关已成功插入到目标按钮前面");
targetButton01.parentNode.insertBefore(switchElement01, targetButton01);
console.log("开关01已成功插入到目标按钮前面");
// 停止查找
clearInterval(searchInterval);
} else {
console.warn("目标按钮或工具栏未找到,继续尝试...");
}
}
// 每隔 1000 毫秒查找一次目标按钮和工具栏
let searchInterval = setInterval(findAndInsert, 1000);
// 如果超过 10 秒仍未找到,停止查找并提示
setTimeout(() => {
clearInterval(searchInterval);
console.error("超过 2 秒仍未找到目标按钮或工具栏,请检查选择器或页面是否正确加载");
}, 2000); // 2 秒后停止查找
}
// 启动插入开关功能
insertSwitchBeforeButton();
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于