const getTagFontSize = (tag: string): number => {
const ele = document.createElement(tag);
document.body.append(ele);
const { fontSize } = getComputedStyle(ele);
document.body.removeChild(ele);
return parseInt(fontSize);
}
// 单位px
const getFontSizePx = (ele: any): number => {
// medium:于16px(h4预设值)
// xx-small:medium的0.6倍(h6预设值)
// x-small:medium的0.75倍
// small:medium的0.8倍(h5预设值,W3C定义为0.89,实测约为0.8)
// large:medium的1.1倍(h3预设值,W3C定义为1.2,实测约为1.1)
// x-large:medium的1.5倍(h2预设值)
// xx-large:medium的2倍(h1预设值)
// smaller:约为父层的80%
// larger:约为父层的120%
let ret = 0;
const {fontSize} = getComputedStyle(ele);
if (['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'].includes(fontSize)) {
switch (fontSize) {
case 'medium': ret = getTagFontSize('h4'); break;
case 'xx-small': ret = getTagFontSize('h6'); break;
case 'x-small': ret = getTagFontSize('h4') * 0.75; break;
case 'small': ret = getTagFontSize('h5'); break;
case 'large': ret = getTagFontSize('h3'); break;
case 'x-large': ret = getTagFontSize('h2'); break;
case 'xx-large': ret = getTagFontSize('h1'); break;
}
} else if (/^\d[\d]+(px)$/.test(fontSize)) {
ret = parseInt(fontSize);
} else if (/^\d[\d]+(em)$/.test(fontSize)) {
const parentFontSize = getFontSizePx(ele.parentElement);
ret = parentFontSize * parseInt(fontSize);
} else if (/^\d[\d]+(rem)$/.test(fontSize)) {
const rootFontSize = getComputedStyle(document.body.parentElement || document.body).fontSize;
ret = parseInt(rootFontSize) * parseInt(fontSize);
} else if (/^\d[\d]+(vh)$/.test(fontSize)) {
ret = window.innerHeight;
} else if (/^\d[\d]+(vw)$/.test(fontSize)) {
ret = window.innerWidth;
} else if (/^\d[\d]+(%)$/.test(fontSize)) {
const fs = getFontSizePx(ele);
ret = fs * parseInt(fontSize) / 100;
} else if (fontSize === 'inherit') {
ret = getFontSizePx(ele.parentElement);
}
return ret;
}
// 单位px
const getLineHeightPx = (ele: any): number => {
// vh/vw/px/em/rem/normal/inherit/数值/百分比
let ret = 0;
const {lineHeight} = getComputedStyle(ele);
if (/^\d[\d]+(px)$/.test(lineHeight)) {
ret = parseInt(lineHeight);
} else if (/^\d[\d]+(em)$/.test(lineHeight)) {
const parentFontSize = getFontSizePx(ele.parentElement);
ret = parentFontSize * parseInt(lineHeight);
} else if (/^\d[\d]+(rem)$/.test(lineHeight)) {
const rootFontSize = getComputedStyle(document.body.parentElement || document.body).fontSize;
ret = parseInt(rootFontSize) * parseInt(lineHeight);
} else if (/^\d[\d]+(vh)$/.test(lineHeight)) {
ret = window.innerHeight;
} else if (/^\d[\d]+(vw)$/.test(lineHeight)) {
ret = window.innerWidth;
} else if (/^\d[\d]+(%)$/.test(lineHeight)) {
const fontSize = getFontSizePx(ele);
ret = fontSize * parseInt(lineHeight) / 100;
} else if (/^\d[\d]+\d$/.test(lineHeight)) {
const fontSize = getFontSizePx(ele);
ret = fontSize * parseInt(lineHeight);
} else if (lineHeight === 'normal') {
const fontSize = getFontSizePx(ele);
ret = 4/3 * fontSize;
} else if (lineHeight === 'inherit') {
ret = getLineHeightPx(ele.parentElement);
}
return ret;
}