如何判断HTML元素是否已从页面底部消失?

时间:2022-09-04 21:10:48

I have a system that takes dynamic data, puts it in HTML for layout and then converts that to PDF. However the problem I am having is that if an element becomes too big for the remaining page space or pushes something else off the bottom how can I detect this and move the element myself to the right position on the next page? (Currently it gets in the way of the footer elements.)

我有一个系统,它采用动态数据,将其放在HTML中进行布局,然后将其转换为PDF。但是我遇到的问题是,如果一个元素对于剩余的页面空间变得太大或者从底部推出其他东西,我怎么能检测到这个并将元素自己移动到下一页的正确位置? (目前它阻碍了页脚元素。)

Any ideas?

8 个解决方案

#1


Have you considered just writing two views for the data instead?

您是否考虑过为数据写两个视图?

This will allow you to address and of PDF issues on the PDF version and address any html issues on the HTML version.

这将允许您解决PDF版本的PDF问题,并解决HTML版本上的任何HTML问题。

Edit: Since HTML itself has no real concept of "page size", beyond it's own viewport (through javascript), this will be tough.

编辑:由于HTML本身没有“页面大小”的真实概念,超出它自己的视口(通过javascript),这将是艰难的。

You can find out the calculated height of a given DOM element using javascript:

您可以使用javascript找出给定DOM元素的计算高度:

document.getelementById("anElement").clientheight

Then if you know the number of pixels in a given page, you can add line breaks as needed to push it down if it will be too big.

然后,如果您知道给定页面中的像素数,则可以根据需要添加换行符,如果它太大则将其向下推。

#2


You'll have to track the specific heights of all items, even dynamic, on a page and determine when you need to insert a page break.

您必须在页面上跟踪所有项目的特定高度,甚至是动态,并确定何时需要插入分页符。

#3


From your question, I assume you use static positioning (position: absolute) for all content elements?

根据您的问题,我假设您对所有内容元素使用静态定位(位置:绝对)?

If your content interrupts footer elements in HTML, then its quite possible that you can fix this by letting the HTML render the footer under all content, as normally done in HTML.

如果你的内容中断了HTML中的页脚元素,那么很可能你可以通过让HTML在所有内容下呈现页脚来解决这个问题,就像在HTML中一样。

Still, it would be very helpful if you can describe how you convert the HTML to PDF.

如果您能描述如何将HTML转换为PDF,那将非常有用。

#4


Guss: I/we are using the winover libraries (wnvhtmlconvert.dll) for the conversion. The positions aren't absolute (with the exceptions of the header and footers) because they need to shuffle down if the elements above them expand. It all needs to be dynamic because the contents of the elements will vary with user input. Each element may need to be split or move depending on how much free space there is on the "page".

Guss:我/我们正在使用winover库(wnvhtmlconvert.dll)进行转换。这些位置不是绝对的(除了页眉和页脚),因为如果它们上面的元素扩展,它们需要随机播放。这一切都需要是动态的,因为元素的内容会随用户输入而变化。根据“页面”上有多少可用空间,可能需要拆分或移动每个元素。

zack: I'm creating the HTML in order to convert it to PDF its just used for template layout. The HTML will never be seen.

zack:我正在创建HTML,以便将其转换为PDF,仅用于模板布局。 HTML永远不会被看到。

#5


I'd take off the absolute positioning on your footer, and just let it flow after the content.

我会取消你的页脚上的绝对定位,然后让它在内容之后流动。

If you render it as one big page, then PDF can break the page where it needs to.

如果将其渲染为一个大页面,那么PDF可以打破它所需的页面。

#6


I'm going to assume you have control over the generated html and can make some changes there. You will need to empirically determine the exact height and width of the pdf. You will also need to determine the maximum number of pdf pages an html page will fill.

我将假设您可以控制生成的html并可以在那里进行一些更改。您需要凭经验确定pdf的确切高度和宽度。您还需要确定html页面将填充的最大pdf页数。

The basic plan is to put the html content in its own containing div and repeat that div for however many pages you might possibly fill. Each div will then be styled and sized to fit on one page, with the overflow being hidden (we can think of each div as a "window"). The repeat divs will have their content shifted so that a different part of the content is in the window. In the following example, I'm going to assume a pdf page dimensions of 500px by 500px (I know this is unrealistic), that the maximum number of pages content will take up is 3, and that your html is being rendered by the pdf converter in a standards-compliant fashion.

基本计划是将html内容放在其自己的包含div中,并为可能填充的页面重复该div。然后将每个div设置样式并调整大小以适合一页,溢出被隐藏(我们可以将每个div视为“窗口”)。重复div将使其内容移位,以便内容的不同部分在窗口中。在下面的例子中,我将假设pdf页面尺寸为500px×500px(我知道这是不现实的),内容的最大页面数将占用3,并且您的html由pdf呈现转换器符合标准。

<!DOCTYPE html>
<html>
<head>
  <title>PDF Pagination Example</title>
  <style>
    .header {background:blue; height:25px}
    .footer {background:green; height:25px}
    .window {height:500px; width:500px}
    #window1, #window2, #window3 {height:450px; overflow:hidden}
    #spacer2 {height:0; margin-top:-450px}
    #spacer3 {height:0; margin-top:-900px}
    li {font-size:30px; padding:10px}
  </style>
</head>
<body>

<div class='window'>
<div class='header'>A header</div>
  <div id='window1'>
    <ol>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
    </ol>
  </div>
<div class='footer'>A footer</div>
</div>

<div class='window'>
<div class='header'>A header</div>
  <div id='window2'>
  <div id='spacer2'></div>
    <ol>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
    </ol>
  </div>
<div class='footer'>A footer</div>
</div>

<div class='window'>
<div class='header'>A header</div>
  <div id='window3'>
  <div id='spacer3'></div>
    <ol>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
    </ol>
</div>
<div class='footer'>A footer</div>
</div>

</body>
</html>

At a font size of 30px, the content splits between two pages. If you increase the font size to 50px, the content will spread to fill all three.

字体大小为30px时,内容在两页之间分割。如果将字体大小增加到50px,内容将扩散以填充所有三个。

The last piece of the puzzle is a bit of javascript. You will need to write a snippet that calculates the height of the content and adds padding to the bottom of each window so you don't get cutoff like in the example. The javascript should also set windows with no content in them to display:none. I'm not sure if this is even the css you are looking for, so I won't work out the javascript, but I am also certain that if you need help with that you can find it here on SO :).

拼图的最后一部分是一些javascript。您需要编写一个计算内容高度的片段,并在每个窗口的底部添加填充,这样就不会像示例中那样获得截断。 javascript还应该设置没有内容的窗口来显示:none。我不确定这是否是你正在寻找的css,所以我不会解决javascript,但我也确定如果你需要帮助,你可以在SO :)找到它。

#7


maybe helpfull to consider some of the CSS print attributes, but without further info its hard to tell

也许有助于考虑一些CSS打印属性,但没有进一步的信息很难说

http://www.w3schools.com/Css/css_ref_print.asp

#8


I found that by using the WebBrowser control and checking the OffsetRectangle.Bottom property of the element in question I could tell if it was lower than the top of the footer then I could tell if the element had overflowed and by how much.

我发现通过使用WebBrowser控件并检查相关元素的OffsetRectangle.Bottom属性,我可以判断它是否低于页脚顶部,然后我可以判断元素是否溢出以及多少。

Thanks for your help anyway guys and gals.

无论如何,谢谢你的帮助男人和女孩。

#1


Have you considered just writing two views for the data instead?

您是否考虑过为数据写两个视图?

This will allow you to address and of PDF issues on the PDF version and address any html issues on the HTML version.

这将允许您解决PDF版本的PDF问题,并解决HTML版本上的任何HTML问题。

Edit: Since HTML itself has no real concept of "page size", beyond it's own viewport (through javascript), this will be tough.

编辑:由于HTML本身没有“页面大小”的真实概念,超出它自己的视口(通过javascript),这将是艰难的。

You can find out the calculated height of a given DOM element using javascript:

您可以使用javascript找出给定DOM元素的计算高度:

document.getelementById("anElement").clientheight

Then if you know the number of pixels in a given page, you can add line breaks as needed to push it down if it will be too big.

然后,如果您知道给定页面中的像素数,则可以根据需要添加换行符,如果它太大则将其向下推。

#2


You'll have to track the specific heights of all items, even dynamic, on a page and determine when you need to insert a page break.

您必须在页面上跟踪所有项目的特定高度,甚至是动态,并确定何时需要插入分页符。

#3


From your question, I assume you use static positioning (position: absolute) for all content elements?

根据您的问题,我假设您对所有内容元素使用静态定位(位置:绝对)?

If your content interrupts footer elements in HTML, then its quite possible that you can fix this by letting the HTML render the footer under all content, as normally done in HTML.

如果你的内容中断了HTML中的页脚元素,那么很可能你可以通过让HTML在所有内容下呈现页脚来解决这个问题,就像在HTML中一样。

Still, it would be very helpful if you can describe how you convert the HTML to PDF.

如果您能描述如何将HTML转换为PDF,那将非常有用。

#4


Guss: I/we are using the winover libraries (wnvhtmlconvert.dll) for the conversion. The positions aren't absolute (with the exceptions of the header and footers) because they need to shuffle down if the elements above them expand. It all needs to be dynamic because the contents of the elements will vary with user input. Each element may need to be split or move depending on how much free space there is on the "page".

Guss:我/我们正在使用winover库(wnvhtmlconvert.dll)进行转换。这些位置不是绝对的(除了页眉和页脚),因为如果它们上面的元素扩展,它们需要随机播放。这一切都需要是动态的,因为元素的内容会随用户输入而变化。根据“页面”上有多少可用空间,可能需要拆分或移动每个元素。

zack: I'm creating the HTML in order to convert it to PDF its just used for template layout. The HTML will never be seen.

zack:我正在创建HTML,以便将其转换为PDF,仅用于模板布局。 HTML永远不会被看到。

#5


I'd take off the absolute positioning on your footer, and just let it flow after the content.

我会取消你的页脚上的绝对定位,然后让它在内容之后流动。

If you render it as one big page, then PDF can break the page where it needs to.

如果将其渲染为一个大页面,那么PDF可以打破它所需的页面。

#6


I'm going to assume you have control over the generated html and can make some changes there. You will need to empirically determine the exact height and width of the pdf. You will also need to determine the maximum number of pdf pages an html page will fill.

我将假设您可以控制生成的html并可以在那里进行一些更改。您需要凭经验确定pdf的确切高度和宽度。您还需要确定html页面将填充的最大pdf页数。

The basic plan is to put the html content in its own containing div and repeat that div for however many pages you might possibly fill. Each div will then be styled and sized to fit on one page, with the overflow being hidden (we can think of each div as a "window"). The repeat divs will have their content shifted so that a different part of the content is in the window. In the following example, I'm going to assume a pdf page dimensions of 500px by 500px (I know this is unrealistic), that the maximum number of pages content will take up is 3, and that your html is being rendered by the pdf converter in a standards-compliant fashion.

基本计划是将html内容放在其自己的包含div中,并为可能填充的页面重复该div。然后将每个div设置样式并调整大小以适合一页,溢出被隐藏(我们可以将每个div视为“窗口”)。重复div将使其内容移位,以便内容的不同部分在窗口中。在下面的例子中,我将假设pdf页面尺寸为500px×500px(我知道这是不现实的),内容的最大页面数将占用3,并且您的html由pdf呈现转换器符合标准。

<!DOCTYPE html>
<html>
<head>
  <title>PDF Pagination Example</title>
  <style>
    .header {background:blue; height:25px}
    .footer {background:green; height:25px}
    .window {height:500px; width:500px}
    #window1, #window2, #window3 {height:450px; overflow:hidden}
    #spacer2 {height:0; margin-top:-450px}
    #spacer3 {height:0; margin-top:-900px}
    li {font-size:30px; padding:10px}
  </style>
</head>
<body>

<div class='window'>
<div class='header'>A header</div>
  <div id='window1'>
    <ol>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
    </ol>
  </div>
<div class='footer'>A footer</div>
</div>

<div class='window'>
<div class='header'>A header</div>
  <div id='window2'>
  <div id='spacer2'></div>
    <ol>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
    </ol>
  </div>
<div class='footer'>A footer</div>
</div>

<div class='window'>
<div class='header'>A header</div>
  <div id='window3'>
  <div id='spacer3'></div>
    <ol>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
      <li>Content of variable height that may or may not overflow.</li>
    </ol>
</div>
<div class='footer'>A footer</div>
</div>

</body>
</html>

At a font size of 30px, the content splits between two pages. If you increase the font size to 50px, the content will spread to fill all three.

字体大小为30px时,内容在两页之间分割。如果将字体大小增加到50px,内容将扩散以填充所有三个。

The last piece of the puzzle is a bit of javascript. You will need to write a snippet that calculates the height of the content and adds padding to the bottom of each window so you don't get cutoff like in the example. The javascript should also set windows with no content in them to display:none. I'm not sure if this is even the css you are looking for, so I won't work out the javascript, but I am also certain that if you need help with that you can find it here on SO :).

拼图的最后一部分是一些javascript。您需要编写一个计算内容高度的片段,并在每个窗口的底部添加填充,这样就不会像示例中那样获得截断。 javascript还应该设置没有内容的窗口来显示:none。我不确定这是否是你正在寻找的css,所以我不会解决javascript,但我也确定如果你需要帮助,你可以在SO :)找到它。

#7


maybe helpfull to consider some of the CSS print attributes, but without further info its hard to tell

也许有助于考虑一些CSS打印属性,但没有进一步的信息很难说

http://www.w3schools.com/Css/css_ref_print.asp

#8


I found that by using the WebBrowser control and checking the OffsetRectangle.Bottom property of the element in question I could tell if it was lower than the top of the footer then I could tell if the element had overflowed and by how much.

我发现通过使用WebBrowser控件并检查相关元素的OffsetRectangle.Bottom属性,我可以判断它是否低于页脚顶部,然后我可以判断元素是否溢出以及多少。

Thanks for your help anyway guys and gals.

无论如何,谢谢你的帮助男人和女孩。