Skip to content

Instantly share code, notes, and snippets.

@ninjamar
Last active March 21, 2024 04:44
Show Gist options
  • Save ninjamar/e7f3819cc86aaa53310f07d3a48fad90 to your computer and use it in GitHub Desktop.
Save ninjamar/e7f3819cc86aaa53310f07d3a48fad90 to your computer and use it in GitHub Desktop.
A JavaScript library
/*
This whole module is a work in progress for me to use
TODO: Rename module to something else from q
*/
class QElement {
constructor($element){
// this.listeners = {};
this.$element = $element;
}
q(selector){
return window.q(selector, this.$element);
}
/* Should HTML be inside QKlass */
get html(){
return this.$element.innerHTML || this.$element.textContent;
}
set html(value){
if (!this.$element.innerHTML){
this.$element.textContent = value;
}
this.$element.innerHTML = value
return true;
}
addEvent(name, callback){
/*
if (!this.listeners[name]){
this.listeners[name] = [];
}
this.listeners[name].push(callback);*/
this.$element.addEventListener(name, callback);
}
removeEvent(name, callback){
this.$element.removeEventListener(name, callback);
}
/* For compatability reasons */
each(callback){
callback(this);
}
attr(name, value){
if (arguments.length > 1){
this.$element.setAttribute(name, value);
return true;
}
return this.$element.getAttribute(name);
}
prop(name, value){
if (arguments.length > 1){
this.$element[name] = value;
return true;
}
return this.$element[name];
}
addClass(cls){
this.$element.classList.add(cls);
return true;
}
removeClass(cls){
this.$element.classList.remove(cls);
return true;
}
append($e){
// TODO: Need to have a guard, because we might be appending QElement
this.$element.append($e)
return true;
}
prepend($e){
this.$element.prepend($e);
return true;
}
insertBefore($e){
this.$element.before($e);
return true;
}
insertAfter($e){
this.$element.after($e);
return true;
}
}
class QElementCollection {
constructor(elements){
this.elements = Array.prototype.map.call(elements, (e) => new QElement(e));
// this.$elements = Array.prototype.map.call(context.querySelectorAll(selector), ($e) => new QElement($e));
}
_migrateFromQElement(name){
return (arg) => {
if (typeof arg == "function"){
this.each(e => e[name](arg(e))); // this.each(element => element.append(factory()));
} else {
this.each(e => e[name](arg));
}
return this;
}
}
each(callback){
for (let elem of this.elements){
callback(elem);
}
return this;
}
addClass = this._migrateFromQElement("addClass");
removeClass = this._migrateFromQElement("removeClass");
append = this._migrateFromQElement("append");
prepend = this._migrateFromQElement("prepend");
insertBefore = this._migrateFromQElement("insertBefore");
insertAfter = this._migrateFromQElement("insertAfter");
attr = this._migrateFromQElement("attr");
prop = this._migrateFromQElement("prop");
addEvent = this._migrateFromQElement("addEvent");
removeEvent = this._migrateFromQElement("removeEvent");
}
window.q = function(selector, context = document){
let all = context.querySelectorAll(selector);
if (all.length == 1){
return new QElement(all[0]);
}
return new QElementCollection(all);
}
window.qhtml = function(html){
let $elem = document.createElement("div");
$elem.innerHTML = html;
return new QElement($elem.firstChild); // TODO: Should I use window.q here?
}
<!DOCTYPE html>
<html>
<head>
<title>Selector</title>
<script src="q.js"></script>
</head>
<body>
<p>Test</p>
<div>
<p id="foo">Test2</p>
<p class="bar">Test3</p>
<p class="bar">Test4</p>
<p class="bar">Test5</p>
<p class="bar">Test6</p>
<p class="bar">Test7</p>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment