下面的小提琴允许将文本粘贴到a中并生成相同的段落,动态地
由相同数量的字符组成.
发生的问题是; 来自先前动态生成的段落的文本在每个标记内溢出,并且不会正确地继续到下一个动态段落.因此,用户是否可以按Enter键并将该内容向下移动到下一个现有段落中,同时仍然动态且自动地保留现有格式?
如果可以提供一个新的小提琴,我将非常感激,因为我还是新编码.再一次,小提琴可以在这里找到.
更新:是否可以生成段落,用户可以按Enter键,如果可能,将其内容无缝地移动到下面的段落中?并且当按下退格按钮时应用同样的内容,以使内容向上移动到上一段?出现的问题是,当按下回车时,文本似乎由于css中的溢出属性而隐藏文本.
$(function() {
$("#Go").on('click', function() {
var theText = $('textarea').val();
var numberOfCharacters = 300;
while (theText.length) {
while (theText.length > numberOfCharacters &&
theText.charAt(numberOfCharacters) !== ' ') {
numberOfCharacters++;
}
$("#text_land").append("
<\/br>" + theText.substring(
0, numberOfCharacters) +
"<\/p>
<\/br>");
theText = theText.substring(numberOfCharacters);
numberOfCharacters = 300;
$('p').attr('contenteditable', 'true');
$("p").addClass("text");
}
})
})
$('select').on('change', function() {
var targets = $('#text_land p'),
property = this.dataset.property;
targets.css(property, this.value);
}).prop('selectedIndex', 0);
(end);
@media print {
p {
page-break-inside: avoid;
}
}
p {
position: relative;
}
@media print {
.no-print,.no-print * {
display: none !important;
}
}
p {
border-style: solid;
color: #000;
display: block;
text-align: justify;
border-width: 5px;
font-size: 19px;
overflow: hidden;
height: 300px;
width: 460px;
word-wrap: break-word;
}
Paste text in the field below to divide text into
paragraphs.
Divided Text Will Appear Below:
用户可以按Enter键并将该内容向下移动到下一个现有段落中,同时仍然动态地自动保留现有格式
如果我理解正确,你想要的是,一旦文本被分成段落,然后用户将一些文本添加到其中一个并按下Enter,那么剩下的文本应该流入下一段分配溢出文本,就像完成一样早.
类似地,当用户BackSpace在段落的开头按下时,文本再次返回到前一段中,溢出的文本与先前所做的一样分配到其他段落中.
作为一种算法,你需要的是这样的:
将初始文本划分为相等的块,并分配到p
根据需要动态创建s的段落中.
听取keyup
有关这些p
元素的事件
按键是Enter,
3.1从Enter按下的位置提取剩余文本
3.2从下面所有段落中提取文本,前面加上上面提取的溢出文本
3.3删除下一个所有段落并分发组合文本,就像我们在步骤1中所做的那样
按键是BackSpace,
4.1检查它是否在段落的开头,如果有前一段
4.2提取段落的文本并附加下一段所有段落的文本
4.3删除包括当前段落在内的所有段落,并将提取的文本附加到前一段.
4.4像在步骤1中一样分发组合文本
使用这种粗略的算法,您可以开始编码,看起来像这样:
注1:这是所有JavaScript,没有jQuery.
注2:这过于简化,您需要进一步优化和计算所有边缘情况.
缓存必需元素并绑定事件处理程序:
var btn = document.getElementById('go'), textarea = document.getElementById('textarea1'), content = document.getElementById('content'); btn.addEventListener('click', initialDistribute); content.addEventListener('keyup', handleKey);
textarea
如果有的话,从删除现有段落中分发初始文本:
function initialDistribute() { var text = textarea.value; while (content.hasChildNodes()) { content.removeChild(content.lastChild); } rearrange(text); }
通过动态创建所需数量的段落来重新排列/分发文本的逻辑:
function rearrange(text) { var chunks = text.match(/.{1,100}/g) || []; chunks.forEach(function(str, idx) { para = document.createElement('P'); para.setAttribute('contenteditable', true); para.textContent = str; content.appendChild(para); }); }
注3:本例中我使用了100个字符来分割文本.此外,这不会处理空格,并将分隔两者之间的单词.您需要在代码中执行此操作.(#见下面的编辑)
陷阱Enter(键码13)和BackSpace(键码8)键的事件处理程序.另外,看看元素是否是一个p
元素:
function handleKey(e) { var para = e.target, position, key, fragment, overflow, remainingText; key = e.which || e.keyCode || 0; if (para.tagName != 'P') { return; } if (key != 13 && key != 8) { return; } ...
获取光标位置以确定是否BackSpace在段落的开头按下了:
position = window.getSelection().getRangeAt(0).startOffset;
如果Enter被按下,提取当前段落的最后一个孩子后的文本(CONTENTEDITABLE会产生div
时Enter按下),删除节点,在前面加上它来在此之后的所有段落的剩余的文本,并删除其余的段落.
if (key == 13) { fragment = para.lastChild; overflow = fragment.textContent; fragment.parentNode.removeChild(fragment); remainingText = overflow + removeSiblings(para, false); rearrange(remainingText); }
如果BackSpace按下,检查是否有前一段并且光标位于开头.如果是,则在删除所有后续段落(包括当前段落)时提取剩余文本:
if (key == 8 && para.previousElementSibling && position == 0) { fragment = para.previousElementSibling; remainingText = removeSiblings(fragment, true); rearrange(remainingText); }
逻辑从后续段落中提取文本并删除它们:
function removeSiblings(elem, includeCurrent) { var text = '', next; if (includeCurrent && !elem.previousElementSibling) { parent = elem.parentNode; text = parent.textContent; while (parent.hasChildNodes()) { parent.removeChild(parent.lastChild); } } else { elem = includeCurrent ? elem.previousElementSibling : elem; while (next = elem.nextSibling) { text += next.textContent; elem.parentNode.removeChild(next); } } return text; }
把它们放在一起,这是一个工作片段:
片段:
var btn = document.getElementById('go'),
textarea = document.getElementById('textarea1'),
content = document.getElementById('content'),
chunkSize = 100;
btn.addEventListener('click', initialDistribute);
content.addEventListener('keyup', handleKey);
function initialDistribute() {
var text = textarea.value;
while (content.hasChildNodes()) {
content.removeChild(content.lastChild);
}
rearrange(text);
}
function rearrange(text) {
var chunks = splitText(text, false);
chunks.forEach(function(str, idx) {
para = document.createElement('P');
para.setAttribute('contenteditable', true);
para.textContent = str;
content.appendChild(para);
});
}
function handleKey(e) {
var para = e.target, position,
key, fragment, overflow, remainingText;
key = e.which || e.keyCode || 0;
if (para.tagName != 'P') { return; }
if (key != 13 && key != 8) { return; }
position = window.getSelection().getRangeAt(0).startOffset;
if (key == 13) {
fragment = para.lastChild;
overflow = fragment.textContent;
fragment.parentNode.removeChild(fragment);
remainingText = overflow + removeSiblings(para, false);
rearrange(remainingText);
}
if (key == 8 && para.previousElementSibling && position == 0) {
fragment = para.previousElementSibling;
remainingText = removeSiblings(fragment, true);
rearrange(remainingText);
}
}
function removeSiblings(elem, includeCurrent) {
var text = '', next;
if (includeCurrent && !elem.previousElementSibling) {
parent = elem.parentNode;
text = parent.textContent;
while (parent.hasChildNodes()) {
parent.removeChild(parent.lastChild);
}
} else {
elem = includeCurrent ? elem.previousElementSibling : elem;
while (next = elem.nextSibling) {
text += next.textContent;
elem.parentNode.removeChild(next);
}
}
return text;
}
function splitText(text, useRegex) {
var chunks = [], i, textSize, boundary = 0;
if (useRegex) {
var regex = new RegExp('.{1,' + chunkSize + '}\\b', 'g');
chunks = text.match(regex) || [];
} else {
for (i = 0, textSize = text.length; i < textSize; i = boundary) {
boundary = i + chunkSize;
if (boundary <= textSize && text.charAt(boundary) == ' ') {
chunks.push(text.substring(i, boundary));
} else {
while (boundary <= textSize && text.charAt(boundary) != ' ') { boundary++; }
chunks.push(text.substring(i, boundary));
}
}
}
return chunks;
}
* { box-sizing: border-box; padding: 0; margin: 0; }
body { font-family: monospace; font-size: 1em; }
h3 { margin: 1.2em 0; }
div { margin: 1.2em; }
textarea { width: 100%; }
button { padding: 0.5em; }
p { padding: 1.2em 0.5em; margin: 1.4em 0; border: 1px dashed #aaa; }
Paste text in the field below to divide text into
paragraphs..
Divided Text Will Appear Below: