Hidden elements have zero width, subtracting offset would make the width negative. These negative values would cascade down to component creation
138 lines
3.4 KiB
JavaScript
138 lines
3.4 KiB
JavaScript
export function $(expr, con) {
|
|
return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
|
|
}
|
|
|
|
export function findNodeIndex(node)
|
|
{
|
|
var i = 0;
|
|
while (node.previousSibling) {
|
|
node = node.previousSibling;
|
|
i++;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
$.create = (tag, o) => {
|
|
var element = document.createElement(tag);
|
|
|
|
for (var i in o) {
|
|
var val = o[i];
|
|
|
|
if (i === "inside") {
|
|
$(val).appendChild(element);
|
|
}
|
|
else if (i === "around") {
|
|
var ref = $(val);
|
|
ref.parentNode.insertBefore(element, ref);
|
|
element.appendChild(ref);
|
|
|
|
} else if (i === "styles") {
|
|
if(typeof val === "object") {
|
|
Object.keys(val).map(prop => {
|
|
element.style[prop] = val[prop];
|
|
});
|
|
}
|
|
} else if (i in element ) {
|
|
element[i] = val;
|
|
}
|
|
else {
|
|
element.setAttribute(i, val);
|
|
}
|
|
}
|
|
|
|
return element;
|
|
};
|
|
|
|
export function getOffset(element) {
|
|
let rect = element.getBoundingClientRect();
|
|
return {
|
|
// https://stackoverflow.com/a/7436602/6495043
|
|
// rect.top varies with scroll, so we add whatever has been
|
|
// scrolled to it to get absolute distance from actual page top
|
|
top: rect.top + (document.documentElement.scrollTop || document.body.scrollTop),
|
|
left: rect.left + (document.documentElement.scrollLeft || document.body.scrollLeft)
|
|
};
|
|
}
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent
|
|
// an element's offsetParent property will return null whenever it, or any of its parents,
|
|
// is hidden via the display style property.
|
|
export function isHidden(el) {
|
|
return (el.offsetParent === null);
|
|
}
|
|
|
|
export function isElementInViewport(el) {
|
|
// Although straightforward: https://stackoverflow.com/a/7557433/6495043
|
|
var rect = el.getBoundingClientRect();
|
|
|
|
return (
|
|
rect.top >= 0 &&
|
|
rect.left >= 0 &&
|
|
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
|
|
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
|
|
);
|
|
}
|
|
|
|
export function getElementContentWidth(element) {
|
|
var styles = window.getComputedStyle(element);
|
|
var padding = parseFloat(styles.paddingLeft) +
|
|
parseFloat(styles.paddingRight);
|
|
|
|
return element.clientWidth - padding;
|
|
}
|
|
|
|
export function bind(element, o){
|
|
if (element) {
|
|
for (var event in o) {
|
|
var callback = o[event];
|
|
|
|
event.split(/\s+/).forEach(function (event) {
|
|
element.addEventListener(event, callback);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
export function unbind(element, o){
|
|
if (element) {
|
|
for (var event in o) {
|
|
var callback = o[event];
|
|
|
|
event.split(/\s+/).forEach(function(event) {
|
|
element.removeEventListener(event, callback);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
export function fire(target, type, properties) {
|
|
var evt = document.createEvent("HTMLEvents");
|
|
|
|
evt.initEvent(type, true, true );
|
|
|
|
for (var j in properties) {
|
|
evt[j] = properties[j];
|
|
}
|
|
|
|
return target.dispatchEvent(evt);
|
|
}
|
|
|
|
// https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/
|
|
export function forEachNode(nodeList, callback, scope) {
|
|
if(!nodeList) return;
|
|
for (var i = 0; i < nodeList.length; i++) {
|
|
callback.call(scope, nodeList[i], i);
|
|
}
|
|
}
|
|
|
|
export function activate($parent, $child, commonClass, activeClass='active', index = -1) {
|
|
let $children = $parent.querySelectorAll(`.${commonClass}.${activeClass}`);
|
|
|
|
forEachNode($children, (node, i) => {
|
|
if(index >= 0 && i <= index) return;
|
|
node.classList.remove(activeClass);
|
|
});
|
|
|
|
$child.classList.add(activeClass);
|
|
}
|