JavaScript를 사용하여 문자열 너비를 계산하고 싶습니다. 고정 폭 서체를 사용하지 않고도 가능합니까?
내장되어 있지 않으면 각 문자에 대해 너비 테이블을 만드는 것이 유일한 아이디어이지만 유니 코드 와 다른 유형 크기 (및 해당 문제에 대한 모든 브라우저)를 지원하는 것은 부당 합니다.
답변
다음 스타일로 스타일 화 된 DIV를 작성하십시오. JavaScript에서 측정하려는 글꼴 크기와 속성을 설정하고 문자열을 DIV에 넣은 다음 DIV의 현재 너비와 높이를 읽습니다. 내용에 맞게 확장되며 크기는 문자열 렌더링 크기의 몇 픽셀 내에 있습니다.
var fontSize = 12;
var test = document.getElementById("Test");
test.style.fontSize = fontSize;
var height = (test.clientHeight + 1) + "px";
var width = (test.clientWidth + 1) + "px"
console.log(height, width);
#Test
{
position: absolute;
visibility: hidden;
height: auto;
width: auto;
white-space: nowrap; /* Thanks to Herb Caudill comment */
}
<div id="Test">
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
</div>
답변
HTML 5 에서는 Canvas.measureText 메서드를 사용할 수 있습니다 (자세한 설명은 여기 참조 ).
/**
* Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
*
* @param {String} text The text to be rendered.
* @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
*
* @see /programming/118241/calculate-text-width-with-javascript/21015393#21015393
*/
function getTextWidth(text, font) {
// re-use canvas object for better performance
var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
var context = canvas.getContext("2d");
context.font = font;
var metrics = context.measureText(text);
return metrics.width;
}
console.log(getTextWidth("hello there!", "bold 12pt arial")); // close to 86
이 바이올린 은이 Canvas 방법을 Bob Monteverde의 DOM 기반 방법의 변형 과 비교하므로 결과의 정확성을 분석하고 비교할 수 있습니다.
이 방법에는 다음과 같은 몇 가지 장점이 있습니다.
- DOM과 같은 전역 상태를 변경하지 않기 때문에 다른 (DOM 기반) 방법보다 더 간결하고 안전합니다.
- 또한, 커스터마이즈가 가능 더 캔버스 텍스트 속성을 수정하는 등,
textAlign
및textBaseline
.
참고 : 텍스트를 DOM에 추가 할 때 채우기, 여백 및 경계 도 고려해야합니다 .
참고 2 : 일부 브라우저에서이 방법은 하위 픽셀 정확도 (결과는 부동 소수점 수)를 생성하고 다른 브라우저에서는 그렇지 않습니다 (결과는 정수임). 불일치를 피하기 위해 결과에서 실행 Math.floor
(또는 Math.ceil
)을 원할 수 있습니다 . DOM 기반 방법은 절대 서브 픽셀 정확도가 아니기 때문에이 방법은 다른 방법보다 정확도가 훨씬 높습니다.
이 jsperf 에 따르면 (주석에 기여한 사람들에게 감사드립니다) 캐싱이 DOM 기반 방법에 추가되고 Firefox를 사용하지 않는 경우 Canvas 방법 과 DOM 기반 방법 이 거의 동일 합니다. Firefox에서 어떤 이유로 든이 Canvas 방법 은 DOM 기반 방법 (2014 년 9 월 기준) 보다 훨씬 빠릅니다 .
답변
여기에 예를 들지 않고 채찍질 한 것이 있습니다. 우리 모두 같은 페이지에있는 것 같습니다.
String.prototype.width = function(font) {
var f = font || '12px arial',
o = $('<div></div>')
.text(this)
.css({'position': 'absolute', 'float': 'left', 'white-space': 'nowrap', 'visibility': 'hidden', 'font': f})
.appendTo($('body')),
w = o.width();
o.remove();
return w;
}
그것을 사용하는 것은 간단합니다 : "a string".width()
** white-space: nowrap
창 너비보다 큰 너비의 문자열을 계산할 수 있도록 추가되었습니다 .
답변
jQuery :
(function($) {
$.textMetrics = function(el) {
var h = 0, w = 0;
var div = document.createElement('div');
document.body.appendChild(div);
$(div).css({
position: 'absolute',
left: -1000,
top: -1000,
display: 'none'
});
$(div).html($(el).html());
var styles = ['font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing'];
$(styles).each(function() {
var s = this.toString();
$(div).css(s, $(el).css(s));
});
h = $(div).outerHeight();
w = $(div).outerWidth();
$(div).remove();
var ret = {
height: h,
width: w
};
return ret;
}
})(jQuery);
답변
이것은 나를 위해 작동합니다 …
// Handy JavaScript to measure the size taken to render the supplied text;
// you can supply additional style information too if you have it.
function measureText(pText, pFontSize, pStyle) {
var lDiv = document.createElement('div');
document.body.appendChild(lDiv);
if (pStyle != null) {
lDiv.style = pStyle;
}
lDiv.style.fontSize = "" + pFontSize + "px";
lDiv.style.position = "absolute";
lDiv.style.left = -1000;
lDiv.style.top = -1000;
lDiv.innerHTML = pText;
var lResult = {
width: lDiv.clientWidth,
height: lDiv.clientHeight
};
document.body.removeChild(lDiv);
lDiv = null;
return lResult;
}
답변
의 ExtJS 자바 스크립트 라이브러리는 “정확히 얼마나 높은 확인할 수 있습니다 넓은 픽셀 단위로 텍스트의 특정 블록이 될 수 있도록 텍스트 블록에 대한 정확한 픽셀 측정을 제공한다”고 Ext.util.TextMetrics라는 큰 클래스를 가지고있다. 직접 사용하거나 소스를보고 코드 작성 방법을 확인할 수 있습니다.
http://docs.sencha.com/extjs/6.5.3/modern/Ext.util.TextMetrics.html
답변
나는 단지 정적 문자 너비 맵을하는 “단 하나의 아이디어”를 좋아합니다! 실제로 내 목적에 잘 작동합니다. 때로는 성능상의 이유로 또는 DOM에 쉽게 액세스 할 수 없기 때문에 단일 글꼴로 교정 된 빠른 해킹 독립형 계산기를 원할 수 있습니다. 여기 Helvetica에 보정 된 것이 있습니다; 문자열과 선택적으로 글꼴 크기를 전달하십시오.
function measureText(str, fontSize = 10) {
const widths = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.2796875,0.2765625,0.3546875,0.5546875,0.5546875,0.8890625,0.665625,0.190625,0.3328125,0.3328125,0.3890625,0.5828125,0.2765625,0.3328125,0.2765625,0.3015625,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.5546875,0.2765625,0.2765625,0.584375,0.5828125,0.584375,0.5546875,1.0140625,0.665625,0.665625,0.721875,0.721875,0.665625,0.609375,0.7765625,0.721875,0.2765625,0.5,0.665625,0.5546875,0.8328125,0.721875,0.7765625,0.665625,0.7765625,0.721875,0.665625,0.609375,0.721875,0.665625,0.94375,0.665625,0.665625,0.609375,0.2765625,0.3546875,0.2765625,0.4765625,0.5546875,0.3328125,0.5546875,0.5546875,0.5,0.5546875,0.5546875,0.2765625,0.5546875,0.5546875,0.221875,0.240625,0.5,0.221875,0.8328125,0.5546875,0.5546875,0.5546875,0.5546875,0.3328125,0.5,0.2765625,0.5546875,0.5,0.721875,0.5,0.5,0.5,0.3546875,0.259375,0.353125,0.5890625]
const avg = 0.5279276315789471
return str
.split('')
.map(c => c.charCodeAt(0) < widths.length ? widths[c.charCodeAt(0)] : avg)
.reduce((cur, acc) => acc + cur) * fontSize
}
그 거대한 추악한 배열은 문자 코드로 색인 된 ASCII 문자 너비입니다. 따라서 이것은 ASCII 만 지원합니다 (그렇지 않으면 평균 문자 너비를 가정합니다). 다행히도 너비는 기본적으로 글꼴 크기와 선형으로 확장되므로 모든 글꼴 크기에서 잘 작동합니다. 커닝이나 합자 등에 대한 인식이 눈에 띄게 부족합니다.
“교정”하기 위해 방금 svg에서 모든 문자를 charCode 126 (강한 물결표)까지 렌더링하고 경계 상자를 가져 와서이 배열에 저장했습니다. 더 많은 코드와 설명 및 데모는 여기에 있습니다 .