文本在DIV内部分页与图像

时间:2013-12-19 20:15:39

标签: javascript html text pagination

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

它的效果非常好 enter image description here

这里是我使用过的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 });
}

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

enter image description here

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

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

4 个答案:

答案 0 :(得分:1)

除了需要计算更多变量的事实外,不仅仅是单词width&amp;高度,还有新行,边距填充以及每个浏览器如何输出所有内容。

然后通过添加图像(如果图像作为最大宽度或高度更高或更大几乎不可能),如果它更小,它还具有边距/填充。并且它可以从一行结束开始,所以再次分解所有内容。基本上只在第一页上你可以简单地通过计算它的宽度+边距和高度+边距/线高来添加图像。但这需要很多数学才能得到想要的结果。

说我前段时间试过写一个类似的脚本但是停止了导致很多问题和不同的浏览器结果。

现在阅读你的问题,我遇到了一些我以前读过的东西:

-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/

添加小于最大高度的图像&amp;第一页的宽度不会弄乱一切。

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

答案 1 :(得分:0)

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

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

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

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

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

答案 2 :(得分:0)

使用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/

答案 3 :(得分:0)

我实际上是基于@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)