UNPKG

@mdui/jq

Version:

拥有和 jQuery 相似 API 的轻量级 JavaScript 工具库

132 lines (131 loc) 4.78 kB
import { getDocument } from 'ssr-window'; import { $ } from '../$.js'; import { isBorderBox, getExtraWidth, getComputedStyleValue, } from '../shared/css.js'; import { isBoolean, isString, isDocument, isFunction, isWindow, toElement, eachArray, } from '../shared/helper.js'; import './css.js'; import './each.js'; /** * 值上面的 padding、border、margin 处理 * @param element * @param name * @param value * @param funcIndex * @param includeMargin * @param multiply */ const handleExtraWidth = (element, name, value, funcIndex, includeMargin, multiply) => { // 获取元素的 padding, border, margin 宽度(两侧宽度的和) const getExtraWidthValue = (extra) => { return (getExtraWidth(element, name.toLowerCase(), extra) * multiply); }; if (funcIndex === 2 && includeMargin) { value += getExtraWidthValue('margin'); } if (isBorderBox(element)) { if (funcIndex === 0) { value -= getExtraWidthValue('border'); } if (funcIndex === 1) { value -= getExtraWidthValue('border'); value -= getExtraWidthValue('padding'); } } else { if (funcIndex === 0) { value += getExtraWidthValue('padding'); } if (funcIndex === 2) { value += getExtraWidthValue('border'); value += getExtraWidthValue('padding'); } } return value; }; /** * 获取元素的样式值 * @param element * @param name * @param funcIndex 0: innerWidth, innerHeight; 1: width, height; 2: outerWidth, outerHeight * @param includeMargin */ const get = (element, name, funcIndex, includeMargin) => { const document = getDocument(); const clientProp = `client${name}`; const scrollProp = `scroll${name}`; const offsetProp = `offset${name}`; const innerProp = `inner${name}`; // $(window).width() if (isWindow(element)) { // outerWidth, outerHeight 需要包含滚动条的宽度 return funcIndex === 2 ? element[innerProp] : toElement(document)[clientProp]; } // $(document).width() if (isDocument(element)) { const doc = toElement(element); return Math.max( // @ts-ignore element.body[scrollProp], doc[scrollProp], // @ts-ignore element.body[offsetProp], doc[offsetProp], doc[clientProp]); } const value = parseFloat(getComputedStyleValue(element, name.toLowerCase()) || '0'); return handleExtraWidth(element, name, value, funcIndex, includeMargin, 1); }; /** * 设置元素的样式值 * @param element * @param elementIndex * @param name * @param funcIndex 0: innerWidth, innerHeight; 1: width, height; 2: outerWidth, outerHeight * @param includeMargin * @param value */ const set = (element, elementIndex, name, funcIndex, includeMargin, value) => { let computedValue = isFunction(value) ? value.call(element, elementIndex, get(element, name, funcIndex, includeMargin)) : value; if (computedValue == null) { return; } const $element = $(element); const dimension = name.toLowerCase(); // 特殊的值,不需要计算 padding、border、margin if (isString(computedValue) && ['auto', 'inherit', ''].includes(computedValue)) { $element.css(dimension, computedValue); return; } // 其他值保留原始单位。注意:如果不使用 px 作为单位,则算出的值一般是不准确的 const suffix = computedValue.toString().replace(/\b[0-9.]*/, ''); const numerical = parseFloat(computedValue); computedValue = handleExtraWidth(element, name, numerical, funcIndex, includeMargin, -1) + (suffix || 'px'); $element.css(dimension, computedValue); }; eachArray(['Width', 'Height'], (name) => { eachArray([`inner${name}`, name.toLowerCase(), `outer${name}`], (funcName, funcIndex) => { $.fn[funcName] = function ( // eslint-disable-next-line @typescript-eslint/no-explicit-any margin, // eslint-disable-next-line @typescript-eslint/no-explicit-any value) { // 是否是赋值操作 const isSet = arguments.length && (funcIndex < 2 || !isBoolean(margin)); const includeMargin = margin === true || value === true; // 获取第一个元素的值 if (!isSet) { return this.length ? get(this[0], name, funcIndex, includeMargin) : undefined; } // 设置每个元素的值 return this.each((index, element) => { return set(element, index, name, funcIndex, includeMargin, margin); }); }; }); });