- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在内容可编辑 = 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/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/
我关注了 tutorial on creating a popup for an add-on在 Firefox 中,效果很好。 我现在遇到的问题是它创建的弹出窗口不会更改大小以适应我添加到其中的内容
我有一些视频,我需要连接一个标题并添加一些覆盖,问题是我需要先做覆盖,否则时间不正确,然后才将标题连接到视频的开头 ffmpeg -i talk.mp4 -i start_pancarte.png
我正在尝试附加一个 CSV 文件。这是我正在使用的线路。不幸的是,我找不到 export-csv 的附加选项。任何想法都有助于使其发挥作用。 Get-ADGroupMember "Domain Adm
我正在努力理解 Attach API (com.sun.tools.attach.*) 的用途。它的典型用途是什么?它是为了“模拟”JVM,以便您可以在不部署/启动代码的情况下测试您的代码吗?它是一个
我不明白为什么这不起作用。 soup_main = BeautifulSoup('FooBar') soup_append = BeautifulSoup('Meh') soup_main.body.
我有以下代码来返回我想要的字符串 $sql = " SELECT `description` FROM `auctions` WHERE `description` REGEX
我正在尝试从数组中附加具有多个值的元素,但我做错了。这是我的代码: for(var i=0; i ` + pricesArray[i].start_date ` ` + pricesArray[i
我正在尝试将图像链接添加到此 javascript 附加表中。使图像位于按钮上方 这是代码 $("#1").append(""+section+""+no+""+price+""+button+""
我有一个问题,我已经解决了,但它太烦人了。 我有一个 js 代码,当使用“追加”按下按钮时,它会放下一些 html 代码,并且通过该代码,我为 x 按钮提供了一个 id,并为容器元素提供了一个 id。
我想逐行读取文件,并且每一行可能都有很多字符。 这个版本的readline效果很好 func readLine(r *bufio.Reader) ([]byte, error) { var (
我有一个网站,每次用户登录或注销时,我都会将其保存到文本文件中。 如果不存在,我的代码在附加数据或创建文本文件时不起作用。这是示例代码 $myfile = fopen("logs.txt", "wr"
我正在尝试使用 typescript 和 Formik 创建一个自定义输入字段。我可以就完成以下代码的最佳方式获得一些帮助吗?我需要添加额外的 Prop 标签和名称......我已经坚持了一段时间,希
我有一个字符串 big_html,我想将它添加到某个 div 中。我观察到以下方面的性能差异: $('#some-div').append( big_html ); // takes about 10
如何使用 FormData 创建以下结果 ------WebKitFormBoundaryOmz20xyMCkE27rN7 Content-Disposition: form-data; name="
有没有办法附加 jQuery 事件处理程序,以便在任何先前附加的事件处理程序之前触发该处理程序?我遇到了this article ,但代码不起作用,因为事件处理程序不再存储在数组中,而这正是他的代码所
我正在开发一个需要网络登录的 iPhone 应用程序。像往常一样我打电话 [[UIApplication sharedApplication] openURL:loginURL]; 这将关闭应用程序并
我想开发一个仅针对特定域激活的扩展。 我不希望它在不浏览此特定域时出现在浏览器菜单中。 有可能这样做吗? 最佳答案 可能:对于菜单,您可以添加一个弹出窗口侦听器,用于检查当前加载的URL(docs f
这段 JavaScript 代码 function writeCookie(CookieName, CookieValue, CookieDuration) { var expiration
我正在使用 Handlebars 来渲染使用ajax从本地服务器获得的信息。我的 HTML 看起来像: {{#each Tabs}}
我尝试了以下代码,但当输入框中没有数据时它不会通知。当我直接添加此内容(不附加)时,它会起作用。我在这里做错了什么 var output = "\n"+ "\n"+
我是一名优秀的程序员,十分优秀!