javascript - 如何在 contenteditable 中将文本分成单独的页面(如 Google 文档)?

标签 javascript html pagination contenteditable text-editor

我一直致力于创建在浏览器中运行的专用文本编辑器。我有一个让我昏迷的问题。如何检测长文本并将其分成单独的页面,就像在 Google 文档中所做的那样? 我知道 google docs 不能通过 contenteditable 工作,但必须有一些解决方案......

Edit1:我们需要考虑几个场景:

  1. 我们通过 json 对象加载文档,然后呈现我们的页面。
  2. 我们正在键入文本并已到达页面末尾。
  3. 我们删除文本。
  4. 我们插入或删除一段文本。

Google docs pagination https://googleblog.blogspot.ru/2011/04/pagination-comes-to-google-docs.html

页面.html

<div class="box-base">
    <div id="page-1" class="page">
         <div id="editable-1" class="document" contenteditable="true"></div>
    </div>
    <div id="page-2" class="page">
         <div id="editable-2" class="document" contenteditable="true"></div>
    </div>
</div>

样式.css

.box-base {
    margin-left: 50px;
    flex: 1 0 430px;
    border-style: solid;
    display: -webkit-flex;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    height: 900px;
    overflow: auto;
}
.page {
    width: @page-width;
    height: @page-width * 1.414;
    /*overflow-y: auto;*/
    background: white;
    margin: 25px 0 25px 0;
}
.document {
  /*max-height: 1000px;*/
  overflow: hidden;
}

最佳答案

我认为您必须尝试在不同位置拆分文本并观察直到 scrollHeight 刚好小于或等于 clientHeight。像这样的东西:

var divs = document.querySelectorAll('div');
var div = divs[0]
// Get text from content of first div - this wouldn't be what real code used
var text = div.textContent;

// Guess the split point as a percentage of the hidden characters
var splitPoint = text.length * div.clientHeight / div.scrollHeight;

// Find first space after splitpoint
splitPoint = text.indexOf(' ', splitPoint);

// Used to make sure we don't get into an infinite loop. Not needed if this code is proven to work on all browsers.
var count = 0;

div.textContent = text.substr(0, splitPoint);

// Add words until we are bigger 
while ((div.clientHeight == div.scrollHeight) && (count++ < 1000)) {
  splitPoint = text.indexOf(' ', splitPoint + 1);
  div.textContent = text.substr(0,splitPoint);
}

// Subtract words until we are smaller 
while ((div.clientHeight < div.scrollHeight) && (count++ < 1000)) {
  splitPoint = text.lastIndexOf(' ', splitPoint - 1);
  div.textContent = text.substr(0, splitPoint);
}

divs[1].textContent = text.substr(splitPoint);

// Create new divs starting at splitpoint (left as an exercise)
div.box {
  width: 150px;
  height: 150px;
  border: 1px solid black;
}

div.moretext {
  background: #ccc;
}
<div class="box">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent viverra malesuada nibh, sed luctus eros egestas in. Donec imperdiet, purus a consequat ultricies, mauris magna laoreet neque, quis tincidunt risus augue in lorem. Donec mauris odio, vehicula eget sollicitudin sed, aliquet et metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec condimentum sed lacus at porttitor. Suspendisse tincidunt vehicula mauris, a ultricies mi fringilla et. Aliquam eget imperdiet magna. Quisque justo libero, commodo vitae dolor quis, volutpat consectetur tellus. Nullam consectetur commodo sem vel posuere. Praesent nec suscipit sem, quis porta diam. Duis gravida lectus fringilla, efficitur quam ut, luctus sem. Ut elit tortor, bibendum a molestie vel, tincidunt vitae lacus. In dapibus commodo mi, id blandit velit mollis placerat. Praesent quis posuere ligula. Praesent ac rhoncus est. In blandit non justo ut egestas. Praesent nec mi sagittis, eleifend nisl ac, egestas enim. Aliquam in tortor ac tellus rutrum feugiat. Etiam bibendum eget metus eget facilisis. Sed mollis eget tellus at viverra. Fusce at leo vel magna convallis dictum. Sed convallis ipsum non feugiat sagittis. Donec a lacus nisl. Donec elementum metus nec arcu interdum interdum. Praesent malesuada eu purus nec tempus. Aliquam in velit nulla. Ut vel turpis et sapien consectetur facilisis. Fusce a pulvinar lorem. Vestibulum vel neque vitae arcu placerat sodales quis ut risus. Cras aliquet, nibh quis sodales venenatis, felis est tempus enim, at condimentum felis nulla sollicitudin tortor. Morbi viverra dolor tempus, lacinia ante ac, dapibus diam. Suspendisse nec ligula viverra, pellentesque lacus nec, maximus turpis.</div>
<div class="moretext"></div>

关于javascript - 如何在 contenteditable 中将文本分成单独的页面(如 Google 文档)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39122713/

相关文章:

javascript - 在 react 中注册时向用户发送电子邮件

javascript - jQuery onChange() 不起作用……

宽度为 100% 的 CSS/div 太高了几个像素/为什么?

javascript - JQuery 在表格末尾追加数据

sql - 限制在 Android 中获取的记录(Sqlite 数据库)

javascript - 添加分页后 AngularJS 中的自定义过滤器

javascript - 使用 gtk3 在 Seed-3.2 javascript 中使用 cairo 进行绘图

javascript - 如何使用javascript来隐藏东西

html - 无法创建具有固定位置的 iframe

javascript - 可重用的 React 分页组件