前言
文字的宽高,不同字体渲染不一样,如何获取字体字号单个文字的实际占用的宽度呢?今天介绍两种方式。
方案一,dom宽度获取
用真实的dom做渲染,然后获取dom的宽度,计算得到最终的准确的字符像素长度。
span方法如下:
function getStringPixelWidthSpan(text, font) {
const span = document.createElement('span');
document.body.appendChild(span);
span.style.position = 'absolute';
span.style.whiteSpace = 'nowrap';
span.style.font = font;
span.textContent = text;
const width = span.offsetWidth;
document.body.removeChild(span);
return width;
}
使用如下:
getStringPixelWidthSpan('haoRooms博客',' 20px Microsoft YaHei')
方案二,canvas获取
function getTextWidth(text, font) {
// 创建一个临时的canvas元素
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
// 设置字体样式
context.font = font;
// 测量文本的宽度
var width = context.measureText(text).width;
// 返回文本的宽度
return width;
}
使用:
getTextWidth('haoRooms博客',' 20px Microsoft YaHei')
获取页面字体
可以通过如下方式获取页面字体
function getPageFont() {
// 获取<html>元素的样式
const htmlStyles = window.getComputedStyle(document.documentElement);
// 获取font-family属性值
const fontFamily = htmlStyles.getPropertyValue('font-family');
return fontFamily;
}
获取效率canvas 和 span 时间对比
// Test data
const textArray = ["你好,世界!", "Hello, World!", "こんにちは、世界!", "안녕하세요, 세상!"];
const font = "16px Arial";
// Performance test
function testPerformance(methodName) {
const startTime = performance.now();
for (let i = 0; i < 1000; i++) {
textArray.forEach((text) => {
if (methodName === 'canvas') {
getTextWidth(text, font);
} else if (methodName === 'span') {
getStringPixelWidthSpan(text, font);
}
});
}
// document.body.removeChild(span);
const endTime = performance.now();
const duration = endTime - startTime;
console.log(`${methodName} method took ${duration.toFixed(2)} milliseconds.`);
}
// Run performance tests
testPerformance('canvas');
testPerformance('span');
1000个时间对比
canvas method took 10.50 milliseconds.
span method took 375.50 milliseconds.
结论
canvas的效果目前看是最好的,推荐使用canvas来获取文字渲染实际宽度。