gpt4 book ai didi

javascript - 如何在生成的 contentEditable div 的顶部和底部附加固定的不可编辑内容?

转载 作者:行者123 更新时间:2023-11-28 08:49:31 25 4
gpt4 key购买 nike

我正在尝试在内容可编辑 = true 的动态生成的 div 上“模拟”固定和不可编辑的页眉页脚

首先,我尝试使用此 css 放置页眉和页脚:

.header{
/*margin:-100px 0px;*/
margin-left: -2cm;
background-color: red;
vertical-align:middle;
text-align:center;
}
.footer{
background-color: darkgray;
margin-top: 735px;
height: 100px;
margin-left: -2cm;
}

并尝试在第一页启用页眉,效果很好:

<div id="editor">
<div contenteditable="true" class="page" id="page-1">
<div class="header" contenteditable="false">
<img class="brasao" alt="brasao-rj*" src="https://i.imgur.com/ktmBQCS.png" />
<span>Procuradoria Geral do Estado do Rio de Janeiro</span>
</div>
<b>hello</b>
<div class="footer" contenteditable="false">
Rua Carmo do Cajuru 128
</div>
</div>
</div>

但是页脚没有按预期工作,因为用户可以向下推页脚,将更多内容放在 div 上。

在我目前的方法中,我尝试在调用 newPage.focus() 之前附加“header”div。但不幸的是,行为并不像预期的那样,允许用户同时按下页眉和页脚。

const getHeader = () => {
let header = document.createElement('div');
header.setAttribute('contenteditable', false);
header.setAttribute('class', 'header');
let imgBrasao = document.createElement('img');
imgBrasao.class = 'brasao';
imgBrasao.setAttribute('class', 'brasao');
imgBrasao.src = 'https://i.imgur.com/ktmBQCS.png';
let spanPGE = document.createElement('span');
spanPGE.textContent = 'Procuradoria Geral do Estado do Rio de Janeiro';
header.appendChild(imgBrasao);
header.appendChild(spanPGE);
return header;
};
const getFooter = () => {
let footer = document.createElement('div');
footer.setAttribute('contenteditable', false);
footer.setAttribute('class', 'footer');
let spanPGE = document.createElement('span');
spanPGE.textContent = 'Rua Carmo do Cajuru 128 - Centro RJ';
footer.appendChild(spanPGE);
return footer;
};

完整代码在这里:

https://jsitor.com/ETmvUUXaS

(无页眉页脚版本:https://jsitor.com/9J30B6YfG)

那么,我怎样才能在那些内容可编辑的 div 上模拟页眉和页脚呢?

提前致谢!

最佳答案

我设法在没有 jQuery 的情况下做到了。这个概念是在您的内容周围添加一个包装器,并将事件添加到该包装器而不是页面。此外,我创建了一个模板 HTML 页面,这样代码就可以在不执行清理的情况下进行克隆。

为了将页脚放在底部,我将页面显示更改为 flex 并将 flex-direction 更改为 column。然后为页脚设置 margin-top: auto

代码如下:

function redator(divId) {
const root = document.getElementById(divId)
const a4 = {
height: 830,
width: 595,
lineHeight: 30
};
const template = document.querySelector('#template');
const headerHeight = root.querySelector('#page-1 .header').offsetHeight;
const footerHeight = root.querySelector('#page-1 .footer').offsetHeight;

const getChildrenHeight = (element) => {

total = parseFloat(getComputedStyle(element).paddingBottom);

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;
};

const getPageHeight = (content) => {
const children = getChildrenHeight(content);
return children + headerHeight + footerHeight;

};

const setSelection = (node, offset) => {
let range = document.createRange();
let sel = window.getSelection();
range.setStart(node, offset);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
};

const addPage = () => {

const newPage = template.cloneNode(true);
const pages = root.getElementsByClassName('page');

newPage.id = 'page-' + (pages.length + 1);
newPage.className = 'page';
root.appendChild(newPage);
newPage.querySelector(".content").focus();
newPage.querySelector(".content").addEventListener('input', onInput);

newPage._emptyPage = true;
return newPage.querySelector(".content");
};

function onInput(e) {
const content = this;
const page = this.closest(".page")
const previousPage = page.previousElementSibling;
const nextPage = page.nextElementSibling;

const pageHeight = getPageHeight(content);
const lastChild = content.lastChild;
const cloneChild = lastChild.cloneNode(true);
const textContent = content.innerText;
if ((pageHeight === 0 || textContent.length <= 1) && !!previousPage && !page._emptyPage) {
page.remove();
previousPage.querySelector(".content").focus();
const lastChild = previousPage.querySelector(".content").lastChild;
setSelection(lastChild, lastChild.childNodes.length);
} else if (pageHeight > a4.height && !nextPage) {
lastChild.remove();
addPage().appendChild(cloneChild);
} else if (pageHeight > a4.height && nextPage) {

lastChild.remove();
nextPage.querySelector(".content").insertBefore(cloneChild, nextPage.querySelector(".content").firstChild);
let selection = getSelection().getRangeAt(0).startContainer.parentElement.closest('div');
if (selection === page.lastChild) {
setSelection(cloneChild, 0);
}
} else if (pageHeight < a4.height - a4.lineHeight && !!nextPage) {
let firstChildOfNextPage = nextPage.firstChild;
let clone = firstChildOfNextPage.cloneNode(true);
firstChildOfNextPage.remove();
page.appendChild(clone);
}
page._emptyPage = false;
}

document.execCommand("DefaultParagraphSeparator", false, "div");
root.querySelector('#page-1 .content').addEventListener('input', onInput);
}

document.addEventListener('DOMContentLoaded', function() {
redator('editor');
}, false);
redator('editor');
#editor {
background-color: gray;
border: 1px black;
padding: 1em 2em;
}

.page {
background-color: white;
border: solid black;
/*padding: 10em 2em;*/
width: 595px;
height: 841px;
display: flex;
flex-direction: column;
}

.content {
word-wrap: break-word;
overflow-wrap: break-word;
white-space: normal;
padding-left: 2cm;
padding-bottom: 2cm;
}

.header {
background-color: red;
text-align: center;
}

.footer {
background-color: darkgray;
margin-top: auto;
height: 100px;
}

.brasao {
height: 60px;
width: 60px;
}

#template {
display: none;
}
<h3>My Editor</h3>
<div id="editor">
<div class="page" id="page-1">
<div class="header">
<img class="brasao" alt="brasao-rj*" src="https://i.imgur.com/ktmBQCS.png" />
<span>Procuradoria Geral do Estado do Rio de Janeiro</span>
</div>
<div class='content' contenteditable="true">
<b>hello</b>
</div>

<div class="footer">
Rua Carmo do Cajuru 128
</div>
</div>
</div>


<div id="template">
<div class="header">
<img class="brasao" alt="brasao-rj*" src="https://i.imgur.com/ktmBQCS.png" />
<span>Procuradoria Geral do Estado do Rio de Janeiro</span>
</div>
<div class='content' contenteditable="true">

</div>

<div class="footer">
Rua Carmo do Cajuru 128
</div>
</div>

关于javascript - 如何在生成的 contentEditable div 的顶部和底部附加固定的不可编辑内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58961491/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com