【问题标题】:Text pagination inside a DIV with image带有图像的DIV内的文本分页
【发布时间】:2014-01-08 13:27:41
【问题描述】:

我想在某个 div 中对文本进行分页,以便它适合允许的区域
逻辑很简单:
1. 将文本拆分为单词
2.逐字添加并计算元素高度
3.如果我们超过高度 - 创建下一页

效果很好

这是我用过的 JS 函数:

function paginate() {
    var newPage = $('<pre class="text-page" />');
    contentBox.empty().append(newPage);
    var betterPageText='';
    var pageNum = 0;
    var isNewPage = false;

    var lineHeight = parseInt(contentBox.css('line-height'), 10);

    var wantedHeight = contentBox.height() - lineHeight;

    for (var i = 0; i < words.length; i++) {        
        if (isNewPage) {
            isNewPage = false;
        } else {            
            betterPageText = betterPageText + ' ' + words[i];
        }
        newPage.text(betterPageText + ' ...');
        if (newPage.height() >= wantedHeight) {
            pageNum++;
            if (pageNum > 0) {
                betterPageText = betterPageText + ' ...';
            }

            newPage.text(betterPageText);
            newPage.clone().insertBefore(newPage)            

            betterPageText = '...';
            isNewPage = true;
        } else {            
            newPage.text(betterPageText);
        }        
    }

    contentBox.craftyslide({ height: wantedHeight });
}

但是当我添加图像时,它会破坏一切。在这种情况下,文本会溢出“绿色”区域。

工作小提琴:http://jsfiddle.net/74W4N/7/

有没有更好的方法对文本进行分页和计算元素高度?

【问题讨论】:

    标签: javascript html text pagination


    【解决方案1】:

    除了有更多变量需要计算之外,不仅仅是单词的宽度和高度,还有换行符、边距以及每个浏览器如何输出所有内容。

    然后通过添加图像(如果图像比最大宽度或高度更高或更大,几乎不可能),如果它更小它也有边距/填充。它可以从一行的末尾开始,因此再次分解所有内容。基本上只有在第一页上,您可以简单地通过计算它的宽度+边距和高度+边距/线高来添加图像。但这需要大量的数学运算才能得到想要的结果。

    说我前段时间尝试编写一个类似的脚本,但停止了导致许多问题和不同浏览器结果的原因。

    现在阅读您的问题,我发现了一些我前段时间读过的东西:

    -webkit-column-count 
    

    所以我对你的函数做了一种不同的方法,省略了所有这些计算。

    不要像我刚才写的那样判断代码。(我在chrome上测试过,其他浏览器需要不同的前缀。)

    var div=document.getElementsByTagName('div')[0].firstChild,
    maxWidth=300,
    maxHeigth=200,
    div.style.width=maxWidth+'px';
    currentHeight=div.offsetHeight;
    columns=Math.ceil(currentHeight/maxHeigth);
    div.style['-webkit-column-count']=columns;
    div.style.width=(maxWidth*columns)+'px';
    div.style['-webkit-transition']='all 700ms ease';
    div.style['-webkit-column-gap']='0px';
    //if you change the column-gap you need to
    //add padding before calculating the normal div.
    //also the line height should be an integer that
    // is divisible of the max height 
    

    这是一个示例

    http://jsfiddle.net/HNF3d/10/

    在第一页中添加小于最大高度和宽度的图像不会搞砸一切。

    现在所有现代浏览器似乎都支持它。(带有正确的前缀)

    【讨论】:

      【解决方案2】:

      根据我的经验,尝试在 HTML 中计算和重新定位文本几乎是徒劳的。浏览器、操作系统和字体问题之间存在太多差异。

      我的建议是利用 overflow CSS 属性。这与使用em 调整高度相结合,应该允许您定义一个仅显示已定义行数的div 块(无论字体的大小和类型如何)。将它与一些 javascript 结合起来滚动包含的 div 元素,你就有了分页。

      我在 JSFiddle 中编写了一个快速的概念证明,您可以在此处查看:http://jsfiddle.net/8CMzY/1/

      它缺少上一个按钮和显示页数的方式,但这些应该是非常简单的添加。

      编辑:我最初链接到 JSFiddle 概念的错误版本

      【讨论】:

        【解决方案3】:

        通过使用 jQuery.clone() 方法并在原始 HTML 元素的隐藏副本上执行所有计算来解决

        function paginate() {
        
             var section = $('.section');
        
             var cloneSection = section.clone().insertAfter(section).css({ position: 'absolute', left: -9999, width: section.width(), zIndex: -999 });
        
             cloneSection.css({ width: section.width() });
        
             var descBox = cloneSection.find('.holder-description').css({ height: 'auto' });
        
             var newPage = $('<pre class="text-page" />');
             contentBox.empty();
             descBox.empty();
             var betterPageText = '';
             var pageNum = 0;
             var isNewPage = false;
        
             var lineHeight = parseInt(contentBox.css('line-height'), 10);
        
             var wantedHeight = contentBox.height() - lineHeight;
             var oldText = '';
        
             for (var i = 0; i < words.length; i++) {
                if (isNewPage) {
                   isNewPage = false;
                   descBox.empty();
                }
                betterPageText = betterPageText + ' ' + words[i];
        
                oldText = betterPageText;
        
                descBox.text(betterPageText + ' ...');
                if (descBox.height() >= wantedHeight) {
        
                   if (i != words.length - 1) {
                      pageNum++;
        
                      if (pageNum > 0) {
                         betterPageText = betterPageText + ' ...';
                      }
        
                      oldText += ' ... ';
                   }
        
                   newPage.text(oldText);
                   newPage.clone().appendTo(contentBox);
        
                   betterPageText = '... ';
                   isNewPage = true;
                } else {
                   descBox.text(betterPageText);
                   if (i == words.length - 1) {
                      newPage.text(betterPageText).appendTo(contentBox);
                   }
                }
             }
        
             if (pageNum > 0) {
                contentBox.craftyslide({ height: wantedHeight });
             }
        
             cloneSection.remove();
        }
        

        现场演示:http://jsfiddle.net/74W4N/19/

        【讨论】:

          【解决方案4】:

          实际上,基于@cocco 所做的,我找到了一个更简单的解决方案,它也适用于IE9。 对我来说,保持向后兼容性和动画等无关紧要是很重要的,所以我把它们去掉了。你可以在这里看到它:http://jsfiddle.net/HNF3d/63/

          它的核心是我不限制高度并将水平分页呈现为垂直的事实。

          var parentDiv = div = document.getElementsByTagName('div')[0];
          var div = parentDiv.firstChild,
              maxWidth = 300,
              maxHeigth = 200,
          
              t = function (e) {
                  div.style.webkitTransform = 'translate(0,-' + ((e.target.textContent * 1 - 1) * maxHeigth) + 'px)';
                  div.style["-ms-transform"] = 'translate(0,-' + ((e.target.textContent * 1 - 1) * maxHeigth) + 'px)';
              };
          
          div.style.width = maxWidth + 'px';
          currentHeight = div.offsetHeight;
          columns = Math.ceil(currentHeight / maxHeigth);
          
          links = [];
          while (columns--) {
              links[columns] = '<span>' + (columns + 1) + '</span>';
          }
          var l = document.createElement('div');
          l.innerHTML = links.join('');
          l.onclick = t;
          document.body.appendChild(l)
          

          【讨论】:

            猜你喜欢
            • 2023-03-26
            • 2015-04-30
            • 1970-01-01
            • 2022-08-18
            • 1970-01-01
            • 1970-01-01
            • 2011-02-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多