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

时间:2014-05-28 03:33:15

标签: javascript html css dom text-align

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

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

即。第一行的对齐方式是左,第二个中心,第三个右边。同样,对于延伸超过两行的标题,第一行将左对齐,第二行右对齐。对于单行,标题将居中。

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

那么你会怎么做呢?

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

3 个答案:

答案 0 :(得分:1)

如果没有JavaScript,则无法

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

如果没有JavaScript,您无法预测段落是否跨越多行以及多少行,仅仅因为用户:

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

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

你可以改为:

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

  2. 禁止换行符(white-space: nowrap;)和:

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

  4. 使用JavaScript ,您可以确定将换行符放在counting the actual number of lines的哪个位置,然后逐个字符缩小文字,直到得到两行,然后一行,找到这种方式您可以插入换行符的确切位置。

    我认为它足够黑,但是,嗯,这只是我的意见。另一方面,您可能会关注一旦加载页面后对用户配置的更改(例如像旧浏览器中使用的文本一样的缩放)可能会破坏布局。

答案 1 :(得分:1)

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

你可以通过在爆炸之前在字符串上使用pr-made“自动换行”功能来简化操作,这样标题将根据你的最大宽度规范自动预先插入\n个字符。

然后在爆炸后你只需要在div中将它们包装在\n断点处的数组中,然后根据需要使用css类对它们进行排列。

然后将implode数组放回字符串中......

答案 2 :(得分:1)

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

  1. 如果我们使用普通包装,则所有行都应该在某个空格字符处中断。特别的是,在这种情况下,结束空格字符将具有rect(来自getBoundingClientRect()),topbottom都是0
  2. 如果我们使用像word-break:break-all这样的包装,则结束字符可能是其他字符(不是空格字符)。在这种情况下,我们将检测结束字符后面的下一个字符,下一个字符的bottom与结束字符的bottom不同。
  3. 所以它确实相当复杂。事实上,起初我认为我们只有1个案例(第二个案例),但如果我们忽略第一个案例,我们会有意想不到的结果。首先,我们需要检查第一个案例,然后是第二个案例。现在检测每行中的结束字符有助于我们将整个文本分成单独的行。然后我们可以用div元素包装每一行,并设置appropritate样式(以对齐每行中的文本)。

    以下是演示代码:

    <强> 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.

相关问题