一个浮窗设置面板
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greatest.deepsurf.us/scripts/534265/1579393/UserPanel.js
const createPanel = function () {
// 创建宿主元素
const container = document.createElement("div");
container.id = "scriptSettings";
// 创建 shadowRoot
const shadowRoot = container.attachShadow({ mode: "open" });
// 插入样式和内容
shadowRoot.innerHTML = `
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.float-ball {
position: fixed;
right: 10px;
top: 80%;
transform: translateY(-50%);
width: 40px;
height: 40px;
background: #4a90e2;
border-radius: 50%;
cursor: pointer;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.float-ball:hover {
background: #357abd;
transform: translateY(-50%) scale(1.1);
}
.float-ball.active {
transform: translateY(-50%) rotate(0deg);
}
.menu-panel {
position: absolute;
right: 60px;
top: 50%;
transform: translateY(-50%) scale(0);
transform-origin: right center;
width: 200px;
background: white;
border-radius: 12px;
padding: 16px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
opacity: 0;
transition: all 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
}
.float-ball.active .menu-panel {
transform: translateY(-50%) scale(1);
opacity: 1;
}
.menu-item {
margin: 12px 0;
display: flex;
align-items: center;
justify-content: space-between;
}
.switch {
width: 40px;
height: 24px;
background: #ddd;
border-radius: 12px;
position: relative;
cursor: pointer;
transition: all 0.3s ease;
}
.switch.active {
background: #4a90e2;
}
.switch::after {
content: "";
position: absolute;
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
top: 2px;
left: 2px;
transition: all 0.3s ease;
}
.switch.active::after {
left: 18px;
}
.input-field {
width: 100%;
padding: 6px 12px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 14px;
transition: all 0.3s ease;
box-shadow: inset -1px -1px 1px 0px #357abd8c;
cursor: pointer;
caret-color: transparent; /* 隐藏光标 */
}
.input-field:focus {
outline: none;
border-color: #4a90e2;
box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
}
.icon {
width: 24px;
height: 24px;
fill: white;
}
</style>
<div class="float-ball">
<svg class="icon" viewBox="0 0 24 24">
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z" />
</svg>
<div class="menu-panel">
<div class="menu-item">
<span>点赞</span>
<div class="switch like-switch"></div>
</div>
<div class="menu-item collect-switch">
<span>收藏</span>
<div class="switch"></div>
</div>
<input type="text" class="input-field" placeholder="粘贴接口地址" />
</div>
</div>
`;
// 获取切换按钮(switch)
const likeSwitch = shadowRoot.querySelector(".like-switch");
const collectSwitch = shadowRoot.querySelector(".collect-switch");
// 初始化按钮状态(status)
function initializeSwitches() {
// 从 GM_getValue 获取状态并更新开关状态
const likeStatus = GM_getValue("likeStatus", false); // 默认值为 false
const collectStatus = GM_getValue("collectStatus", false); // 默认值为 false
// 设置初始状态
if (likeStatus !== null) {
likeSwitch.classList.toggle("active", likeStatus);
}
if (collectStatus !== null) {
collectSwitch.classList.toggle("active", collectStatus);
}
}
// 绑定切换事件(event)
likeSwitch.addEventListener("click", (event) => {
// 阻止点击事件冒泡
event.stopPropagation();
const currentStatus = likeSwitch.classList.contains("active");
const newStatus = !currentStatus;
// 切换按钮状态
likeSwitch.classList.toggle("active", newStatus);
// 保存新的状态到 GM
GM_setValue("likeStatus", newStatus);
});
collectSwitch.addEventListener("click", (event) => {
// 阻止点击事件冒泡
event.stopPropagation();
const currentStatus = collectSwitch.classList.contains("active");
const newStatus = !currentStatus;
// 切换按钮状态
collectSwitch.classList.toggle("active", newStatus);
// 保存新的状态到 GM
GM_setValue("collectStatus", newStatus);
});
// 初始化页面加载时的状态
initializeSwitches();
// 打开或关闭菜单(menu)
floatBall.addEventListener("click", function (event) {
this.classList.toggle("active");
});
// 为悬浮球和开关添加事件
const floatBall = shadowRoot.querySelector(".float-ball");
// 点击页面其他地方时关闭菜单
floatBall.addEventListener("click", function () {
floatBall.classList.remove("active");
});
// 获取 input 元素
const inputField = shadowRoot.querySelector(".input-field");
// 设置 URL 默认值(可以从 GM_getValue 获取已存储的 URL)
const defaultURL = GM_getValue("storedURL", "");
// 初始化 input 的值
inputField.value = defaultURL;
// 绑定点击事件,点击时粘贴剪贴板的 URL 到 input 中
inputField.addEventListener("click", function () {
// 使用 Clipboard API 来获取剪贴板内容
navigator.clipboard
.readText()
.then((text) => {
inputField.value = text; // 将剪贴板中的 URL 填充到 input 中
GM_setValue("storedURL", text); // 存储该 URL
})
.catch((err) => {
console.error("无法读取剪贴板内容:", err);
});
});
return container;
};