/** * {常用方法库} * @author yutent * @date 2023/03/07 22:11:30 */ export function noop() {} export function $(selector, container, multi) { let fn = multi ? 'querySelectorAll' : 'querySelector' if (container) { return container[fn](selector) } return document.body[fn](selector) } export function $$(selector, container) { return $(selector, container, true) } export const nextTick = (function () { let queue = [] let node = document.createTextNode('') let bool = false function callback() { while (queue.length > 0) { let fn = queue.shift() try { fn() } catch (err) { console.error(err) } } } new MutationObserver(callback).observe(node, { characterData: true }) return function (fn) { queue.push(fn) bool = !bool node.data = bool } })() export function range(...args) { let start = 0, end = 0, step = 1, out = [] switch (args.length) { case 1: end = args[0] break case 2: case 3: ;[start, end, step = 1] = args step = Math.abs(step) || 1 break } if (start > end) { ;[start, end] = [end, start] } for (let i = start; i < end; i += step) { out.push(i) } return out } //驼峰转换为连字符线风格 export function hyphen(target) { return target.replace(/([a-z\d])([A-Z]+)/g, '$1-$2').toLowerCase() } //连字符转换为驼峰风格 export function camelize(target) { //提前判断,提高效率 if (target.indexOf('-') < 0) { return target } return target.replace(/\-([a-z])/g, (m, s) => s.toUpperCase()) } //取得距离页面左上角的坐标 export function offset(node) { try { let rect = node.getBoundingClientRect() if (rect.width || rect.height || node.getClientRects().length) { let doc = node.ownerDocument let root = doc.documentElement let win = doc.defaultView return { top: rect.top + win.pageYOffset - root.clientTop, left: rect.left + win.pageXOffset - root.clientLeft } } } catch (e) { return { left: 0, top: 0 } } } /** * 事件绑定 */ export function bind(dom, type = '', selector, fn, phase = false) { let events = type.split(',') let callback let isWc = dom && dom.host === dom let host = isWc ? dom : null if (!dom || !type) { return console.error( "Argument Error: function bind's arg 1 must be a document obejct" ) } if (typeof selector === 'function') { phase = fn || false fn = selector selector = null } else { if (typeof selector !== 'string') { selector = null } fn = fn || noop } if (isWc === false) { let node = dom while (node && node !== document.body && node !== document) { if (node.ownHost) { isWc = true host = node.ownHost break } node = node.parentNode } } if (selector) { callback = function (ev) { let agents = $(selector, dom) let elem = ev.target if (agents) { while (true) { if (elem === dom) { break } if (agents.contains(elem)) { fn(ev) break } else { elem = elem.parentNode } } } } } else { callback = fn } events.forEach(function (t) { t = t.trim() if (isWc) { host.$events[t] ??= [] let _list = host.$events[t] if (_list.length) { let idx = _list.findIndex( it => it.el === dom && it.listener === callback && it.options === phase ) if (idx > -1) { let item = _list[idx] _list.splice(idx, 1) dom.removeEventListener(t, item.listener, item.options) } } _list.push({ el: dom, listener: callback, options: phase }) } dom.addEventListener(t, callback, phase) }) return callback } /** * 解除事件绑定 */ export function unbind(dom, type = '', fn = noop, phase = false) { let events = type.split(',') events.forEach(function (t) { dom.removeEventListener(t.trim(), fn, phase) }) } // 指定节点外点击(最高不能超过body层) export function outsideClick(dom, fn = noop) { return bind(document, 'mousedown', ev => { let path = ev.composedPath ? ev.composedPath() : ev.path if (path) { while (path.length > 3) { if (path.shift() === dom) { return } } } else { let target = ev.explicitOriginalTarget || ev.target if ( dom === target || dom.contains(target) || (dom.root && dom.root.contains(target)) ) { return } } fn(ev) }) } export function clearOutsideClick(fn = noop) { unbind(document, 'mousedown', fn) } /** * @param el 节点 * @param name 自定义的事件名 * @param data 要合并进event对象的参数 * @param stop 是否禁止事件冒泡 */ export function fire(el, name = 'click', data = {}, stop) { let ev = new Event(name, { bubbles: !stop, cancelable: true }) Object.assign(ev, data) el.dispatchEvent(ev) }