텍스트 너비 계산


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.