快捷便笺+:一个快速记录信息的浏览器扩展
// ==UserScript== // @name 快捷便笺+ // @namespace kjnote Scripts // @author Takitooru // @match :///* // @version 1.1.0.5 // @description 快捷便笺,快速记录所需信息 // @license GPL License // @grant GM_getValue // @grant GM_setValue // @grant GM_addValueChangeListener // @grant GM_addStyle // @grant GM_addElement // @noframes // ==/UserScript==
(function() { // 给该脚本创建一个随机的ID const RndToken = ({ TOKEN_LIST:['ContainerID', 'ContainerCSSOpen'], init() { this.TOKEN_LIST.forEach((name) => (this[name] = randstr(16, false, true))); return this; } }).init();
// CSS和HTML的常量
const CONST = {
CSS: {
outer: replaceText(
`#{ContainerID}{width:20px;border:1px solid #70ae2d;position:fixed;top:2px;right:0px;z-index:999999999999999999999;background-color:#8bc34a;color:#fff;border-radius:3px;font:initial;opacity:0.5;transition-duration: 0.3s;}
#{ContainerID}:hover, #{ContainerID}.{ContainerCSSOpen}{opacity:1;}`,
{'{ContainerID}': RndToken.ContainerID, '{ContainerCSSOpen}': RndToken.ContainerCSSOpen}
),
inner: `.kjbtn{display: inline-block;text-align: center;cursor:pointer;user-select:none;}
.boxhide{display: none;position:fixed;z-index:998;padding:3px;border-radius:3px;}
.jstoolbar{color:#000;display:block;border-bottom:1px solid #ddd;background-color:#eeeeee;padding:10px 0 10px 0;}
.slider{display:inline-block;font-size:13px}.sliderinput{vertical-align:middle;}
.sclose{margin-right: 10px;font-size: 14px;text-align: center;font-weight:bold;color:black;width:20px;float:left;cursor:pointer;}
.savetxt{width:80px;float:right;background-color:#8bc34a;border-radius:3px;color:#fff;padding:2px;font-size: 14px;text-align: center;cursor:pointer;margin-right:1em;}
.stextarea{background-color: #eeeeee;margin: 0;padding: 5px 0 0 0;height: 200px;width: 350px;color: #000;font-size: 15px;resize: vertical;outline:none;border: none;scrollbar-width: thin;}.stextarea:focus{border: none;box-shadow: none;}
.stextarea::-webkit-scrollbar {width: 5px;height: 5px;}.stextarea::-webkit-scrollbar-thumb {border-radius: 3px;-webkit-border-radius: 3px;background-color: #8bc34a;}.stextarea::-webkit-scrollbar-track {background-color: transparent;}`
},
HTML: {
all: `<span class="kjbtn">快捷便笺+</span>
<div class="boxhide"><div class="jstoolbar"><div class="sclose">X</div>
<div class="slider">透明度:<input class="sliderinput" type="range" min="30" max="100" step="1" value="100"></div>
<div class="savetxt">保存为txt</div>
</div><textarea class="stextarea"></textarea></div>`
}
};
// 创建一个div元素
const Newdiv = document.createElement("div");
Newdiv.id = RndToken.ContainerID;
stopPropagation(Newdiv, ['click', 'dblclick', 'input', 'change', 'focus', 'blur', 'copy', 'paste', 'contextmenu', 'drag', 'mouseenter', 'mousemove', 'mouseover', 'mouseleave', 'mousedown', 'keydown', 'keyup', 'keypress']);
const shadow = Newdiv.attachShadow({mode: 'closed'});
shadow.innerHTML = CONST.HTML.all;
document.body.appendChild(Newdiv);
// 添加CSS样式
GM_addStyle(CONST.CSS.outer);
GM_addElement(shadow, 'style', {textContent: CONST.CSS.inner});
// 获取各个DOM元素
const boxname = $(shadow, ".boxhide");
const kjbtn = $(shadow, ".kjbtn");
const close = $(shadow, ".sclose");
const input = $(shadow, ".stextarea");
const savetxt = $(shadow, ".savetxt");
const opacity2t = $(shadow, ".sliderinput");
// 绑定事件
kjbtn.addEventListener('click', e => e.preventDefault() || e.stopImmediatePropagation() || [...Newdiv.classList].includes(RndToken.ContainerCSSOpen) ? hide() : show(), {capture: true});
close.onclick = hide;
input.oninput = save;
input.value = GM_getValue('text', '');
// 监听GM的值变化
if (typeof GM_addValueChangeListener === 'function') {
GM_addValueChangeListener('text', function(name, old_value, new_value, remote) {
remote && (input.value = new_value);
});
} else {
setInterval(function() {
input.value = GM_getValue('text', '');
}, 500);
}
savetxt.addEventListener("click",function(e) {
Val2txt();
});
opacity2t.addEventListener("input",function(e) {
o2t(this);
});
function show() {
Newdiv.classList.add(RndToken.ContainerCSSOpen);
boxname.style.display = "block";
boxname.style.top = "2px";
boxname.style.right = (Newdiv.clientWidth + 2) + "px";
}
function hide() {
Newdiv.classList.remove(RndToken.ContainerCSSOpen);
boxname.style = null;
}
function save() {
GM_getValue('text', '') !== input.value && GM_setValue('text', input.value);
}
function Val2txt() {
const Filename = new Date().getTime();
const TextContent = input.value;
const Addele = document.createElement('a');
Addele.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(TextContent));
Addele.setAttribute('download', Filename);
const jset = document.createEvent('MouseEvents');
jset.initEvent('click', true, true);
Addele.dispatchEvent(jset);
}
function o2t(vv) {
input.style.opacity = vv.value / 100;
}
function stopPropagation(elm, evtName) {
Array.isArray(evtName) ? evtName.forEach(name => stopPropagation(elm, name)) : elm.addEventListener(evtName, e => e.stopPropagation());
}
// 下面是一些基础的函数
// querySelector
function $() {
switch(arguments.length) {
case 2:
return arguments[0].querySelector(arguments[1]);
break;
default:
return document.querySelector(arguments[0]);
}
}
// querySelectorAll
function $All() {
switch(arguments.length) {
case 2:
return arguments[0].querySelectorAll(arguments[1]);
break;
default:
return document.querySelectorAll(arguments[0]);
}
}
// createElement
function $CrE
原文地址: https://www.cveoy.top/t/topic/nsOt 著作权归作者所有。请勿转载和采集!