텍스트 너비 계산


101

jQuery를 사용하여 텍스트 너비를 계산하려고합니다. 나는 무엇인지 잘 모르겠지만 분명히 뭔가 잘못하고 있습니다.

따라서 다음은 코드입니다.

var c = $('.calltoaction');

var cTxt = c.text();

var cWidth =  cTxt.outerWidth();

c.css('width' , cWidth);

그렇다면 그 코드는 어떤 방식으로 작동하지 않습니까? 다르게 수행하려면 무엇이 필요합니까?
Sixten Otto

답변:


142

이것은 나를 위해 더 잘 작동했습니다.

$.fn.textWidth = function(){
  var html_org = $(this).html();
  var html_calc = '<span>' + html_org + '</span>';
  $(this).html(html_calc);
  var width = $(this).find('span:first').width();
  $(this).html(html_org);
  return width;
};

4
+1-이것은 brainreavis의 솔루션과 같은 포함 블록 요소뿐만 아니라 텍스트를 진정으로 측정합니다.

멋진. +1. '</span>'차이를 만들지 않는 것 같지만 세 번째 줄에 세미콜론이 누락 된 것 같습니다 (FF9에서 사용하거나 사용하지 않음).
shmeeps

21
그래도 조심하십시오 ...이 메서드는 자식 요소에 대한 모든 이벤트의 바인딩을 해제합니다.
brianreavis

이 함수를 여러 가지 방법으로 사용하려고 시도했지만 계속 null을 반환합니다. 누군가이 함수가 실제로 어떻게 사용되는지에 대한 구문을 게시 해 주시겠습니까? jQuery 객체에서 .textWidth () 함수를 실행합니까? 이 함수에 텍스트를 전달합니까? 함수를 jQuery 함수 (예 : $ .textWidth (jqObject))로 실행합니까? 이러한 옵션 중 어느 것도 작동하지 않는 것 같습니다. 감사합니다 ...
moosefetcher 2013-10-31

2
@moosefetcher 당신은 $ (selector) .textWidth (); 여기 봐 learn.jquery.com/plugins/basic-plugin-creation/...
uesports135

89

여기에 게시 된 다른 것보다 더 나은 기능이 있습니다.

  1. 더 짧다
  2. 통과 할 때 작동 <input>, <span>또는 "string".
  3. 기존 DOM 요소를 재사용하기 때문에 자주 사용하는 경우 더 빠릅니다.

데모 : http://jsfiddle.net/philfreo/MqM76/

// Calculate width of text from DOM element or string. By Phil Freo <http://philfreo.com>
$.fn.textWidth = function(text, font) {
    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
    $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
    return $.fn.textWidth.fakeEl.width();
};

1
와! 순수한 굉장함!
Michel Triana 2014

3
훌륭한 솔루션, 받아 들여야 할 대답입니다. 고마워, 친구!
Ilia Rostovtsev

판타 스티 코! 간단하고 깨끗합니다.
Carey Estes 2014

좋지만 이것은 공백을 처리하지 않습니다. 이 솔루션의 개선 사항은 @edsioufi의 답변을 참조하십시오.
Badgerspot

요소 내부에 숨겨진 텍스트가 있으면 너비가 기울어집니다. 이를 설명하려면 텍스트 너비를 계산하기 전에 숨겨진 노드를 제거해야합니다. 숨겨진 노드를 안전하게 제거하려면 먼저 복제본을 만들고 제거해야합니다.
thdoan 2014

36

내 솔루션

$.fn.textWidth = function(){
    var self = $(this),
        children = self.children(),
        calculator = $('<span style="display: inline-block;" />'),
        width;

    children.wrap(calculator);
    width = children.parent().width(); // parent = the calculator wrapper
    children.unwrap();
    return width;
};

기본적으로 룬보다 개선 된 것으로, .html그렇게 가볍게 사용하지 않습니다.


으로 Ajarn 게르하르트 : 대답으로이 게시 당신이 누락하고 있기 때문에 IE8에서 작업이하지 /의 닫기 괄호하기 전에 <span>: 태그calculator = $('<span style="display: inline-block;" />'),
페트르 R.

1
측정하는 요소 아래에 자식 요소가 있으면 null을 반환하는 것 같습니다. 자식 요소없이 작동하도록 만들 수 있습니까? 참조 jsfiddle.net/h22tj/41
캐스퍼

+1-나는 끝없는 슬픔을 유발하는 unwrap ()이 있다는 것을 결코 알지 못했습니다.
Orwellophile

Chrome에서는 항상 null을 반환합니다.
emeraldhieu

12

textWidth답을 제공 기능은 동의 string공백을 앞뒤를 고려하지 않을 인자 (이들의 더미 용기 렌더링하지 않음)한다. 또한 텍스트에 html 마크 업이 포함되어 있으면 작동하지 않습니다 (하위 문자열 <br>은 출력을 생성하지 않고 &nbsp;한 공백의 길이를 반환합니다).

textWidth이것은를 받아들이 는 함수 의 문제 일뿐입니다. string왜냐하면 DOM 요소가 주어지고 요소에 대해 .html()호출되면 그러한 사용 사례에 대해 이것을 수정할 필요가 없기 때문입니다.

그러나 예를 들어 사용자가 입력 할 때 텍스트 input요소 의 너비를 동적으로 수정하기 위해 텍스트 너비를 계산하는 경우 (현재 사용 사례), 선행 및 후행 공백을 &nbsp;문자열 로 바꾸고 인코딩 할 수 있습니다. html로.

나는 philfreo의 솔루션을 사용했기 때문에 이것을 수정하는 버전이 있습니다 (추가에 대한 의견 포함).

$.fn.textWidth = function(text, font) {
    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').appendTo(document.body);
    var htmlText = text || this.val() || this.text();
    htmlText = $.fn.textWidth.fakeEl.text(htmlText).html(); //encode to Html
    htmlText = htmlText.replace(/\s/g, "&nbsp;"); //replace trailing and leading spaces
    $.fn.textWidth.fakeEl.html(htmlText).css('font', font || this.css('font'));
    return $.fn.textWidth.fakeEl.width();
};

감사. 귀하의 답변이 가장 중요합니다.
Vishal

1
이상하게도 이것을 시도했을 때 font-size. 나는 css('font-size'), this.css('font-size'))그것이 작동 하도록 추가 해야했다. font혼자서 그 가치를 복사하지 않는 이유 는 무엇입니까?
Gone Coding

@GoneCoding 그 엑스트라를 어디에 추가 했습니까?
webmagnets

@webmagnets : 기존 .css방법 과 같은 위치 이지만 괄호가 잘못되었습니다. 이어야 css('font-size', this.css('font-size'))합니다.
Gone Coding

11

일관되지 않은 상자 모델로 인해 텍스트 너비를 결정하려고 할 때 jQuery의 너비 함수가 약간 그늘 질 수 있습니다. 확실한 방법은 실제 텍스트 너비를 결정하기 위해 요소 내부에 div를 삽입하는 것입니다.

$.fn.textWidth = function(){
  var sensor = $('<div />').css({margin: 0, padding: 0});
  $(this).append(sensor);
  var width = sensor.width();
  sensor.remove();
  return width;
};

이 미니 플러그인을 사용하려면 다음을 수행하십시오.

$('.calltoaction').textWidth();

1
이것은 텍스트가 아닌 블록 너비를 제공하지 않습니까?
Josh Rickard

-1 이것은 실제로 텍스트 너비보다는 상자의 너비를 측정하는 것 같습니다.
Nathan Arthur

1
div 대신 스팬을 사용하여 너비 문제를 해결하지 않겠습니까? 그렇다면이 함수는 허용되는 답변보다 약간 낫습니다.
Josh

@Josh : a로 바꾸면 span0이됩니다. H2부모 요소에 오버플로가 숨겨져있는 에서이 솔루션을 시도 했으며 텍스트의 잘린 길이 만 얻습니다. 아마도 이것이 어떻게 작동 하는지에 대한 설명이 더 잘 작동하도록 도울 것입니까?
Gone Coding

8

이 솔루션이 잘 작동하고 크기 조정 전에 원본 글꼴을 상속한다는 것을 알았습니다.

$.fn.textWidth = function(text){
  var org = $(this)
  var html = $('<span style="postion:absolute;width:auto;left:-9999px">' + (text || org.html()) + '</span>');
  if (!text) {
    html.css("font-family", org.css("font-family"));
    html.css("font-size", org.css("font-size"));
  }
  $('body').append(html);
  var width = html.width();
  html.remove();
  return width;
}

1
나는 이것을 사용했지만 org.css("font-weight"). 또한 if(!text)부분이 직관적이지 않다고 말하고 싶습니다 . 예를 들어 사용 jQuery("#someContainer").textWidth("Lorem ipsum")하면 특정 컨테이너에 적용될 때 "Lorem ipsum"의 텍스트 너비를 알고 싶습니다.
Sleavely 2012-06-20

8

텍스트를 담고있는 요소의 너비가 고정 된 경우 룬과 브레인 모두 저에게 효과가 없었습니다. 나는 Okamera와 비슷한 것을했다. 더 적은 선택자를 사용합니다.

편집 : font-size다음 코드가 htmlCalc요소를 삽입 body하여 부모 관계에 대한 정보를 잃어 버리기 때문에 relative를 사용하는 요소에서는 작동하지 않을 것입니다 .

$.fn.textWidth = function() {
    var htmlCalc = $('<span>' + this.html() + '</span>');
    htmlCalc.css('font-size', this.css('font-size'))
            .hide()
            .prependTo('body');
    var width = htmlCalc.width();
    htmlCalc.remove();
    return width;
};

이것은 IE8을 지원하는 나에게 가장 적합한 솔루션이었으며 프로세스의 요소에 대한 바인딩을 끊지 않습니다! 고마워.
ouija

참고 : jQuery 확장 메서드에서는 this이미 jQuery 객체이므로 $(this)중복됩니다.
Gone Coding

계산 된 너비가 너무 작다는 점에서 이것은 잘못되었습니다. 허용 대답은 제대로 일
PandaWood

5

선택 상자의 텍스트로이 작업을 수행하거나 두 가지가 작동하지 않는 경우 대신 다음을 시도하십시오.

$.fn.textWidth = function(){
 var calc = '<span style="display:none">' + $(this).text() + '</span>';
 $('body').append(calc);
 var width = $('body').find('span:last').width();
 $('body').find('span:last').remove();
 return width;
};

또는

function textWidth(text){
 var calc = '<span style="display:none">' + text + '</span>';
 $('body').append(calc);
 var width = $('body').find('span:last').width();
 $('body').find('span:last').remove();
 return width;
};

먼저 텍스트를 잡고 싶다면


4

문제는 cTxt에서 메소드를 호출하고 있다는 것입니다. 이는 jQuery 객체가 아닌 단순한 문자열입니다. cTxt는 실제로 포함 된 텍스트입니다.


2

.children ()은 h1 또는 p 와 같은 텍스트 요소를 참조하는 경우 빈 집합을 반환하므로 Nico에 약간의 변경이 있습니다 . 그래서 우리는 대신 .contents ()를 사용 하고 jQuery 객체에 메서드를 생성하고 있기 때문에 $ (this) 대신 이것을 사용합니다.

$.fn.textWidth = function(){
    var contents = this.contents(),
        wrapper  = '<span style="display: inline-block;" />',
        width    = '';

    contents.wrapAll(wrapper);
    width = contents.parent().width(); // parent is now the wrapper
    contents.unwrap();
    return width;
    };

1

이틀 동안 유령을 쫓다가 텍스트의 너비가 잘못된 이유를 알아 내다 보면 너비 계산이 중단되는 텍스트 문자열의 공백 때문이라는 것을 깨달았습니다.

따라서 또 다른 팁은 공백이 문제를 일으키는 지 확인하는 것입니다. 사용하다

&nbsp;

깨지지 않는 공간을 확인하고 문제가 해결되는지 확인하십시오.

사람들이 제안한 다른 기능도 잘 작동하지만 문제를 일으키는 공백이었습니다.


white-space: nowrap이를 피하기 위해 인라인 CSS에 일시적으로 추가 하십시오.
Gone Coding

1

주어진 요소 내에서 텍스트 노드와 요소의 혼합 너비를 결정하려는 경우 모든 콘텐츠를 wrapInner () 로 래핑 하고 너비를 계산 한 다음 콘텐츠를 풀어야 합니다.

* 참고 : unwrapInner () 함수는 기본적으로 제공되지 않으므로 jQuery를 확장하여 추가해야합니다.

$.fn.extend({
  unwrapInner: function(selector) {
      return this.each(function() {
          var t = this,
              c = $(t).children(selector);
          if (c.length === 1) {
              c.contents().appendTo(t);
              c.remove();
          }
      });
  },
  textWidth: function() {
    var self = $(this);
    $(this).wrapInner('<span id="text-width-calc"></span>');
    var width = $(this).find('#text-width-calc').width();
    $(this).unwrapInner();
    return width;
  }
});

.wrapInner의 경우 +1. 아시다시피 jQuery에서 순수한 텍스트 요소를 다루는 것은 지옥입니다. 적용 가능한 다른 jQuery 메소드가 있으면 알려주십시오. .get (0) .children에 의지해야했는데 예쁘지 않습니다.
Orwellophile

1

@philfreo의 답변을 확장하십시오.

나는 일반적으로 텍스트를 더 넓게 만드는 경향이 있기 text-transform때문에 확인하는 기능을 추가했습니다 text-transform: uppercase.

$.fn.textWidth = function (text, font, transform) {
    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
    $.fn.textWidth.fakeEl.text(text || this.val() || this.text())
        .css('font', font || this.css('font'))
        .css('text-transform', transform || this.css('text-transform'));
    return $.fn.textWidth.fakeEl.width();
};

0
var calc = '<span style="display:none; margin:0 0 0 -999px">' + $('.move').text() + '</span>';

0

getColumnWidth ()를 호출하여 텍스트를 가져옵니다. 이것은 완벽하게 잘 작동합니다.

someFile.css
.columnClass { 
    font-family: Verdana;
    font-size: 11px;
    font-weight: normal;
}


function getColumnWidth(columnClass,text) { 
    tempSpan = $('<span id="tempColumnWidth" class="'+columnClass+'" style="display:none">' + text + '</span>')
          .appendTo($('body'));
    columnWidth = tempSpan.width();
    tempSpan.remove();
return columnWidth;
}

참고 :-인라인 .css를 원하는 경우 글꼴 세부 정보를 스타일로만 전달하십시오.


0

나는 니코의 코드를 내 필요에 맞게 수정했습니다.

$.fn.textWidth = function(){
    var self = $(this),
        children = self.contents(),
        calculator = $('<span style="white-space:nowrap;" />'),
        width;

    children.wrap(calculator);
    width = children.parent().width(); // parent = the calculator wrapper
    children.unwrap();
    return width;
};

내가 사용하고 .contents () 내가 필요한 텍스트 노드를 반환하지 않습니다 .children 등을 (). 또한 반환 된 너비가 줄 바꿈을 유발하는 뷰포트 너비의 영향을 받았으므로 white-space : nowrap; 뷰포트 너비에 관계없이 올바른 너비를 얻으려면


0
$.fn.textWidth = function(){
        var w = $('body').append($('<span stlye="display:none;" id="textWidth"/>')).find('#textWidth').html($(this).html()[0]).width();
        $('#textWidth').remove();
        console.log(w);
        return w;
    };

거의 하나의 라이너. 첫 번째 캐릭터와 함께 제공


0

나열된 솔루션 중 어떤 것도 100 % 작동하지 않았으므로 @chmurson (@Okamera를 기반으로 함)의 아이디어와 @philfreo의 아이디어를 기반 으로이 하이브리드 를 생각해 냈습니다.

(function ($)
{
    var calc;
    $.fn.textWidth = function ()
    {
        // Only create the dummy element once
        calc = calc || $('<span>').css('font', this.css('font')).css({'font-size': this.css('font-size'), display: 'none', 'white-space': 'nowrap' }).appendTo('body');
        var width = calc.html(this.html()).width();
        // Empty out the content until next time - not needed, but cleaner
        calc.empty();
        return width;
    };
})(jQuery);

노트:

  • thisjQuery 확장 메서드 내부에는 이미 jQuery 객체가 있으므로 $(this)많은 예제에있는 모든 추가 항목 이 필요하지 않습니다 .
  • 바디에 더미 요소를 한 번만 추가하고 다시 사용합니다.
  • 또한을 지정해야합니다 (다른 페이지 스타일을 기반으로 한 줄 바꿈이 아닌 한 줄로white-space: nowrap 측정 ).
  • 나는 이것을 font단독으로 사용하여 작동시킬 수 없으며 명시 적으로 복사해야했습니다 font-size. 아직 이유가 확실하지 않습니다 (여전히 조사 중).
  • 이 방식 은 입력 필드를 지원 하지 않습니다@philfreo .

0

때로는 높이텍스트 뿐만 아니라 HTML 너비 도 추가로 측정해야합니다 . @philfreo 답변을 받아 더 유연하고 유용하게 만들었습니다.

function htmlDimensions(html, font) {
  if (!htmlDimensions.dummyEl) {
    htmlDimensions.dummyEl = $('<div>').hide().appendTo(document.body);
  }
  htmlDimensions.dummyEl.html(html).css('font', font);
  return {
    height: htmlDimensions.dummyEl.height(),
    width: htmlDimensions.dummyEl.width()
  };
}

0

텍스트 너비는 부모마다 다를 수 있습니다. 예를 들어 h1 태그에 텍스트를 추가하면 div 또는 레이블보다 넓어 지므로 내 솔루션은 다음과 같습니다.

<h1 id="header1">

</h1>

alert(calcTextWidth("bir iki", $("#header1")));

function calcTextWidth(text, parentElem){
    var Elem = $("<label></label>").css("display", "none").text(text);
    parentElem.append(Elem);
  var width = Elem.width();
  Elem.remove();
    return width;
}

0

많은 양의 텍스트에 대해 @ rune-kaagaard와 같은 솔루션에 문제가있었습니다. 나는 이것을 발견했다 :

$.fn.textWidth = function() {
	var width = 0;
	var calc = '<span style="display: block; width: 100%; overflow-y: scroll; white-space: nowrap;" class="textwidth"><span>' + $(this).html() + '</span></span>';
	$('body').append(calc);
	var last = $('body').find('span.textwidth:last');
	if (last) {
			var lastcontent = last.find('span');
			width = lastcontent.width();
			last.remove();
	}
	return width;
};

JSFiddle GitHub


-1

나는 당신이 사용해야한다고 생각합니다 $('.calltoaction').val;

또한, 나는 그것을 위해 클래스 대신 id (#)를 사용할 것입니다 .. 만약 u가 그것을 어떻게 처리 할 그런 클래스 중 하나 이상을 가지고 있다면?


예, 문서에 하나 이상이 있습니다. 왜 이드를 제안하겠습니까?
Dom
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.