当内容超过 x 高度时,如何将节点从 contentEditable div 动态移动到另一个?

How to move nodes from a contentEditable div to another dynamically when its content exceed a x height?

我正在尝试制作一个简单的 wyswyg 原型,它使用 contentEditable div 模拟 A4 页面的概念。 所以我当前的代码是这样的:

HTML:

<div id="editor">
            <div contenteditable="true" class="page" id="page-1">
                <b>hello</b>
            </div>
        </div>

CSS:

#editor{
                background-color: gray;
                border: 1px black;
                padding: 1em 2em;
            }
            .page{
                background-color: white;
                border: solid black;
                padding: 1em 2em; 
                width:595px;
                height:841px;
                word-wrap: break-word;
                overflow-wrap: break-word;
                white-space: normal;
            }

JS:

//force br
document.execCommand("DefaultParagraphSeparator", false, "br");
const a4 = {
    height: 841,
    width: 595
};
document.getElementById('editor').addEventListener('input', function(e) {
    let getChildrenHeight = function(element) {
        total = 0;
        if (element.childNodes) {
            for (let child of element.childNodes) {
                switch (child.nodeType) {
                    case Node.ELEMENT_NODE:
                        total += child.offsetHeight;
                        break;
                    case Node.TEXT_NODE:
                        let range = document.createRange();
                        range.selectNodeContents(child);
                        rect = range.getBoundingClientRect();
                        total += (rect.bottom - rect.top);
                        break;
                }
            }
        }
        return total;
    };
    let pages = document.getElementsByClassName('page');
    for (let i in pages) {
        let page = pages[i];
        //remove empty page    
        if (page.offsetHeight == 0 && i > 1) {
            page.remove();
        }
        let childrenHeight = getChildrenHeight(page);
        while (childrenHeight > a4.height) {
            //recursively try to fit elements on max size 
            //removing/pushing excedents elements to the next div (aka page)
            let excedents = [];
            let children = page.childNodes;
            let children_length = children.length - 1;
            let backup = children[children_length].cloneNode(true);
            children[children_length].remove();
            if (pages.item(i + 1) === null) {
                var newPage = page.cloneNode(true);
                newPage.innerHTML = '';
                newPage.appendChild(backup);
                page.parentNode.appendChild(newPage);
            } else {
                page.item(i + 1).insertBefore(backup, page.item(i + 1).childNodes[0]);
            }
            //console.log(children[i].innerHTML);
        }
    }
});

不幸的是,结果并不如我所料。 当超过一页的高度时,第一页的所有内容都会被删除,不像我想的那样:

  1. 超出部分移至下一页。
  2. 并且当页面缺少子项时,将被删除。

类似于非常非常原始的 Microsoft Word 多页编辑器。

怎么做? 提前致谢 塞尔索

您的代码是一个良好的开端,但还有一些问题需要解决:

  • 您正在尝试使用 for..in 循环遍历 HTMLCollection,这将访问集合中的 lengthitemnamedItem(只需尝试 for(let i in document.getElementsByClassName('page')) console.log(i); 在控制台中)
  • 您正尝试在 offsetHeight 为 0 时删除空白页,请尝试 childrenHeight

  • 你可以用 if 语句交换 while 循环

  • 您还必须检查当前页面上是否有足够的空间,以便从下一页拉回行
  • 此外,您必须手动处理分页符上的光标位置

我做了一个 codepen 来演示我建议的更改。它远非完美,但可以处理页面删除和多余删除。