- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试制作一个内容可编辑的 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 函数。可能不会造成什么问题,但是脚本的编写方式非常不专业,可能会影响程序的运行效率。
最佳答案
作为起点,我建议进行以下改进:
innerHTML
属性上使用正则表达式。这将提高性能,因为 innerHTML
很慢。您可以使用标准 DOM 方法 getElementsByTagName()
来完成此操作。如果您更喜欢使用效率稍低的 jQuery,您可以使用 $("#text").find("*")
。更简单和更快的方法是检查您的可编辑元素是否有一个子节点,它是一个文本节点。textContent
属性的文本节点替换元素的内容来剥离 HTML。这比用正则表达式替换 HTML 标签更可靠。keypress
、keyup
、input
和 paste
开胃菜)。我会保持 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/
如果我有一个使用 strpos() 导出的字符串位置,我将如何跳到该位置?我正在使用一个需要从该位置或下一行开始处开始的函数。 我该怎么做?速度是一个因素。 最佳答案 您可以使用 跳到字符串中的任何字
我构建了一个表单,用数组中的数据填充字段。 我有 2 个按钮,一个将使用 Ajax“发布”- 提交,另一个我试图跳到数组中的下一个对象 - 跳过。 我不知道如何让跳过按钮起作用。我有 found允许您
我实现了一个具有开始和结束状态的 CSS3 动画。一旦达到结束状态,动画就会停止并且不再重复。我需要做的是有一个绕过整个动画但显示最终状态的“跳到结束”链接。是否可以通过 CSS3 执行此操作。 这是
我有一个应用程序,我试图从 jQuery .animate 切换到 CSS3 转换,以响应滑动手势和按钮按下来左右移动卡片列表。 除了一件事,它现在运行良好。我希望该应用程序每次滑动一次移动一页卡片,
我下载了 Matchit 插件并将其用于我的 HTML 文件。一切都按预期工作,直到我在我的列表中使用它。 reddit vim w3schools 如果光标在第一个 o
我下载了 Matchit 插件并将其用于我的 HTML 文件。一切都按预期工作,直到我在我的列表中使用它。 reddit vim w3schools 如果光标在第一个 o
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
在我的 Scala 代码中的 for 循环中,如果特定条件为真,我想跳到循环的开头并且不执行以下语句。在 Java 中,我可以使用“继续”来执行此操作。但是“继续”在 Scala 中似乎不起作用。那么
我犯了一个错误,将 Visual Studio 项目从 2008 年升级到 2010 年,但没有先检查我以前的更改。因此,我有一个巨大的系统生成文件(10k+ 行),每 4 行更改一次。 我通常很擅长
#include #include int main() { char nameuser[12]; int userChoice; printf("Name(Max. 12 Chara
我正在使用 Firebase 存储上传文件。 https://firebase.google.com/docs/storage/web/upload-files#monitor_upload_prog
我有一个带有 TransitionListener 的 MotionLayout,我的 MotionScene 的进度似乎从 0 到 1:
大家好,我对 qprogressbar 有疑问。我怎样才能使它光滑?我希望它从 0 到 100% 顺利进行。我将它与 reply 变量一起使用,该变量从 php 脚本读取数据并返回给我数据。我需要等待
我有一个非常非常奇怪的问题,我无法弄清楚。所以你可以看看,这是我的代码; point * findLongPaths(point * points, double threshold_distance
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在播放一个电视节目,该节目已使用 AVQueuePlayer 在我的项目中分成不同的章节。我还想提供在 AVQueuePlayer 已经播放时跳到上一章/下一章或即时选择不同章节的可能性。 AVQ
我想在我的环境中设置这样的东西。 [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKe
这个问题已经有答案了: Identity increment is jumping in SQL Server database (6 个回答) 已关闭 8 年前。 我遇到了一个奇怪的情况,其中 SQ
当我进入循环时,我的“计数器”从 1 跳到 4。有任何想法吗?代码和输出如下: static bool harvestLog() { ifstream myFile("LOGS/ex0
我正在尝试解决所有关于 codility 的类(class),但我未能解决以下问题:Ladder by codility 我在整个互联网上进行了搜索,但没有找到令我满意的答案,因为没有人回答为什么最大
我是一名优秀的程序员,十分优秀!