更改多行文本中每行的文本对齐方式

Changing text alignment for each line in multi-line text

本文关键字:文本 对齐 方式      更新时间:2023-09-26

在旧报纸上,如果文章的标题超过三行,通常会像这样居中(图(:

|RACKET KINGPINS       |
|    ARE ROUNDED UP    |
|       IN BOMB KILLING|

也就是说,第一行的对齐方式是左、中、右。类似地,对于两行以上的标题,第一行左对齐,第二行右对齐。对于一句俏皮话,标题将居中。

我一直试图在我正在研究的主题中模仿这一点,但问题是,我如何将台词彼此分开?当然,每篇文章的标题都不包含任何实际的硬编码换行符,而是根据宽度限制自动换行,所以我不能只寻找换行符来分割DOM的innerHTML

那么你会怎么做呢?

(如果不清楚的话,我欢迎JavaScript解决方案(

您可以尝试循环所有字符,在每个循环中,将当前字符选择到范围对象中,然后使用范围对象的getBoundingClientRect()方法来获得字符rect的bottom。这是我们检测每一行结尾字符的方法。以下是检测结束字符的标志:

  1. 如果我们使用普通换行,所有的行都应该在某个空格字符处换行。特别的是,在这种情况下,结束空间字符将具有rect(从getBoundingClientRect()获得(,topbottom都是0
  2. 如果我们像word-break:break-all一样使用换行,那么结束字符可能是其他字符(而不是空格字符(。在这种情况下,我们将检测结束字符后面的下一个字符,下一个角色的bottom与结束字符的bottom不同

所以这确实相当复杂。事实上,一开始我以为我们只有一个病例(第二个病例(,但如果我们忽略第一个病例,我们会有意想不到的结果。因此,首先我们需要检查第一种情况,然后检查第二种情况。现在,检测每一行中的结束字符可以帮助我们将整个文本分隔成单独的行。然后,我们可以用appropriate样式集将每一行包装在div元素中(以对齐每一行中的文本(。

这是演示的代码:

HTML

<h3>Original column</h3>
<div class='o-column'>racket kingpins are rounded up in bomb killing</div>
<h3>Column after adjusted</h3>
<div class='column'>racket kingpins are rounded up in bomb killing</div>

CSS

.column, .o-column {
  width:300px;  
  border:1px solid black;
  margin-bottom:5px;
  text-transform:uppercase;
  padding:5px;    
  font-size:30px;
  font-family:'Arial';
  word-wrap:break-word;
}

JS

console.clear();
var column = document.querySelector('.column');
var ends = [];
var range = document.createRange();
range.selectNodeContents(column);
var lines = [];
var lastBottom = null;
//if the innerHTML has some 'n character, there will be some unexpected
//behavior, all the 'n characters should be removed first.
column.innerHTML = column.innerHTML.replace(/'n/g,'');
var len = column.innerHTML.length;
for(var i = 0; i < len; i++){    
  //set range for current character
  range.setStart(column.childNodes[0],i);
  range.setEnd(column.childNodes[0],i+1);
  var rect = range.getBoundingClientRect();    
  if((rect.bottom == 0 && rect.top == 0) ||
    rect.bottom != lastBottom && lastBottom != null || i == len-1){
    var line = document.createElement('div');
    var lineStart = ends.length ? ends[ends.length - 1] + 1 : 0;
    line.innerHTML = column.innerHTML.substring(lineStart, i == len - 1 ? len : i);
    lines.push(line);
    ends.push(rect.bottom ? i - 1 : i);    
  }
  if(rect.bottom != 0) lastBottom = rect.bottom;
  else lastBottom = null;
  if(ends.length > 3) break;
}
var n = lines.length;
//we align each line only if there are less than 4 lines
if(n < 4 && n > 0){
  column.innerHTML = "";    
  for(var i = 0; i < n; i++){
    column.appendChild(lines[i]);
  }
  if(n == 1) lines[0].style.textAlign = 'center';
  else {        
    lines[0].style.textAlign = 'left';        
    lines[n-1].style.textAlign = 'right';
    if(n == 3) lines[1].style.textAlign = 'center';
  }
}

演示

如果没有JavaScript,你就做不到

这是HTML/CSS的局限性之一。如果您需要打印功能来控制文本的确切位置和大小,请使用PDF。

如果没有JavaScript,你就无法预测一个段落是否会跨越多行以及跨越多少行,因为用户:

  • 可能没有安装相同的字体,

  • 或者可能已将文本配置为在浏览器中显示得更大。

你可以:

  1. 手动添加换行符,在大多数情况下,每条线的宽度都将低于容器的宽度

  2. 禁止断线(white-space: nowrap;(和:

  3. 根据需要将三条线对齐。

使用JavaScript,您可以通过计算实际行数,然后逐个字符减少文本,直到得到两行,然后是一行,从而确定可以插入换行符的确切位置,从而确定换行符的位置。

我觉得这已经够让人生气的了,但这只是我的看法。另一方面,您可能会注意,一旦加载页面,对用户配置的更改(如旧浏览器中使用的纯文本缩放(可能会破坏布局。

您可以创建一个函数,将字符串explode转换为javascript中的字符数组,然后根据需要操作该数组。

在分解字符串之前,您可以在字符串上使用pr制作的"换行"函数,从而使操作更容易,这样标题将自动根据最大宽度规范提前适当插入'n字符。

然后,在分解之后,您只需要通过在'n断点处将部分插入数组中来将它们封装在div中,并根据需要使用css类将它们排列起来。

然后implode将数组重新转换成字符串。。。