0

我正在为带有旧 Gecko 引擎(我认为是 1.9)的电视开发应用程序。我有一个 250x40 的容器,我想在其中放置2 行文本,如果它太长,则应该显示一个省略号(就像在 CSS3 属性中一样text-overflow: ellipsis)。

但是: - 我不能使用 CSS3, - 我尝试使用一些 jQuery 插件,但是它们工作得太慢了 - 你可以准确地看到文本被缩小,直到它适合容器。

我试着数字母,但它不起作用,因为它们都是不同的宽度。我尝试将每个字母映射到它的宽度,并计算整个文本的宽度,但是它是 2 行的事实把它搞砸了——我不知道文本会在什么时候进入下一行。

任何帮助表示赞赏。

4

3 回答 3

3

稍微基于@Emissary的回答,这是一对性能合理的jQuery插件,可以处理在可能包含多行文本的元素上添加省略号:

(function($) {

    $.fn.reflow = function() {
        return this.each(function() {

            var $this = $(this);
            var $parent = $this.parent();
            var text = $this.data('reflow');
            $this.text(text);               // try full text again

            var words = text.split(' ');
            while ($this.height() > $parent.height() ||
                   $this.width() > $parent.width()) {
                words.pop();
                $this.html(words.join(' ') + '…');
            }
        });
    }

    $.fn.overflow = function() {
        return this.each(function() {
            var $this = $(this);
            var text = $this.text();
            $this.data('reflow', text);
        }).reflow();
    }

})(jQuery);

后者注册用于回流的元素,而第一个实际上完成了工作。拆分是为了允许调整窗口大小以自动重新格式化元素的(原始)内容,例如:

$('.overflow').overflow();
$(window).on('resize', function() {
    $('.overflow').reflow();
});

为了获得更高的性能,如果重要的话,您可以考虑将.pop序列替换为使用O(log n)二进制分区算法来找到最佳切割点的东西,而不是一次只删除一个单词。

http://jsfiddle.net/alnitak/vyth5/

于 2013-10-27T20:01:18.297 回答
1

这里的这一章有一个使用 javascript 而没有 JQuery 的解决方案:http: //blog.mastykarz.nl/measuring-the-length-of-a-string-in-pixels-using-javascript/

在 jsfiddle 中完成:http: //jsfiddle.net/ZfDYG/

编辑 - 只需阅读大约 2 行文本:http: //jsfiddle.net/ZfDYG/8/

代码(为了完整性):

String.prototype.visualLength = function() {
  var ruler = $("ruler");
  ruler.innerHTML = this;
  return ruler.offsetWidth;
}
function $(id) {
  return document.getElementById(id);
}
var s = "Some text that is quite long and probably too long to fit in the box";
var len = s.visualLength();

String.prototype.trimToPx = function(length,postfix) {
  postfix = postfix || '';
  var tmp = this;
  var trimmed = this;
  if (tmp.visualLength() > length) {
    trimmed += postfix;
    while (trimmed.visualLength() > length) {
      tmp = tmp.substring(0, tmp.length-1);
      trimmed = tmp + postfix;
    }
  }

  return trimmed;
}
String.prototype.wrapToLength = function(complete) {
  if(complete[this.length] == ' ' || complete[this.length - 1] == ' ') return;

  var wrapped = this;
  var found = false;
  for(var i = this.length-1; i > 0 && !found; i--) {
    if(this[i] == ' ') { 
      wrapped = this.substring(0, i); 
      found = true; 
    }
  }
  return wrapped;
}
var firstLine = s.trimToPx(240).wrapToLength(s);
var secondLine = s.substring(firstLine.length, s.length);
$('output').innerHTML= firstLine+' '+secondLine.trimToPx(240,'...');

html:

<span id="ruler"></span>
<div id="output"></div>

CSS:

#ruler { visibility: hidden; white-space: nowrap; }
#output { 
  width: 240px;
  height: 50px;
  border: 1px solid red;
}

如果这在您的盒子上仍然太慢,我想应该可以通过从更大的添加开始以向最终长度(有点像弹簧)振荡而不是慢慢增加来加速while循环。

于 2013-10-27T19:11:16.320 回答
1

自从我为支持旧版浏览器而烦恼已经有一段时间了,但这就是我一直这样做的方式。应该指出它修剪的是单词而不是字符,我一直认为半个单词看起来很愚蠢-如果您关心排版...

html:

<div id="el">
    <span class="overflow">Lorem ipsum dolor sit amet</span>
</div>

CSS:

#el { 
    width: 250px;
    height: 40px;
    overflow: hidden;
}
.overflow {
    white-space: nowrap;
}

js / jQuery的:

var el = $('#el'),
    ov = $('#el .overflow'),
    w = el.text().split(' ');
while(ov.width() > el.width()){ 
    w.pop();     
    ov.html( w.join(' ') + '&hellip;' );
}

jsFiddle

于 2013-10-27T19:13:57.320 回答