gpt4 book ai didi

javascript - 如何避免从 jQuery 中的 contenteditable

中删除键入的文本

转载 作者:行者123 更新时间:2023-12-01 00:17:26 26 4
gpt4 key购买 nike

我正在使用 jQuery UI 可拖动组件来添加 <span>内容可编辑<p> .

预期输出为段落 <p>应该是可编辑的,并且可拖动组件应该能够拖放到段落以及 <p> 的内容应该可以编辑。我的代码有问题。当我在 <p> 中输入内容时然后单击外部 <p> 。从段落中删除的键入单词。

我的代码如下:

$(function() {
function textWrapper(str, sp, btn) {
if (sp == undefined) {
sp = [0, 0];
}
var txt = "";
if (btn) {
txt = "<span class='w b'>" + str + "</span>";
} else {
txt = "<span class='w'>" + str + "</span>";
}

if (sp[0]) {
txt = "&nbsp;" + txt;
}

if (sp[1]) {
txt = txt + "&nbsp;";
}

return txt;
}

function chunkWords(p) {
var words = p.split(" ");
words[0] = textWrapper(words[0], [0, 1]);
var i;
for (i = 1; i < words.length; i++) {
var re = /\[.+\]/;
if (re.test(words[i])) {
var b = makeTextBox(words[i].slice(1, -1));
words[i] = "&nbsp;" + b.prop("outerHTML") + "&nbsp;";
} else {
if (words[0].indexOf(".")) {
words[i] = textWrapper(words[i], [1, 0]);
} else {
words[i] = textWrapper(words[i], [1, 1]);
}
}
}
return words.join("");
}

function unChunkWords(tObj) {
var words = [];
$(".w", tObj).each(function(i, el) {
console.log($(el).text(), $(el).attr("class"));
if ($(el).hasClass("b")) {
words.push("[" + $(el).text().trim() + "]");
} else {
words.push($(el).text().trim());
}
});
return words.join(" ");
}

function makeBtn(tObj) {
var btn = $("<span>", {
class: "ui-icon ui-icon-close"
}).appendTo(tObj);
}

function makeTextBox(txt) {
var sp = $("<span>", {
class: "w b"
}).html(txt);
makeBtn(sp);
return sp;
}

function makeDropText(obj) {
return obj.droppable({
drop: function(e, ui) {
var txt = ui.draggable.text();
var newSpan = textWrapper(txt, [1, 0], 1);
$(this).after(newSpan);
makeBtn($(this).next("span.w"));
makeDropText($(this).next("span.w"));
$("span.w.ui-state-highlight").removeClass("ui-state-highlight");
},
over: function(e, ui) {
$(this).add($(this).next("span.w")).addClass("ui-state-highlight");
},
out: function() {
$(this).add($(this).next("span.w")).removeClass("ui-state-highlight");
}
});
}

$("p.given").html(chunkWords($("p.given").text()));

$("p.given").on("click", ".b > .ui-icon", function() {
$(this).parent().remove();
});

$("p.given").blur(function() {
var w = unChunkWords($(this));
console.log(w);
$(this).html(chunkWords(w));
makeDropText($("p.given span.w"));
});

$("span.given").draggable({
helper: "clone",
revert: "invalid"
});

makeDropText($("p.given span.w"));
});
p.given {
display: flex;
flex-wrap: wrap;
}

p.given span.w span.ui-icon {
cursor: pointer;
}

div.blanks {
display: inline-block;
min-width: 50px;
border-bottom: 2px solid #000000;
color: #000000;
}

div.blanks.ui-droppable-active {
min-height: 20px;
}

span.answers>b {
border-bottom: 2px solid #000000;
}

span.given {
margin: 5px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="row">
<p class="given" contenteditable="true">Lorem Ipsum is simply dummy text of the printing and typesetting industry. [Lorem] Ipsum has been the industry's standard dummy text ever since the 1500s, Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
</div>

<div class="divider"></div>
<div class="section">
<section>
<div class="card blue-grey ">
<div class="card-content white-text">
<div class="row">
<div class="col s12">
<span class="given btn-flat white-text red lighten-1" rel="1">the Santee, thDakota</span>
<span class="given btn-flat white-text red lighten-1" rel="2">America</span>
<span class="given btn-flat white-text red lighten-1" rel="3">Qatar</span>
<span class="given btn-flat white-text red lighten-1" rel="4">Philippines</span>
</div>
</div>
</div>
</div>
</section>
</div>

该问题间歇性发生。

最佳答案

有时用户输入的文本会再次被删除,原因在函数unChunkWords中:

此函数仅迭代元素(具有类“w”),但它不会迭代这些元素之间可能出现的纯文本节点。在内容可编辑元素中,用户确实可以在元素之间的区域中键入文本。因此,unChunkWords 中的循环永远不会访问此类文本,并在返回的数组中忽略它。

您可以通过将光标放在单词末尾的空格之前,然后按向右箭头键来强制执行此操作。这要么将光标移动到下一个单词的开头,要么它不明显移动(它只是移出了它所在的span)。无论哪种方式,您的光标现在都位于分隔两个单词的文本节点中。输入一些内容并单击其他地方。 ...异常发生了。

有很多方法可以规避这个问题。其中之一是使用 jQuery contents() 方法,该方法也收集文本节点。更改以下代码:

$(".w", tObj).each(function(i, el) {
if ($(el).hasClass("b")) {
words.push("[" + $(el).text().trim() + "]");
} else {
words.push($(el).text().trim());
}
});

...对此:

$(tObj).contents().each(function (i, el) {
if (el.nodeType !== 3 && !$(el).is(".w")) return; // Only regard ".w" or text nodes
if ($(el).hasClass("b")) {
words.push("[" + $(el).text().trim() + "]");
} else {
words.push($(el).text().trim());
}
});

现在,您输入的文本将不会从 words 中省略,即使您在作为内容可编辑元素的直接子级的文本节点中键入该文本也是如此。

添加空格

您的代码使用 .join("") 添加空格,而没有验证文本片段是否确实由 p 元素内容中的空格分隔。因此,我会抓取所有内容,包括间距,然后将其连接起来。这样,您将获得与 p 元素中完全相同的单词分隔。

那么你的函数将是:

  function unChunkWords(tObj) {
var words = "";
$(tObj).contents().each(function (i, el) {
if ($(el).hasClass("b")) {
words += "[" + $(el).text() + "]";
} else {
words += $(el).text();
}
});
return words.replace(/\s+/g, " ").trim();
}

免责声明:我只研究了这个特定问题,指出为什么您有这种特定行为,以及如何解决它。这并不意味着现在您的代码将在其所有预期功能中正常工作,这超出了问题的范围。

关于javascript - 如何避免从 jQuery 中的 contenteditable <p> 中删除键入的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58527619/

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