/* == class 相关 == */ const any = (obj: any) => obj; // 添加 class export const addClass = (element: Element, ...className: string[]): void => { element.classList.add(...className); }; // 移除 class export const removeClass = (element: Element, ...className: string[]): void => { element.classList.remove(...className); }; // 是否包含指定 class export const hasClass = (element: Element, className: string): boolean => { return element.classList.contains(className); }; // 切换指定 class // 若为移除,则返回 false;若为添加,则返回 true export const toggleClass = (element: Element, className: string): boolean => { return element.classList.toggle(className); }; /* == DOM 相关 == */ // 查找第一个指定的css选择器 export const query = ( startNode: Element, cssSelector: string ): Element | null => { return startNode.querySelector(cssSelector); }; // 查找所有指定的css选择器 export const queryAll = ( startNode: Element, cssSelector: string ): NodeListOf => { return (startNode || document).querySelectorAll(cssSelector); }; // 返回或者设置 innerHTML // eslint-disable-next-line consistent-return export const html = (element: Element, innerHTML?: string): string | void => { if (typeof innerHTML === "undefined") { return element.innerHTML; } element.innerHTML = innerHTML; }; // 返回或者设置 innerText // eslint-disable-next-line consistent-return export const text = ( element: HTMLElement, innerText?: string ): string | void => { if (typeof innerText === "undefined") { return element.innerText; } element.innerText = innerText; }; // 创建元素 export const createElement = (tagName: string): HTMLElement => { return document.createElement(tagName); }; // 在container内部的后面挂载元素 export const append = (container: Element, ...element: Element[]): void => { container.append(...element); }; // 在container内部的前面挂载元素 export const prepend = (container: Element, ...element: Element[]): void => { container.prepend(...element); }; // 移除元素 export const remove = (element: Element | null): void => { element && element.remove(); }; // 绑定事件 export const on = ( element: Element, eventName: string, callback: (event: Event) => void, useCapture = false ): void => { element.addEventListener(eventName, callback, useCapture); }; // 解绑事件 export const off = ( element: Element, eventName: string, callback: (event: Event) => void ): void => { element.removeEventListener(eventName, callback); }; // hover export const hover = ( element: Element, handlerIn: (e: Event) => void, handlerOut: (e: Event) => void ): void => { on(element, "mouseenter", handlerIn); on(element, "mouseleave", handlerOut); }; // wheel滚轮事件 export const wheel = ( element: Element, handlerWheel: (e: Event) => void ): void => { on(element, "mousewheel", handlerWheel); }; // 解析字符串生成DOM元素 export const parse = (innerHTML: string): Element => { const container = createElement("div"); html(container, innerHTML.trim()); return container.firstChild as Element; }; // 设置元素样式 export const style = ( element: HTMLElement, styleObj: { [key in keyof CSSStyleDeclaration]?: string } ): void => { const keys = Object.keys(styleObj); keys.forEach((key) => { any(element.style)[key] = any(styleObj)[key]; }); }; // 清空dom元素 export const empty = (element: Element): void => { let child; // eslint-disable-next-line no-cond-assign while ((child = element.lastChild)) { element.removeChild(child); } }; // 获取元素的位置 export const getElementOffset = (element: HTMLElement) => { const offset = { left: 0, top: 0 }; let current: HTMLElement = element.offsetParent as any; offset.left += element.offsetLeft; offset.top += element.offsetTop; while (current !== null) { offset.left += current.offsetLeft; offset.top += current.offsetTop; current = current.offsetParent as any; } return offset; }; /** * Returns caret position in text input * * @author http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea * @return {Number} */ export const getCaretPosition = (el: HTMLInputElement) => { if (el.selectionStart) { return el.selectionStart; } if ((document as any).selection) { // IE8 el.focus(); const r = (document as any).selection.createRange(); if (r == null) { return 0; } const re = (el as any).createTextRange(); const rc = re.duplicate(); re.moveToBookmark(r.getBookmark()); rc.setEndPoint("EndToStart", re); return rc.text.length; } return 0; }; /** * Sets caret position in text input. * * @author http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/ * @param {Element} element * @param {Number} pos * @param {Number} endPos */ export const setCaretPosition = ( element: HTMLInputElement, pos: number, endPos: number ) => { if (endPos === 0) { endPos = pos; } if (element.setSelectionRange) { element.focus(); try { element.setSelectionRange(pos, endPos); } catch (err) { const elementParent = element.parentNode as HTMLElement; const parentDisplayValue = elementParent.style.display; elementParent.style.display = "block"; element.setSelectionRange(pos, endPos); elementParent.style.display = parentDisplayValue; } } else if ((element as any).createTextRange) { // IE8 const range = (element as any).createTextRange(); range.collapse(true); range.moveEnd("character", endPos); range.moveStart("character", pos); range.select(); } };