gpt4 book ai didi

javascript - 在contenteditable div中粘贴原文中间的HTML单词后,如何防止插入符号跳到整个文本的末尾?

转载 作者:可可西里 更新时间:2023-11-01 13:30:52 26 4
gpt4 key购买 nike

总结/背景

我正在尝试制作一个内容可编辑的 div,当它被 HTML 单词粘贴时,我希望它可以转换为纯文本并且插入符号可以自动跳转到粘贴的 HTML 单词的末尾。

我的尝试

我已经尝试过,下面是我输入的代码。

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test</title>
</head>

<body>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
function stripHTML(input){
var output = '';
if(typeof(input) == "string"){
output = input.replace(/(<([^>]+)>)/ig, "");
}
return output;
}

$(function(){
$("#text").focus(function(event){
setItv = setInterval('clearHTML()', 1);
});
$("#text").blur(function(event){
clearInterval(setItv);
});
});

function clearHTML(){
var patt = /(<([^>]+)>)/ig;
var input = $("#text").html();

if(input.search(patt) >= 0){
var output = '';
if(typeof(input) == "string"){
output = stripHTML(input);
}
$("#text").html(output);
}
}
</script>

<div contenteditable="true" style="border: 1px #000 solid; width: 300px;
height: 100px;" id="text">Hello, world!</div>

</body>

</html>

问题

最大的问题是光标放置。将 HTML 粘贴到原始文本的中间(例如,粘贴在“Hello”和“world”之间)后,插入符号会跳到整个文本的末尾,而不是粘贴的 HTML 的末尾。通常,当我们在原文中间粘贴一段单词时,插入符号会跳到粘贴单词的末尾,而不是整个文本的末尾。但是在这种情况下我不知道为什么它会自动跳到整个文本的末尾。

次要问题是setInterval 函数。可能不会造成什么问题,但是脚本的编写方式非常不专业,可能会影响程序的运行效率。

问题

  1. contenteditable div中在原文中间粘贴HTML文字后,如何防止插入符号跳到整篇文章的末尾?
  2. 如何在不使用setInterval 函数 的情况下优化脚本?

最佳答案

作为起点,我建议进行以下改进:

  • 直接检查可编辑内容中是否存在元素,而不是在 innerHTML 属性上使用正则表达式。这将提高性能,因为 innerHTML 很慢。您可以使用标准 DOM 方法 getElementsByTagName() 来完成此操作。如果您更喜欢使用效率稍低的 jQuery,您可以使用 $("#text").find("*")。更简单和更快的方法是检查您的可编辑元素是否有一个子节点,它是一个文本节点。
  • 通过用包含元素的 textContent 属性的文本节点替换元素的内容来剥离 HTML。这比用正则表达式替换 HTML 标签更可靠。
  • 在剥离 HTML 标签之前将选择存储为字符偏移量,并在之后恢复它。我有 previously posted code on Stack Overflow to do this .
  • 在相关事件触发时执行 HTML 剥离(我建议使用 keypresskeyupinputpaste开胃菜)。我会保持 setInterval() 的间隔频率较低,以处理这些事件未涵盖的其他情况

以下代码段包含所有这些改进:

var saveSelection, restoreSelection;

if (window.getSelection && document.createRange) {
saveSelection = function(containerEl) {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(containerEl);
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;

return {
start: start,
end: start + range.toString().length
};
};

restoreSelection = function(containerEl, savedSel) {
var charIndex = 0, range = document.createRange();
range.setStart(containerEl, 0);
range.collapse(true);
var nodeStack = [containerEl], node, foundStart = false, stop = false;

while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
range.setEnd(node, savedSel.end - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}

var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
} else if (document.selection) {
saveSelection = function(containerEl) {
var selectedTextRange = document.selection.createRange();
var preSelectionTextRange = document.body.createTextRange();
preSelectionTextRange.moveToElementText(containerEl);
preSelectionTextRange.setEndPoint("EndToStart", selectedTextRange);
var start = preSelectionTextRange.text.length;

return {
start: start,
end: start + selectedTextRange.text.length
}
};

restoreSelection = function(containerEl, savedSel) {
var textRange = document.body.createTextRange();
textRange.moveToElementText(containerEl);
textRange.collapse(true);
textRange.moveEnd("character", savedSel.end);
textRange.moveStart("character", savedSel.start);
textRange.select();
};
}

$(function(){
var setInv;
var $text = $("#text");

$text.focus(function(event){
setItv = setInterval(clearHTML, 200);
});

$text.blur(function(event){
clearInterval(setItv);
});

$text.on("paste keypress keyup input", function() {
// Allow a short delay so that paste and keypress events have completed their default action bewfore stripping HTML
setTimeout(clearHTML, 1)
});
});

function clearHTML() {
var $el = $("#text");
var el = $el[0];
if (el.childNodes.length != 1 || el.firstChild.nodeType != 3 /* Text node*/) {
var savedSel = saveSelection(el);
$el.text( $el.text() );
restoreSelection(el, savedSel);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div contenteditable="true" style="border: 1px #000 solid; width: 300px;
height: 100px;" id="text">Hello, world!</div>

关于javascript - 在contenteditable div中粘贴原文中间的HTML单词后,如何防止插入符号跳到整个文本的末尾?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30284555/

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