Last active
November 3, 2024 07:24
-
-
Save AdaRoseCannon/d95a7cbb8edd730443c62f0daff875ac to your computer and use it in GitHub Desktop.
Oh no!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is just the worst don't use it. | |
function $(...s) { | |
if (s.length === 0) return document.childNodes; | |
// Handle it being used as a template tag | |
const inString = (typeof s[0] === 'string' ? s[0] : String.raw(...s)).trim(); | |
if (inString[0].includes('<')) { | |
return document.createRange().createContextualFragment(inString); | |
} else { | |
return document.querySelectorAll(inString); | |
} | |
} | |
Element.prototype.on = window.on = function (name, fn, options) { | |
if (!this.funcRef) this.funcRef = new Set(); | |
// Store it for later | |
this.funcRef.add(fn); | |
this.addEventListener(name, fn, options); | |
return this; | |
}; | |
Element.prototype.off = window.off = function (name, fn) { | |
if (!this.funcRef) return; | |
if (fn) { | |
this.removeEventListener(name, fn); | |
} else { | |
this.funcRef.forEach(fn => this.removeEventListener(name, fn)); | |
} | |
this.funcRef.delete(fn); | |
return this; | |
}; | |
Element.prototype.once = window.once = function (name, fn, options) { | |
const o = {once: true}; | |
Object.assign(o, options); | |
this.on(name, function tempF(e) { | |
fn.bind(this)(e); | |
this.off(name, tempF); | |
}, o); | |
return this; | |
}; | |
const childAccessorProxy = { | |
get(target, prop) { | |
if (prop in target) return target[prop]; | |
// Maps each parent to that property on that parent | |
// If they are functions they get bound. | |
const propFromEachElement = target.map((i,index) => { | |
return (i[prop] && 'bind' in i[prop]) ? i[prop].bind(i) : i[prop] | |
}); | |
const proxiedArray = new Proxy(propFromEachElement, childAccessorProxy); | |
// Return a function which will try to call all of the children with the arguments. | |
// Otherwise will reflect them onto the proxied array of the requested property from all the | |
return new Proxy(function (...args) { | |
target.forEach(i => i[prop] && i[prop](...args)); | |
return target; | |
}, { | |
get(target,...args){return Reflect.get(proxiedArray, ...args)}, | |
set(target,...args){return Reflect.set(proxiedArray, ...args)}, | |
has(target,...args){return Reflect.has(proxiedArray, ...args)}, | |
}); | |
}, | |
set(target, prop, value) { | |
if (prop in target) { | |
target[prop] = value; | |
} else { | |
target.forEach(i => i[prop] = value); | |
} | |
} | |
}; | |
// Add all properties and functions on Element to NodeList | |
// This is a bad thing to do | |
for (const key in Element.prototype) { | |
if (key in NodeList.prototype) continue; | |
Object.defineProperty(NodeList.prototype, key, { | |
get(){ | |
try { | |
if (typeof Element.prototype[key] === 'function') return function (...args) { | |
this.forEach(el => el instanceof Element && el[key](...args)); | |
return this; | |
} | |
} catch (e) {} | |
return new Proxy(Array.from(this).filter(el => el instanceof Element).map(el=>el[key]), childAccessorProxy); | |
}, | |
set(value){ | |
this.forEach(el=>el[key]=value) | |
}, | |
configurable: true | |
}) | |
} | |
export default $; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
document.querySelectorAll('span').textContent = 'butts'; // Change the text of every span | |
// Get at an Array of all the textContents | |
document.querySelectorAll('span').textContent; | |
// ['butts', 'butts', 'butts', 'butts', 'butts', 'butts', ...] | |
// $('span') or $`span` can also be used. | |
// It also recursively works on the properties: | |
$`span`.classList.add('blue'); | |
// You can also use it to create fragments on the fly | |
$`body`.appendChild($`<b>hi!`) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
as you go for
.trim()
after checkings[0]
, you might as well consider using the way more performanttypeof
check:also, as
if (inString[0] === '<') {
wouldn't consider fragments with<
within the query, and as that's still not valid CSS selector, you might as well go for:Last, but not least, whenever you pollute global/native prototypes, it's always welcome to use, at least,
configurable: true
, for whatever patch is needed in the future, or for those environments that would like to delete these non-standards entries.