mylib

我的工具

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.greasyfork.org/scripts/435697/1428275/mylib.js

// ==UserScript==
// @name mylib
// @description 我的工具
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
;(function(win){
    const My =function(){//构造函数,需配合实例方法,与this,prototype有关
        const e=document.documentElement.firstElementChild,sv=GM_setValue,gv=GM_getValue;
        if(e.tagName==='Z'){
            win.myzone=e;
            win.mybtns=e.querySelector('my-btns');
        }else {
            win.cl=win.console.log;win.al=win.alert; // win.gv=gv;win.sv=sv
            win.myzone=e.mbefore('z','',`class`,'rwf');
            win.myaddStyle(`.my-a{border-style: inset!important;}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.mappend('my-btns','',`class`,'rwf');
            if(!gv('fixbar',0)||win.top!==win.self){//如果不固定,或在iframe
                Element.prototype.mbindDrag(win.mybtns);
            }
            if(win.top===win.self){
                win.mybtns.onmouseup=e=>{
                    sv('left',win.mybtns.style.left);
                    sv('top',win.mybtns.style.top);
                }
            }
            win.mybtns.style.left=gv('left',0);
            win.mybtns.style.top=gv('top',0);
            win.myaddBtns(function 拽(){}).children[0].oncontextmenu=e=>{//右键 固定/不固定 按钮组
                e.preventDefault();//取消默认
                sv('fixbar',gv('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.mappend('style',css,`class`,className);
    }
    Element.prototype.mappend = function(tagName, innerHTML, ...attributes) {//z.mappend('x','content','idk','true','data-s').on("click",()=>{alert(1)}).mappend('y','test','idk','true','data-s')
        const ele = document.createElement(tagName);
        ele.innerHTML = innerHTML;
        for (let i = 0; i < attributes.length; i += 2) ele.setAttribute(attributes[i], attributes[i + 1]);
        this.appendChild(ele);
        ele.on = function (event, handler) {
            this.addEventListener(event, handler);
            return this; // 支持链式调用
        };
        return ele;
    }
    Element.prototype.mafter = function(tagName, innerHTML, ...attributes) {
        const ele = document.createElement(tagName);
        ele.innerHTML = innerHTML;
        for (let i = 0; i < attributes.length; i += 2) ele.setAttribute(attributes[i], attributes[i + 1]);
        this.after(ele);
        ele.on = function(event, handler) {
            this.addEventListener(event, handler);
            return this; // 支持链式调用
        };
        return ele;
    }
    win.Element.prototype.mbefore = function(tagName, innerHTML, ...attributes) {
        const ele = document.createElement(tagName);
        ele.innerHTML = innerHTML;
        for (let i = 0; i < attributes.length; i += 2) ele.setAttribute(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.mappend('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) => {//my.addAs("https://www.bilibili.com/","https://www.baidu.com/")
        return urls.forEach(url=>{
            const u=new URL(url);
            win.mybtns.mappend('a','iframe',`href`,url,'class','my-a my-btn');
        });
    }
    Element.prototype.mbindDrag=(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.mywaitForElement=(selector,timeout=3e4)=>{//查找ele.30000
        return new Promise((resolve, reject) => {
            const intervalTime=500;
            const startTime=Date.now();
            const 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.mywaitForElements=(selector,timeout=3e4)=>{//查找eles
        return new Promise((resolve, reject) => {
            const intervalTime=500,startTime=Date.now(),interval=setInterval(() => {
                const elements=document.querySelectorAll(selector);
                if (elements) {
                    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);