63 lines
2.0 KiB
JavaScript
63 lines
2.0 KiB
JavaScript
const LOAD = 'load';
|
|
const DOM_CONTENT_LOADED = 'DOMContentLoaded';
|
|
class QueryResult extends Array {}
|
|
const search = (list, el) => {
|
|
const nodes = [];
|
|
for (const CSS of list) {
|
|
const css = CSS.trim();
|
|
if (css.slice(-6) === ':first') {
|
|
const node = el.querySelector(css.slice(0, -6));
|
|
if (node) nodes.push(node);
|
|
} else
|
|
for (const node of el.querySelectorAll(css))
|
|
nodes.push(node);
|
|
}
|
|
return new QueryResult(...nodes);
|
|
};
|
|
const {defineProperty} = Object;
|
|
const $ = defineProperty(
|
|
(CSS, parent = document) => {
|
|
switch (typeof CSS) {
|
|
case 'string': return search(CSS.split(','), parent);
|
|
case 'object': return new QueryResult(
|
|
...(('nodeType' in CSS || 'postMessage' in CSS) ? [CSS] : CSS)
|
|
);
|
|
case 'function':
|
|
const $parent = $(parent);
|
|
const $window = $(parent.defaultView);
|
|
const handler = {handleEvent(event) {
|
|
$parent.off(DOM_CONTENT_LOADED, handler);
|
|
$window.off(LOAD, handler);
|
|
CSS(event);
|
|
}};
|
|
$parent.on(DOM_CONTENT_LOADED, handler);
|
|
$window.on(LOAD, handler);
|
|
const rs = parent.readyState;
|
|
if (rs == 'complete' || (rs != 'loading' && !parent.documentElement.doScroll))
|
|
setTimeout(() => $parent.dispatch(DOM_CONTENT_LOADED));
|
|
return $;
|
|
}
|
|
},
|
|
Symbol.hasInstance,
|
|
{value: instance => instance instanceof QueryResult}
|
|
);
|
|
$.extend = (key, value) => (defineProperty(
|
|
QueryResult.prototype,
|
|
key, {configurable: true, value}
|
|
), $);
|
|
$.extend('dispatch', function dispatch(type, init = {}) {
|
|
const event = new CustomEvent(type, init);
|
|
for (const node of this) node.dispatchEvent(event);
|
|
return this;
|
|
})
|
|
.extend('off', function off(type, handler, options = false) {
|
|
for (const node of this) node.removeEventListener(type, handler, options);
|
|
return this;
|
|
})
|
|
.extend('on', function on(type, handler, options = false) {
|
|
for (const node of this) node.addEventListener(type, handler, options);
|
|
return this;
|
|
});
|
|
|
|
export default $;
|