确定要放入div的文本量以最大化最后一行的宽度

时间:2014-01-31 10:33:30

标签: javascript jquery html css algorithm

我制作了自己的csscolumn(css3)polyfill脚本,将文本分成两列以便于阅读。它不是一个带参数的动态脚本,而是根据我现在正在处理的网站量身定制的。

除了第一列中最后一行文本的一个问题外,它工作正常。在某些情况下,在剩余文本进入第二列之前,只有一个单词显示在column1的最后一行,其中句子继续。换句话说:在column1和column2之间的句子中有太多的空格。例如:

Column 1. Lorem ipsum dolor sit amet,   sentence continued after break in first column.
consectetur adipisicing elit, sed do    etc etc etc etc etc etc etc etc etc etc etc
sentence                                 etc etc etc etc etc etc etc.

我认为这需要使用每列的heightwidthline-height来完成(两者都有相同的宽度,49%)。

到目前为止我的逻辑是:

  • 在字符串中找到中间索引位置
  • 搜索文本将被拆分的下一个空格
  • 然后将文本分割为大约在中间的空白

我没有运气使用现有的polyfill来解决这个问题。然后我使用Columnizer我遇到了一个错误,当我的字符数低于450时,第一列留空。所以我在我的隔间里尖叫着“F @ **它!!我们会现场直播! ”。 对于简单的文章文本,我不希望ul li出现任何可怕的语义。

但如果有更好的脚本可以解决这个问题,那么我就可以作为答案了。

我的简化代码:

$('.article-body').each(function (index) {
if ($(this).text().length > 300) {

  var text = $(this).text();
  var length = $(this).text().length;

  var col1 = null;
  var col2 = null;

  if (text[Math.floor(length/2)+14].trim() === '') {
    col1 = text.slice(0, Math.floor(length/2)+14).trim();
    col2 = text.slice((Math.floor(length/2))+15, length).trim();
  }
  else {
    loop1:
    for (var i = Math.floor(length/2)+14; i <= length; i++) {
      if (text[i].trim() === '') {

        col1 = text.slice(0, i).trim();
        col2 = text.slice(i+1, length).trim();

        $(this).empty();
        $(this).append("<div class='first-column'>"+col1+"</div>"); // Column 1
        $(this).append("<div class='second-column'>"+col2+"</div>"); // Column 2

        break loop1;
      }
    }
  }
}

2 个答案:

答案 0 :(得分:1)

将文章拆分为文字。然后创建两个列div并将文章文本添加到第一个度量高度。然后清空第一个div并逐渐用文字填充它,直到div的高度大约是具有全部内容的列div的高度的一半。将所有单词放在第一个div中的当前单词,其余单词放在第二个div中。

这似乎运作良好,因为浏览器正在进行破解。它仅适用于不可调整的列。我认为它足够快,我已经在一个页面上用各种文章div测试了它。检查自动换行时,你可以从中间开始。 (我意识到Mabedan的答案使用了类似的方法,但它似乎没有考虑到单词,只考虑字符。)

以下是代码:

$().ready(function() {
  $('.article-body').each(function(index) {

    // get text as words
    var text = $(this).text();
    var words = text.split(" ");

    // prepare columns
    var col1 = $('<div class="first-column">');
    var col2 = $('<div class="second-column">');

    $(this).empty();
    $(this).append(col1);
    $(this).append(col2);

    // calculate div metrics
    $(col2).text(text);
    var height = $(col2).height();
    var middle = Math.ceil(0.5 * height);

    // fill col1 with words until it overflows
    var start = Math.floor(0.3 * words.length);
    var line = words.slice(0, start).join(' ');

    for (var i = start; i < words.length; i++) {
      var w = words[i];

      if (line) line += " ";
      line += w;

      $(col1).text(line);
      if ($(col1).height() > middle) {
          $(col1).text(words.slice(0, i).join(' '));
          $(col2).text(words.slice(i).join(' '));
          return;
      }
    }

    // not enough text: just fill col1
    $(col1).text(words.join(' '));
    $(col2).text('');

  });
});

答案 1 :(得分:0)

我想出了类似的东西,这太可怕了。但可能会给你一些进一步调查的想法。

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript" src='http://code.jquery.com/jquery-1.10.2.min.js'></script>
    <script type="text/javascript">
    document.setText = function () {
        var text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
            divs = $("div"),
            position  = Math.round(text.length / 2),
            divToEnlarge,
            initialFirstDivHeight,
            initialSecondDivHeight,
            incrementFactor;

        function setText() {
            divs.eq(0).text(text.slice(0, position));
            divs.eq(1).text(text.slice(position));
        }
        setText();
        initialFirstDivHeight = divs.eq(0).height();
        initialSecondDivHeight = divs.eq(1).height();

        divToEnlarge = initialFirstDivHeight > initialSecondDivHeight ? 1 : 0;
            incrementFactor = divToEnlarge === 0 ? +1 : -1;
        for (;;) {
            position += incrementFactor;
            setText();
            if (divs.eq(divToEnlarge).height() > initialFirstDivHeight) {
                position -= incrementFactor;
                setText();
                return;
            }
        }
    }
    </script>
    <style type="text/css">
    div {
        display: inline-block;
        width: 50%;
    }
    button {
        display: block;
    }
    body {
        margin: 0;
    }
    </style>
</head>
<body>
<button onclick="document.setText()"></button>
<div></div><div></div>
</body>
</html>