// ==UserScript==
// @name js-domExtend
// @namespace http://tampermonkey.net/
// @version 1.2
// @description 轻量级原生js增强插件,将部分原生dom对象方法模仿jQuery进行二次封装,便于使用
// @author tutu辣么可爱
// @dayr 2022.4.27 GMT+0800 (中国标准时间)
// @license MIT License
// ==/UserScript==
/*
*function $ele(dom, dom2)
*parameter0 dom:需要创建的dom对象的html字符串或者选择器字符串
*parameter1 dom2:选择器模式时生效,选择器的父节点,默认值document
*return:dom对象或nodeList对象
*note:本质是对createElement、querySelectorAll的二次封装,使用体验类似jQuery的$()方法
*
*function $eleFn(dom, dom2)
*parameter0 dom:选择器字符串
*parameter1 dom2:选择器的父节点,默认值document
*return:一组方法
*note:选择dom对象并执行一些特殊方法。具体用法见$eleFn.listen和$eleFn.ready部分
*
*function $eleFn.listen(callback, interval)
*parameter0 callback:对dom对象监控时,循环执行的回调方法
*parameter1 interval:dom对象的监控时间间隔,默认值500
*return:定时器ID
*note:本质是调用setInterval不断执行$ele方法检测dom对象是否存在
*
*function $eleFn.ready(callback, interval)
*parameter0 callback:dom对象检测到存在时的回调方法
*parameter1 timeout:dom对象存在性检测的超时时长
*return:定时器ID
*note:本质是调用$eleFn.listen检测对象是否存在,setTimeout控制超时时长
*
*function DOM.attr(key, val)
*parameter0 key:dom对象属性名
*parameter1 val:dom对象属性值
*return:对应属性名的值或者原dom对象本身
*note:没有val则返回对应属性名的值;有val则进行属性设置,返回dom对象本身,支持nodeList对象。本质是对getAttribute、setAttribute、removeAttribute的二次封装,使用体验类似jQuery的$.attr方法
*
*function DOM.css(key, val)
*parameter0 key:dom对象css样式属性名
*parameter1 val:dom对象css样式属性值
*return:对应属性名的值或者原dom对象本身
*note:没有val则返回对应属性名的值;有val则进行属性设置,返回dom对象本身,支持nodeList对象。本质是对getComputedStyle、DOM.style.setProperty的二次封装,使用体验类似jQuery的$.css方法
*
*function DOM.hide()
*return:原dom对象本身
*note:调用DOM.css隐藏dom对象,支持nodeList对象。本质是将dom对象样式display设置为none,使用体验类似jQuery的$.hide方法
*
*function DOM.show()
*return:原dom对象本身
*note:调用DOM.css显示dom对象,支持nodeList对象。本质是将dom对象样式display还原为原属性值,使用体验类似jQuery的$.show方法
*
*function DOM.insert(dom, position, reNew)
*parameter0 dom:选择器字符串、dom对象、nodeList对象或多个dom对象组成的Array数组
*parameter1 position:插入位置,默认值end
*parameter2 reNew:返回值类型。布尔型可选参数,默认值false。true表示返回插入的dom对象、nodeList对象或dom对象构成的Array数组; false表示返回原dom对象本身
*return:原dom对象本身、插入的新dom对象、新nodeList对象或新dom对象构成的Array数组
*note:position为start时,插入到父节点(原dom对象)开头;position为end时,插入到父节点(原dom对象)结尾;position为before时,插入到dom节点(原dom对象)前面;position为after时,插入到dom节点(原dom对象)后面。本质是对insertBefore、append的二次封装
*
*function DOM.replace(dom)
*parameter dom:选择器字符串、dom对象或多个dom对象组成的Array数组
*return:新dom对象
*note:本质是调用DOM.insert后将原dom节点remove
*
*/
function $ele(dom, dom2 = document) {
switch (dom.slice(0, 1)) {
case "<":
dom2 = document.createElement("div");
dom2.innerHTML = dom;
dom2 = dom2.childNodes;
break;
default:
dom2 = dom2.querySelectorAll(dom);
break;
}
return dom2.length > 1 ? dom2 : dom2[0]
}
function $eleFn(dom, dom2 = document) {
return {
data: [dom, dom2],
listen: function(callback, interval = 500) {
var that = this;
return setInterval(() => {
if ($ele(that.data[0], that.data[1])) {
callback();
}
}, interval)
},
ready: function(callback, timeout = 3000) {
var timer = this.listen(() => {
clearInterval(timer);
callback();
})
setTimeout(() => {
clearInterval(timer);
}, timeout)
return timer
}
}
}
HTMLElement.prototype.attr = function(key, val) {
if (typeof key === "string") {
if (/string|boolean/.test(typeof val)) {
if (!val && val !== false) {
this.removeAttribute(key);
} else {
this.setAttribute(key, val);
}
return this;
} else {
return this.getAttribute(key);
}
}
}
HTMLElement.prototype.css = function(key, val) {
if (typeof key === "string") {
if (/string|boolean/.test(typeof val)) {
this.style.setProperty(key, val);
} else if (!val) {
return getComputedStyle(this)[key];
}
} else {
for (let i in key) {
this.style.setProperty(i, key[i]);
}
}
if (this.style === "") {
this.attr("style", "")
}
return this;
}
HTMLElement.prototype.hide = function() {
this.setAttribute("display_backup", this.css("display"));
this.css("display", "none")
return this;
}
HTMLElement.prototype.show = function() {
var backup = this.attr("display_backup") ? this.attr("display_backup") : "";
this.css("display", backup !== "none" ? backup : "");
return this;
}
HTMLElement.prototype.insert = function(dom, position = "end",reNew=false) {
dom = typeof dom === "string" ? $ele(dom) : dom;
dom = (Array.isArray(dom)||dom instanceof NodeList) ? dom : [dom];
switch (position) {
case "start":
Array.from(dom).reverse().forEach((e, i) => {
this.insertBefore(e, this.firstChild);
})
break;
case "end":
dom.forEach((e, i) => {
this.append(e);
})
break;
case "before":
Array.from(dom).reverse().forEach((e, i) => {
this.parentElement.insertBefore(e, this);
})
break;
case "after":
if (this.parentElement.lastChild === this) {
dom.forEach((e, i) => {
this.append(e);
})
} else {
let next = this.nextSilbing;
Array.from(dom).reverse().forEach((e, i) => {
this.parentElement.insertBefore(e, next);
})
}
break;
}
if(reNew){
return dom.length>1?dom:dom[0]
}else{
return this
}
}
HTMLElement.prototype.replace = function(dom) {
dom = this.insert(dom, "before",true);
this.remove();
return dom;
}
NodeList.prototype.attr = function(key,val){
this.forEach((e, i) => {
e.attr(key, val)
})
}
NodeList.prototype.css = function(key,val){
this.forEach((e, i) => {
e.css(key, val)
})
}
NodeList.prototype.hide = function() {
this.forEach((e, i) => {
e.hide();
})
}
NodeList.prototype.show = function() {
this.forEach((e, i) => {
e.show();
})
}