我有一个页面,其中包含许多以网格布局的div。每个div都有文本。我希望文本足够大以填补div。我这样做是通过增加文本大小直到我检测到div已经滚动,然后返回,根据这个答案:
Auto-size dynamic text to fill div
这在大多数浏览器上都很有效,包括移动浏览器,但在IE10上它非常慢。你可以实际观察它使文字变小。我猜测每次字体大小改变时它都会进行某种窗口范围的布局操作。
知道如何暂停重绘,直到完成所有div或以其他方式提高性能?
这是一个显示该技术的简单小提琴。想象一下,页面上有大约50个div。立即使用Chrome浏览器,在IE10中需要几秒钟:
(function($) {
$.fn.textfill = function(options) {
var fontSize = options.maxFontPixels;
var ourText = $('span:visible:first', this);
var maxHeight = $(this).height();
var maxWidth = $(this).width();
var textHeight;
var textWidth;
do {
ourText.css('font-size', fontSize);
textHeight = ourText.height();
textWidth = ourText.width();
fontSize = fontSize - 1;
} while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);
return this;
}
})(jQuery);
$(document).ready(function() {
$('.jtextfill').textfill({ maxFontPixels: 200 });
});
jsfiddle:http://jsfiddle.net/pRJdY/
答案 0 :(得分:0)
jsFiddle失败,因为jQuery jsFiddle引用的版本中存在一个错误http://bugs.jquery.com/ticket/13980。
所以我创建了一个本地版本的示例。我想我看到你在谈论什么,但并不完全确定。我看到它从正常的小文本变得更大,但它发生得非常快。我在Chrome中看到了相同的行为。所以我的猜测是,直到我在页面上有数千个元素,我可能无法重新创建您的问题。
我确实优化了你的JavaScript,所以我希望能帮你解决一下:
(function ($) {
$.fn.textfill = function (options) {
var $this = $(this),
fontSize = options.maxFontPixels,
ourText = $('span:visible:first', this),
maxHeight = $this.height(),
maxWidth = $this.width(),
textHeight,
textWidth;
do {
ourText.css('font-size', fontSize);
textHeight = ourText.height();
textWidth = ourText.width();
fontSize = fontSize - 1;
} while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);
return this;
}
})(jQuery);
答案 1 :(得分:0)
问题是大量的DOM访问。幸运的是,您的算法可以大大优化。
从200px fontsize开始下降,当你最终以10-30px结束时非常慢。最好上去,更好地进行二进制搜索以获得正确的大小。
从最小尺寸开始,上升速度提高5倍,在这种情况下,至少:http://jsfiddle.net/pRJdY/2/
二进制搜索再次将所需时间缩短一半:http://jsfiddle.net/pRJdY/4/
(function($) {
$.fn.textfill = function(options) {
var start = (new Date).getTime(),
node = $(this),
max = options.maxFontPixels,
min = 3,
span = $('span:visible:first', this),
maxHeight = node.height(),
maxWidth = node.width(),
size,
isTooBig,
finalSize = null;
do {
console.log(size);
size = Math.round((min + max) / 2);
span.css('font-size', size);
isTooBig = (span.height() > maxHeight || span.width() > maxWidth);
if (isTooBig) {
max = size - 1;
} else {
min = size;
}
if (min === max) {
finalSize = max;
}
} while (finalSize === null);
span.css('font-size', finalSize);
console.log('elements:', node.size(), 'elapsed time:', (new Date).getTime() - start);
return this;
}
})(jQuery);