//==UserScript==
// @name mylib
// @description 我的工具
// @grant GM_setValue
// @grant GM_getValue
// @grant GM.xmlHttpRequest
//==/UserScript==
;(function(win){
const My=function(){//构造函数,需配合实例方法,与this,prototype有关
const head=document.documentElement.firstElementChild,gsv=GM_setValue,ggv=GM_getValue,gxhr=GM.xmlHttpRequest;
if(head.tagName==='Z'){
win.myzone=head;
win.mybtns=head.querySelector('my-btns');
}else{
win.al=win.alert;
win.cl=win.console.log;
win.myzone=head.mybefore('z','',`class`,'rwf');
win.myaddstyle(`.my-a{border: 1px solid black!important;font-size: medium;}my-btns{display:block;z-index:9195129;position:fixed;height: min-content;}.my-btn{user-select: none;font-size: initial!important;}`,'my-btns');
win.mybtns=win.myzone.myappend('my-btns','',`class`,'rwf');
if(!ggv('fixbar',0)||win.top!==win.self) Element.prototype.mybinddrag(win.mybtns);//如果不固定,或在iframe
if(win.top===win.self){
win.mybtns.onmouseup=e=>{
gsv('left',win.mybtns.style.left);
gsv('top',win.mybtns.style.top);
}
}
win.mybtns.style.left=ggv('left',0);
win.mybtns.style.top=ggv('top',0);
win.myaddbtns(function 拽(){}).children[0].oncontextmenu=e=>{//右键 固定/不固定 按钮组
e.preventDefault();//取消默认
gsv('fixbar',ggv('fixbar')?0:1);
location.reload();
}
}
return My;
}
//My.静态方法 My.prototype实例方法(如本案例中my.prototype.constructor.toString())
// My.prototype.test1=function(){}
// My.test2=function(){}
win.myaddstyle=function(css,className='rwf'){//function和lambda this指向不同,后者没有prototype、arguments,后者不能new/作为构造函数,
return win.myzone.myappend('style',css,`class`,className);
}
Element.prototype.myappend=function(tagName,innerHTML,...attributes){//z.myappend('x','content','idk','true','data-s').on("click",()=>{alert(1)}).myappend('y','test','idk','true','data-s')
const ele=document.createElement(tagName);
ele.innerHTML=innerHTML;
for(let i=0;i<attributes.length;i+=2) ele[attributes[i]]=attributes[i+1];
this.appendChild(ele);
ele.on=function (event,handler){
this.addEventListener(event,handler);
return this; // 支持链式调用
};
return ele;
}
Element.prototype.myafter=function(tagName,innerHTML,...attributes){
const ele=document.createElement(tagName);
ele.innerHTML=innerHTML;
for(let i=0;i<attributes.length;i+=2) ele[attributes[i]]=attributes[i+1];
this.after(ele);
ele.on=function(event,handler){
this.addEventListener(event,handler);
return this; // 支持链式调用
};
return ele;
}
win.Element.prototype.mybefore=function(tagName,innerHTML,...attributes){
const ele=document.createElement(tagName);
ele.innerHTML=innerHTML;
for(let i=0;i<attributes.length;i+=2) ele[attributes[i]]=attributes[i+1];
this.before(ele);
ele.on=function(event,handler){
this.addEventListener(event,handler);
return this; // 支持链式调用
};
return ele;
}
win.myaddbtns=(...args)=>{//my.addBtns(()=>{},e=>{confirm(e.target.id)},function(e){prompt(e.target.outerHTML)},function test(e){return 1})
const len=args.length;
for(let i=0;i<len;i++){
const btn=win.mybtns.myappend('input','',`type`,'button','class','my-btn','value',args[i].name);
btn.addEventListener('click',args[i]);
}
return win.mybtns;
}
win.myeods=()=>{//enable or disable style in win.myzone
win.myzone.querySelectorAll('style').forEach(e=>{
e.type==='0'?e.type='':0
});
}
win.mysohe=(...args)=>{//show or hide elements
return args.forEach(e=>{
if(typeof e!=="string") e.style.display==='none'?e.style.display='initial':'none';
else{
document.querySelectorAll(e).forEach(e=>{
e.style.display==='none'?e.style.display='initial':'none'
});
}
});
}
win.mys2d=(seconds)=>{//seconds2date//my.s2d(new Date().getTime())
const date=new Date(seconds),year=date.getFullYear(),month=date.getMonth()+1,day=date.getDate(),
hour=date.getHours(),minute=date.getMinutes(),second=date.getSeconds(),milliseconds=date.getMilliseconds(),currentTime=year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second+":"+milliseconds;
return currentTime;
}
win.mytieba=(uname,pwd)=>{
document.querySelector('[name="userName"]').value=uname;
document.querySelector('[name="password"]').value=pwd;
return document.querySelector('[value="登录(不可用)"]').click();
}
win.myfixtitle=()=>{//disable title change
Object.defineProperty(document,"title",{
writable:false
});
}
win.myaddas=(...urls)=>{//myaddas("https://www.bilibili.com/","https://www.baidu.com/")
urls.forEach(url=>{
gxhr({
url:url
}).then(resp=>resp.responseText).then(html=>{
const parser=new DOMParser(),doc=parser.parseFromString(html,'text/html'),title=doc.title,u=new URL(url);
win.mybtns.myappend('a',title,'href',u.href,`className`,'my-a my-btn');
}).catch(err=>win.cl(err));
});
}
Element.prototype.mybinddrag=(ele)=>{//鼠标拖动
ele.onmousedown=function(ev){//if(ev.target.tagName==='TEXTAREA') return;
const diffX=ev.clientX-ele.offsetLeft,diffY=ev.clientY-ele.offsetTop,iw=win.innerWidth,ih=win.innerHeight;
document.onmousemove=function(ev){
let moveX=ev.clientX-diffX,moveY=ev.clientY-diffY;
moveX<0?moveX=0:moveX>iw-ele.offsetWidth?moveX=iw-ele.offsetWidth:0
moveY<0?moveY=0:moveY>ih-ele.offsetHeight?moveY=ih-ele.offsetHeight:0;
ele.style.left=moveX/iw*100+'%'//moveX + 'px';
ele.style.top=moveY/ih*100+'%'//moveY + 'px'
}
document.onmouseup=function(ev){
this.onmousemove=null;
this.onmouseup=null;
}
}
}
win.mysleep=time=>{
return new Promise((resolve)=> setTimeout(resolve,time));
}
win.mywaitele=(selector,timeout=3e4)=>{//查找ele.30000
return new Promise((resolve,reject)=>{
const intervalTime=500,startTime=Date.now(),interval=setInterval(()=>{
const element=document.querySelector(selector);
if (element){
clearInterval(interval);
resolve(element);//找到则返回函数
} else if (Date.now() - startTime > timeout){
clearInterval(interval);
reject(`Timeout waiting for element ${selector}`);//超时则返回字符串
}//继续寻找
},intervalTime);
});
}
win.mywaiteles=(selector,timeout=3e4)=>{//查找eles
return new Promise((resolve,reject)=>{
const intervalTime=500,startTime=Date.now(),interval=setInterval(()=>{
const elements=document.querySelectorAll(selector);
if (elements.length>0){
clearInterval(interval);
resolve(elements);//找到则返回函数
} else if (Date.now() - startTime > timeout){
clearInterval(interval);
reject(`Timeout waiting for element ${selector}`);//超时则返回字符串
}//继续寻找
},intervalTime);
});
}
win.my=new My();
})(window.unsafeWindow);