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

标签 javascript html css dom text-align

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

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

即第一行的对齐方式是左对齐,第二行居中,第三行右对齐。类似地,对于跨越两行的标题,第一行左对齐,第二行右对齐。对于单行,标题将居中。

我一直在尝试针对我正在研究的主题模仿这一点,但问题是,我如何将线条彼此分开?每个帖子的标题当然不包含任何实际的硬编码换行符,而是根据宽度限制自动换行,所以我不能只寻找换行符来拆分 innerHTML例如 DOM。

那么你会怎么做呢?

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

最佳答案

您可以尝试遍历所有字符,在每个循环中,将当前字符选择到一个范围对象中,从中您可以使用范围对象的 getBoundingClientRect() 方法获取 底部 字符矩形。这是我们检测每一行结束字符的方式。这是检测结束字符的标志:

  1. 如果我们使用正常换行,所有的行都应该在某个空格处换行。特殊之处在于,在这种情况下,结束空格字符将具有矩形(来自 getBoundingClientRect()),同时 topbottom0
  2. 如果我们像word-break:break-all那样使用换行符,结束字符可能是其他字符(不是空格字符)。在这种情况下,我们将检测结束字符之后的下一个字符,下一个字符的 bottom 与结束字符的 bottom 不同。

所以这确实相当复杂。事实上,一开始我以为我们只有一种情况(第二种情况),但如果我们忽略第一种情况,我们会得到意想不到的结果。所以首先我们需要检查第一种情况,然后是第二种情况。现在检测每一行的结束字符可以帮助我们将整个文本分成不同的行。然后我们可以将每一行包装在具有适当样式集的 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';
  }
}

Demo.

关于javascript - 更改多行文本中每一行的文本对齐方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23902385/

相关文章:

html - input 的边框比 div 的边框更细

javascript - 在 HTML 中加载通用页脚

java - 如何通过 Vaadin UI Framework 使用 Yandex map ?

javascript - CakePHP - 加载时javascript文件不更新

jquery - 使用 jquery animate 时 Div 不会占据全高

html - 可扩展的侧滚动问题

javascript - 来自 $.ajax 和 json 的数据对象是浅层的

javascript - 如何选择除一个div之外的整个html

html - CSS - 如何在 3 层中正确添加 3 个图像

CSS 选择类后的元素