简体   繁体   English

带图像的DIV中的文本分页

[英]Text pagination inside a DIV with image

I want to paginate a text in some div so it will fit the allowed area 我想在某个div中对文本进行分页,使其适合允许的区域
Logic is pretty simple: 逻辑很简单:
1. split text into words 1.把文字分成单词
2. add word by word into and calculate element height 2.逐字添加并计算元素高度
3. if we exceed the height - create next page 3.如果我们超过高度-创建下一页

It works quite good 效果很好
在此处输入图片说明

here is JS function i've used: 这是我使用过的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 });
}

But when i add an image it break everything. 但是,当我添加图像时,它会破坏一切。 In this case text overflows 'green' area. 在这种情况下,文本溢出“绿色”区域。

在此处输入图片说明

Working fiddle: http://jsfiddle.net/74W4N/7/ 工作提琴: http : //jsfiddle.net/74W​​4N/7/

Is there a better way to paginate the text and calculate element height? 是否有更好的方式对文本进行分页并计算元素高度?

Except the fact that there are many more variables to calculate,not just only the word width & height, but also new lines,margins paddings and how each browser outputs everything. 除了要计算的变量更多以外,不仅包括单词的宽度和高度,还包括新行,边距填充以及每个浏览器如何输出所有内容。

Then by adding an image (almost impossible if the image is higher or larger as the max width or height) if it's smaller it also has margins/paddings. 然后添加图像(如果图像更大或更大,则最大宽度或高度几乎不可能),如果图像较小,则还具有边距/填充。 and it could start at the end of a line and so break up everything again.basically only on the first page you could add an image simply by calculating it's width+margin and height+margin/lineheight. 它可以从一行的末尾开始,因此可以再次拆分所有内容。基本上仅在第一页上,您可以通过计算图像的width + margin和height + margin / lineheight来添加图像。 but that needs alot math to get the wanted result. 但这需要大量的数学运算才能得到想要的结果。

Said that i tried some time ago to write a similar script but stopped cause of to many problems and different browser results. 说我前段时间尝试编写类似的脚本,但停止了导致许多问题和不同浏览器结果的原因。

Now reading your question i came across something that i read some time ago: 现在阅读您的问题时,我遇到了一段时间前读到的内容:

-webkit-column-count 

so i made a different approach of your function that leaves out all this calculations. 因此,我对您的函数采用了另一种方法,而忽略了所有这些计算。

don't judge the code as i wrote it just now.(i tested on chrome, other browsers need different prefixes.) 不要像我刚才编写的那样判断代码。(我在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 

here is an Example 这是一个例子

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

adding an image smaller than the max height & width in the first page would not mess up everything. 在首页添加小于最大高度和宽度的图像不会使所有内容混乱。

and it looks like it's supported by all modern browsers now.(with the correct prefixes) 并且看起来现在所有现代浏览器都支持它(带有正确的前缀)。

In my experience, trying to calculate and reposition text in HTML is almost an exercise in futility. 以我的经验,尝试计算和重新定位HTML中的文本几乎是徒劳的。 There are too many variations among browsers, operating systems, and font issues. 浏览器,操作系统和字体问题之间存在太多差异。

My suggestion would be to take advantage of the overflow CSS property. 我的建议是利用CSS overflow属性。 This, combined with using em sizing for heights, should allow you to define a div block that only shows a defined number of lines (regardless of the size and type of the font). 此,结合使用em上浆高度,应允许你定义一个div块,仅示出了一个定义的行数(无论该字体的大小和类型)。 Combine this with a bit of javascript to scroll the containing div element, and you have pagination. 结合一些JavaScript来滚动包含的div元素,就可以进行分页了。

I've hacked together a quick proof of concept in JSFiddle, which you can see here: http://jsfiddle.net/8CMzY/1/ 我在JSFiddle中汇集了一个快速的概念证明,您可以在这里查看: http : //jsfiddle.net/8CMzY/1/

It's missing a previous button and a way of showing the number of pages, but these should be very simple additions. 它缺少上一个按钮和一种显示页数的方法,但是这些应该是非常简单的补充。

EDIT: I originally linked to the wrong version for the JSFiddle concept 编辑:我最初链接到JSFiddle概念的错误版本

Solved by using jQuery.clone() method and performing all calculations on hidden copy of original HTML element 通过使用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();
}

live demo: http://jsfiddle.net/74W4N/19/ 现场演示: http : //jsfiddle.net/74W​​4N/19/

I actually came to an easier solution based on what @cocco has done, which also works in IE9. 实际上,我基于@cocco所做的事情找到了一个更简单的解决方案,该解决方案也可以在IE9中使用。 For me it was important to keep the backward compatibility and the animation and so on was irrelevant so I stripped them down. 对我来说,保持向后兼容性和动画等无关紧要,因此我将它们剥离了很重要。 You can see it here: http://jsfiddle.net/HNF3d/63/ 您可以在这里看到它: http : //jsfiddle.net/HNF3d/63/

heart of it is the fact that I dont limit height and present horizontal pagination as vertical. 它的核心是我不限制高度,而将水平分页显示为垂直。

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM