@aplus-frontend/utils
Version:
Utils for Aplus frontend team.
140 lines (139 loc) • 3.7 kB
JavaScript
import { upperFirst } from "../utils";
function getBoundingClientRect(element) {
if (!element || !element.getBoundingClientRect) {
return 0;
}
return element.getBoundingClientRect();
}
function trim(string) {
return (string || "").replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, "");
}
function hasClass(el, cls) {
if (!el || !cls) return false;
if (cls.indexOf(" ") !== -1)
throw new Error("className should not contain space.");
if (el.classList) {
return el.classList.contains(cls);
} else {
return (" " + el.className + " ").indexOf(" " + cls + " ") > -1;
}
}
function addClass(el, cls) {
if (!el) return;
let curClass = el.className;
const classes = (cls || "").split(" ");
for (let i = 0, j = classes.length; i < j; i++) {
const clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.add(clsName);
} else if (!hasClass(el, clsName)) {
curClass += " " + clsName;
}
}
if (!el.classList) {
el.className = curClass;
}
}
function removeClass(el, cls) {
if (!el || !cls) return;
const classes = cls.split(" ");
let curClass = " " + el.className + " ";
for (let i = 0, j = classes.length; i < j; i++) {
const clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.remove(clsName);
} else if (hasClass(el, clsName)) {
curClass = curClass.replace(" " + clsName + " ", " ");
}
}
if (!el.classList) {
el.className = trim(curClass);
}
}
function getViewportOffset(element) {
const doc = document.documentElement;
const docScrollLeft = doc.scrollLeft;
const docScrollTop = doc.scrollTop;
const docClientLeft = doc.clientLeft;
const docClientTop = doc.clientTop;
const pageXOffset = window.pageXOffset;
const pageYOffset = window.pageYOffset;
const box = getBoundingClientRect(element);
const {
left: retLeft,
top: rectTop,
width: rectWidth,
height: rectHeight
} = box;
const scrollLeft = (pageXOffset || docScrollLeft) - (docClientLeft || 0);
const scrollTop = (pageYOffset || docScrollTop) - (docClientTop || 0);
const offsetLeft = retLeft + pageXOffset;
const offsetTop = rectTop + pageYOffset;
const left = offsetLeft - scrollLeft;
const top = offsetTop - scrollTop;
const clientWidth = window.document.documentElement.clientWidth;
const clientHeight = window.document.documentElement.clientHeight;
return {
left,
top,
right: clientWidth - rectWidth - left,
bottom: clientHeight - rectHeight - top,
rightIncludeBody: clientWidth - left,
bottomIncludeBody: clientHeight - top
};
}
function hackCss(attr, value) {
const prefix = ["webkit", "Moz", "ms", "OT"];
const styleObj = {};
prefix.forEach((item) => {
styleObj[`${item}${upperFirst(attr)}`] = value;
});
return {
...styleObj,
[attr]: value
};
}
function on(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
}
function off(element, event, handler) {
if (element && event && handler) {
element.removeEventListener(event, handler, false);
}
}
function once(el, event, fn) {
const listener = function(...args) {
if (fn) {
fn.apply(this, args);
}
off(el, event, listener);
};
on(el, event, listener);
}
function useRafThrottle(fn) {
let locked = false;
return function(...args) {
if (locked) return;
locked = true;
window.requestAnimationFrame(() => {
fn.apply(this, args);
locked = false;
});
};
}
export {
addClass,
getBoundingClientRect,
getViewportOffset,
hackCss,
hasClass,
off,
on,
once,
removeClass,
useRafThrottle
};