将特定目标词移到单词允许的最佳水平中心
您可以使用非常简单的JavaScript实现粗略居中。它只是沿着标记扫描,将找到的第一个TextNode转换为用<span>
包装的“单词”,然后尝试并出错地插入换行符,直到找到将目标单词最接近中心的那个。
在fiddle中,我已经用红色突出显示了代码认为应该在其后断开的跨度,并用绿色表示目标词。在大多数情况下,它做得很好,有一些情况可能会使单词单独成行 - 但是,这可以通过调整代码来修复到您的确切用例。
以防万一,人们不知道这是可以实现的示例,绝不是完美的 - 没有代码是完美的,因为它总是可以改进和应该改进的。
fiddle
http://jsfiddle.net/s8XgJ/2/
更新的fiddle,显示具有随机目标词的行为:
http://jsfiddle.net/s8XgJ/3/
标记
<center>
Once upon a time, there was a squirrel who lived in the
<span class="centered">middle</span> of the forest. I
say middle, but without knowing where the edges were,
the squirrel had no idea where the center was.
</center>
我大致保留了您的标记,但正如其他人所说,应避免使用center标签。我还将内部div转换为span以保留行内间距。如果您无法这样做,仍然可以使用div,只需覆盖其正常显示为display:inline-block;
JavaScript / jQuery
jQuery.fn.findYourCenter = function( target ){
base = $(this); target = base.children(target);
base.contents().eq(0).each(function(){
var i = -1, word, words, found, dif,
last = Infinity,
node = $(this),
text = node.text().split(/\s+/),
cwidth = Math.round(target.width() * 0.5),
bwidth = Math.round(base.width() * 0.5),
breaks = 2
;
node.replaceWith(
'<span class="word">'+text.join(' </span><span class="word">')+' </span>'
);
words = base.find('.word');
do {
while ( ++i < words.length ){
word && word.removeClass('clear');
word = words.eq(i).addClass('clear');
dif = Math.round(Math.abs((target.position().left + cwidth) - bwidth));
if ( dif < last ) { last = dif; found = i; }
}
word.removeClass('clear');
if ( found ) {
words.eq(found).addClass('clear');
i = found; found = word = null;
}
else {
break;
}
} while ( i < words.length && --breaks );
});
};
我使用了jQuery来简化。
CSS
您需要此CSS项:
.clear:after {
content: '';
display: block;
clear: both;
}
如果您的 .centered
元素是一个 <div>
,那么可能还需要添加以下内容:
.centered {
display: inline-block;
}
那么您所需要执行的就是:
jQuery(function($){
$('center').findYourCenter('.centered');
});
问题
为了精确对齐,你需要偏移一些东西——因为根据单词的长度(和位置),你不能总是同时实现段落、行和目标单词的完美中心。上述代码仍然保持了行的居中,代价是目标单词被偏移。如果想以行为代价来让单词居中,可以改进上述方法,对包含目标的行进行边距调整。
目前,如果目标单词出现在前五个单词中,居中可能难以实现,基本上是因为这种方法依赖于单词换行和断行。如果由于单词位于段落开头而无法使用这两种情况,则除了引入边距、填充或文本缩进之外,无可奈何。
这段代码依赖于能够正确读取元素的位置。旧版浏览器(如IE6和早期版本的Safari/Opera)存在这方面的问题。
还有一件事要注意。这段代码依赖于浏览器在同步执行循环中立即重新计算其内部测量值。大多数现代浏览器似乎都会这样做——在大多数情况下——但你可能会发现你需要实现setTimeout(func, 0)
或setImmediate
延迟,以使其在旧系统上正常工作。
...最后
这是一个相当疯狂的请求,它到底是为了什么? :)
div
内使用span
元素(如果需要的话)。但是,如果你能解释一下你想要实现什么,也许有更好的解决方案!? - Netsurfer