计算文字宽度
我试图用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,因为
- 它更短
- 它在传递
<input>
,<span>
或"string"
时起作用。 - 频繁使用会更快,因为它重用了现有的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>
将不会生成任何输出,并且将返回一个空格的长度),则它们将不起作用。
这只是接受string
的textWidth
函数的一个问题,因为如果给出了DOM元素,并且在元素上调用了.html()
,那么可能不需要为这样的用例解决这个问题。
但是,例如,如果您正在计算文本的宽度,以随着用户types(我当前的用例)的typesdynamic修改文本input
元素的宽度,则可能需要用
replace前导和尾随空格
并将该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, " "); //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,因为如果我们引用像h1或p这样的文本元素,.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中的空格会停止宽度计算。
所以,另一个技巧是检查空白是否造成问题。 使用
没有突破的空间,看看是否能解决这个问题。
人们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
。 不知道为什么(仍在调查)。 - 这不支持
@philfreo
input字段。
有时候你还需要额外的高度来衡量,不仅仅是文字 ,还要测量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(#)而不是类。如果你有不止一个这样的类,它将如何处理它?