计算文字宽度

我试图用jQuery来计算文字宽度。 我不知道是什么,但我肯定是做错了什么。

所以,这里是代码:

var c = $('.calltoaction'); var cTxt = c.text(); var cWidth = cTxt.outerWidth(); c.css('width' , cWidth); 

这对我更好:

 $.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; }; 

这是一个比其他人更好的function,因为

  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(); }; 

我的解决scheme

 $.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

当由于不一致的盒子模型而试图确定文本宽度时,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(); 

在答案中提供的接受string作为参数的textWidth函数不会考虑前导和尾随的空白(那些不在虚拟容器中呈现的)。 另外,如果文本包含任何html标记(子string<br>将不会生成任何输出,并且将返回一个空格的长度),则它们将不起作用。

这只是接受stringtextWidth函数的一个问题,因为如果给出了DOM元素,并且在元素上调用了.html() ,那么可能不需要为这样的用例解决这个问题。

但是,例如,如果您正在计算文本的宽度,以随着用户types(我当前的用例)的typesdynamic修改文本input元素的宽度,则可能需要用&nbsp;replace前导和尾随空格&nbsp; 并将该string编码为html。

我用philfreo的解决scheme,所以这里是它的一个版本,修正了这一点(附加评论):

 $.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(); }; 

我发现这个解决scheme效果很好,它在resize之前inheritance了原始字体:

 $.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; } 

如果拿着文本的元素具有固定的宽度,符文和大脑都不为我工作。 我做了一些和Okamera类似的东西。 它使用较less的select器。

编辑:它不会工作的元素,使用相对的font-size ,因为下面的代码插入htmlCalc元素到body从而失去了有关父母关系的信息。

 $.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; }; 

如果你试图用select框中的文字来做到这一点,或者如果这两个不工作尝试这一个:

 $.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; }; 

如果你想抢先文字

事情,你做错了,你正在调用cTxt的方法,这是一个简单的string,而不是一个jQuery对象。 cTxt实际上是包含的文本。

稍微改变为Nico's,因为如果我们引用像h1p这样的文本元素,.children()将返回一个空集。 所以我们将使用.contents()来代替$(this),因为我们正在jQuery对象上创build一个方法。

 $.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; }; 

在追了两天的幽灵后,试图弄清楚为什么文本的宽度不正确,我意识到这是因为文本string中的空格会停止宽度计算。

所以,另一个技巧是检查空白是否造成问题。 使用

 &nbsp; 

没有突破的空间,看看是否能解决这个问题。

人们build议的其他function也很好,但这是造成麻烦的空白。

如果您正在尝试确定给定元素中文本节点和元素的混合宽度,则需要使用wrapInner()来包装所有内容,计算宽度,然后展开内容。

*注意:您还需要扩展jQuery来添加一个unwrapInner()函数,因为它不是默认提供的。

 $.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; } }); 

扩展@ 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(); }; 
 var calc = '<span style="display:none; margin:0 0 0 -999px">' + $('.move').text() + '</span>'; 

调用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; } 

注意: – 如果您希望inline .css仅以样式传递font-details。

我修改了Nico的代码来满足我的需求。

 $.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()不会返回我需要的文本节点。 我还发现,返回的宽度受到视口宽度的影响,导致包装,所以我使用空白:nowrap; 无论视口宽度如何都能获得正确的宽度。

 $.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; }; 

几乎是一个class轮。 给你第一个字符

我无法得到任何上市的解决scheme100%的工作,所以想出了这个混合 ,基于@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); 

笔记:

  • this里面的一个jQuery扩展方法已经是一个jQuery对象,所以不需要所有额外的$(this)那么多的例子。
  • 它只添加虚拟元素到身体一次,并重新使用它。
  • 你还应该指定white-space: nowrap ,只是为了确保它测量为单行 (而不是基于其他页面样式的换行)。
  • 我无法单独使用font ,也不得不明确复制font-size 。 不知道为什么(仍在调查)。
  • 支持@philfreoinput字段。

有时候你还需要额外的高度来衡量,不仅仅是文字 ,还要测量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() }; } 

我想你应该使用$('.calltoaction').val;

另外,我会使用id(#)而不是类。如果你有不止一个这样的类,它将如何处理它?