9

我有一个用于打印的 2 列布局。h2-5 在列内,h1s 跨越两列。我正在使用Paged.js进行分页。

这两个页面显示了可接受的布局:

在此处输入图像描述

但是,如果出现标题位于列底部的情况,我希望将标题强制到下一列的顶部。

在此处输入图像描述

如果一篇新文章从页面底部的 40% 开始,我也希望它也被强制到下一页。

在此处输入图像描述

对于 h2 及以下,我在标题上方注入一个 div,如果标题位于其列的底部,我将其膨胀以推入下一列。

在此处输入图像描述

这似乎对 h2-5 有效,因为它们位于由浏览器管理的流程中。但前提是它们在左栏中;如果它们是正确的,它们就会被从页面上撞出。例如:

在此处输入图像描述

将 H1 从页面上撞出会导致问题,垫片膨胀,但会将标题推入不可见的区域,或者其他一些奇怪的情况。

在此处输入图像描述 在此处输入图像描述

第一个图像显示了第二个图像中出现的标题,从页面中删除。

以下(略微简化的)标记是生成第 11 页的内容(右,第二张图片)

<div class="the-articles">
  <article class="architectural-review.com paper-story noted">
    <p>
      No question, Rem is a genius. Nonetheless, his wake is toxic: stained by
      Randian egos (both triumphal and crushed), the intense interpersonal
      competition, and the exploitation of intellectual and manual labour. How
      does it all end, you wonder. In some ways, Tomas Koolhaas’s documentary
      was a preemptive eulogy. Death is present in every shot, tugging at the
      great man’s sleeve. The film is also suffused by an intense melancholy. It
      is the peculiar sadness of endings: when a family line is extinguished,
      when change erases beauty and meaning, when an entire world order
      disintegrates.
    </p>
    <p>
      Starchitects are still with us, even though their era is over. Koolhaas
      himself called time on it in the mid-2000s. It is no contradiction to
      honour them, while admitting that we must give ourselves permission to
      abandon the figure of the heroic architect, and along with it the Western
      blueprint for greatness that Koolhaas has so relentlessly and obsessively
      perfected.
    </p>
    <div class="tail-meta">
      From:
      <span class="url"
        >https://www.architectural‑review.com/essays/reputations/rem‑koolhaas‑1944/10037224.article</span
      >
    </div>
    <!-- SHIM IS HERE -->
    <div class="shim-between-articles" style="height: 181.944px;"></div>
  </article>
  <article id="2415273718" class="newyorker.com paper-story noted">
    <h1 class="article-title" id="h2415273718">
      Love Is Not a Permanent State of Enthusiasm: An Interview with Esther
      Perel
    </h1>
  </article>
</div>

我在里面做 shim-inflation afterPageLayout,它调用这个函数:

function identifyTooCloseToBottomHeading(
  theHeading,
  pageCutoffPercentage,
  page,
  pageFragment
) {
  try {
    if (theHeading !== null && theHeading !== undefined) {
      const pageBox = page.element.getBoundingClientRect();
      const headingBox = theHeading.getBoundingClientRect();
      const pdelta = pageBox.bottom - headingBox.bottom;
      const botPC = pdelta / pageBox.height; //Gives a % up the page. I.e. 100% is the top
      const cutPC = pageCutoffPercentage[theHeading.tagName.toLowerCase()];
      const oneRem = parseFloat(
        getComputedStyle(document.documentElement).fontSize
      );
      if (botPC < cutPC) {
        console.log("at risk", theHeading);
        if (theHeading.previousElementSibling) {
          AdjustShimSize(oneRem);
        } else {
          const thisArticle = theHeading.parentElement;
          const prevArticle = thisArticle.previousElementSibling;
          const shim = prevArticle.querySelector(".shim-between-articles");
          const topMetaBox = thisArticle
            .querySelector(".top-meta")
            .getBoundingClientRect();
          shim.style.height = `${
            theHeading.getBoundingClientRect().height + topMetaBox.height
          }px`;
        }
      }
    }
  } catch (e) {
    console.log(e, theHeading);
  }

  function AdjustShimSize(oneRem) {
    const shim = theHeading.previousElementSibling;
    // calculate the height that it needs to be
    try {
      const shimBox = shim.getBoundingClientRect();
      const container = shim.closest(".the-articles");
      const containerBox = container.getBoundingClientRect();
      // logShimDetails(theHeading, container, shimBox, nextElBox, containerBox, oneRem);
      shim.style.height = `${containerBox.bottom - shimBox.bottom - oneRem}px`;
      console.log("shimmed", theHeading);
    } catch {
      console.log("trouble with", theHeading);
    }
  }
}

这似乎应该工作,但它不是很优雅。我怀疑我可以用breaktoken? 有没有正确的方法来做到这一点?


对于 H1,我还尝试在上面的文章中添加一个类,具体取决于将标题撞到下一页需要多少行。即一系列css规则:

.n-line-fat-bottom-20 {
  margin-bottom: calc(var(--wp-line-height) * 20) !important;
}
.n-line-fat-bottom-22 {
  margin-bottom: calc(var(--wp-line-height) * 24) !important;
}

然后在 Paged.js 生命周期的同一点应用该类。它有同样无益的结果。


如果我提前知道哪些标题需要打破,我可以给他们一个break-before: column;break-before: page;规则,但内容是不提前知道的。事后添加这些规则似乎不适用于 paged.js 的生命周期。我怀疑这一个生命周期问题,因为如果我在正确的点/正确的处理程序处执行此操作,将内容从页面上推出应该会导致下一页的重排。

4

1 回答 1

1

嗨,为了解决这个问题,我添加了一个新组件并为其提供了必要的高度以在新页面/列中发送内容这是我的用例的原始实现:

  const attribute = node?.getAttribute('data-pdf-break-past');
  const pageHeight = 967;
  let maxHeightValueBeforeBreak = pageHeight;
  if (attribute) {
    maxHeightValueBeforeBreak = (pageHeight * +attribute) / 100;
  }
  const distanceToTop = node.getBoundingClientRect()?.top + window.scrollY;

  const contentHeightInPage = distanceToTop % pageHeight;
  const marginToSet = pageHeight - contentHeightInPage;
  if (
    (attribute && contentHeightInPage > maxHeightValueBeforeBreak) ||
    node.className.includes('pdf-break-before')
  ) {
    const newNode = document.createElement('div');
    newNode.style.height = `${marginToSet}px`;

    node.parentNode?.insertBefore(newNode, node);
  }
  

在 Paged.js 解析了内容之后,我使用了 Dom 操作。

请注意,不使用边距或填充,因为可能会导致库出现问题(发生分页时的奇怪行为)。

于 2021-11-17T11:42:12.843 回答