如何拖放组件作为第一个单词
how drag and drop component as first word
我正在使用 jQuery UI 可拖动组件添加到可编辑的内容
。这段代码可以找到,但我遇到了一个小问题。问题是我不能拖放可拖动组件作为第一个词,我该如何解决这个问题?请帮我解决这个问题。
注意:当前功能无法破解。
我的代码如下:
$(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 = " " + txt;
}
if (sp[1]) {
txt = txt + " ";
}
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] = " " + b.prop("outerHTML") + " ";
} 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 = "";
$(tObj).contents().each(function (i, el) {
if ($(el).hasClass("b")) {
words += "[" + $(el).text() + "]";
} else {
words += $(el).text();
}
});
return words.replace(/\s+/g, " ").trim();
}
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>
您可以执行以下操作:
1。判断是否在第一个元素前插入
拖动过程中:
- 当可拖动元素悬停在文本中的第一个单词上时进行监视。
- 如果是这样,请检查它是否更多地悬停在单词的左侧或右侧
- 如果左边多,则去掉第二个字的高亮
- 如果更靠右,则恢复第二个字的高亮
因此,此视觉指示将指示该词是插入第一个词之后(突出显示 2 个)还是插入第一个词之前(突出显示 1 个)。
2。相应地执行下降
当用户放下元素时:
- 检查是否突出显示了第一个单词,而不是任何其他单词。
- 如果是,插入新元素在当前词之前
- 如果没有,则在当前单词之后插入新元素(就像已经完成一样)
因此,您需要对代码进行两处更改才能使其正常工作:
添加以下代码来实现第一部分:
document.addEventListener("mousemove", function() {
var $draggable = $(".ui-draggable-dragging");
if (!$draggable.length) return; // nothing is being dragged
var $highlighted = $(".ui-state-highlight");
if (!$highlighted.length || $($highlighted).index() > 0) return; // first word is not highlighted
// Get center x coordinate of the item that is being dragged
var dragX = $draggable.offset().left + $draggable.width() / 2;
// Get center x coordinate of the first word in the paragraph
var firstX = $highlighted.offset().left + $highlighted.width() / 2;
// If draggable is more on the left side of the first word, then only the first word should be highlighted
if ((dragX < firstX) === ($highlighted.length < 2)) return; // Situation is as it should be
// Toggle the highlight on the second word of the paragraph
$highlighted.first().next("span.w").toggleClass("ui-state-highlight");
});
修改 drop
处理程序以实现第二部分:
drop: function(e, ui) {
var txt = ui.draggable.text();
// Use proper jQuery to create a new span element
var newSpan = $("<span>").addClass('w b').text(txt);
// Determine if the element is being dropped on the first word, and only that one
if (!$(".ui-state-highlight").last().index()) {
$(this).before(newSpan, " "); // ...then prepend
} else {
$(this).after(" ", newSpan); // normal case
}
makeBtn(newSpan);
makeDropText(newSpan);
$("span.w.ui-state-highlight").removeClass("ui-state-highlight");
},
修复 chunkWords
出于某种原因,您在 chunkWords
中进行了硬编码,第一个单词(在索引 0 处)不能是丢弃的项目 -- 它始终被解释为纯文本(标记为粗体)。这也是您当前代码中的一个错误,您可以按如下方式重现它:
- 在前两个词之间删一个词
- 编辑文本并删除第一个词,使删除的词成为第一个词
- 退出编辑区
- 第一个词现在不再是被丢弃的元素,而是带有 "button" 标记(方括号)的词。
您写道,现有行为不应中断,但从评论中我了解到您并未预料到这种行为。
另一个问题是该函数中的以下条件:
if (words[0].indexOf(".")) {
...想一想:为什么 first 单词中的一个点会影响短语中 another 单词的间距?您肯定打算这样做:
if (words[i].indexOf(".")) {
无论如何,我建议完全不要使用 textWrapper
,并在最后的 join
中添加空格。之前没有。
解决这两个问题,chunkWords
最终应该是这样的:
function chunkWords(p) {
var words = p.split(" "), b;
for (var i = 0; i < words.length; i++) {
if (/\[.+\]/.test(words[i])) {
b = makeTextBox(words[i].slice(1, -1));
} else {
b = $("<span>").addClass("w").text(words[i]);
}
// do not pad the value with " " at this moment:
words[i] = b.prop("outerHTML");
}
return words.join(" "); // add the spaces here
}
随着这些更改 textWrapper
不再使用,您可以删除该功能。
查看 this fiddle
中应用的更改
我正在使用 jQuery UI 可拖动组件添加到可编辑的内容
。这段代码可以找到,但我遇到了一个小问题。问题是我不能拖放可拖动组件作为第一个词,我该如何解决这个问题?请帮我解决这个问题。
注意:当前功能无法破解。
我的代码如下:
$(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 = " " + txt;
}
if (sp[1]) {
txt = txt + " ";
}
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] = " " + b.prop("outerHTML") + " ";
} 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 = "";
$(tObj).contents().each(function (i, el) {
if ($(el).hasClass("b")) {
words += "[" + $(el).text() + "]";
} else {
words += $(el).text();
}
});
return words.replace(/\s+/g, " ").trim();
}
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>
您可以执行以下操作:
1。判断是否在第一个元素前插入
拖动过程中:
- 当可拖动元素悬停在文本中的第一个单词上时进行监视。
- 如果是这样,请检查它是否更多地悬停在单词的左侧或右侧
- 如果左边多,则去掉第二个字的高亮
- 如果更靠右,则恢复第二个字的高亮
因此,此视觉指示将指示该词是插入第一个词之后(突出显示 2 个)还是插入第一个词之前(突出显示 1 个)。
2。相应地执行下降
当用户放下元素时:
- 检查是否突出显示了第一个单词,而不是任何其他单词。
- 如果是,插入新元素在当前词之前
- 如果没有,则在当前单词之后插入新元素(就像已经完成一样)
因此,您需要对代码进行两处更改才能使其正常工作:
添加以下代码来实现第一部分:
document.addEventListener("mousemove", function() {
var $draggable = $(".ui-draggable-dragging");
if (!$draggable.length) return; // nothing is being dragged
var $highlighted = $(".ui-state-highlight");
if (!$highlighted.length || $($highlighted).index() > 0) return; // first word is not highlighted
// Get center x coordinate of the item that is being dragged
var dragX = $draggable.offset().left + $draggable.width() / 2;
// Get center x coordinate of the first word in the paragraph
var firstX = $highlighted.offset().left + $highlighted.width() / 2;
// If draggable is more on the left side of the first word, then only the first word should be highlighted
if ((dragX < firstX) === ($highlighted.length < 2)) return; // Situation is as it should be
// Toggle the highlight on the second word of the paragraph
$highlighted.first().next("span.w").toggleClass("ui-state-highlight");
});
修改 drop
处理程序以实现第二部分:
drop: function(e, ui) {
var txt = ui.draggable.text();
// Use proper jQuery to create a new span element
var newSpan = $("<span>").addClass('w b').text(txt);
// Determine if the element is being dropped on the first word, and only that one
if (!$(".ui-state-highlight").last().index()) {
$(this).before(newSpan, " "); // ...then prepend
} else {
$(this).after(" ", newSpan); // normal case
}
makeBtn(newSpan);
makeDropText(newSpan);
$("span.w.ui-state-highlight").removeClass("ui-state-highlight");
},
修复 chunkWords
出于某种原因,您在 chunkWords
中进行了硬编码,第一个单词(在索引 0 处)不能是丢弃的项目 -- 它始终被解释为纯文本(标记为粗体)。这也是您当前代码中的一个错误,您可以按如下方式重现它:
- 在前两个词之间删一个词
- 编辑文本并删除第一个词,使删除的词成为第一个词
- 退出编辑区
- 第一个词现在不再是被丢弃的元素,而是带有 "button" 标记(方括号)的词。
您写道,现有行为不应中断,但从评论中我了解到您并未预料到这种行为。
另一个问题是该函数中的以下条件:
if (words[0].indexOf(".")) {
...想一想:为什么 first 单词中的一个点会影响短语中 another 单词的间距?您肯定打算这样做:
if (words[i].indexOf(".")) {
无论如何,我建议完全不要使用 textWrapper
,并在最后的 join
中添加空格。之前没有。
解决这两个问题,chunkWords
最终应该是这样的:
function chunkWords(p) {
var words = p.split(" "), b;
for (var i = 0; i < words.length; i++) {
if (/\[.+\]/.test(words[i])) {
b = makeTextBox(words[i].slice(1, -1));
} else {
b = $("<span>").addClass("w").text(words[i]);
}
// do not pad the value with " " at this moment:
words[i] = b.prop("outerHTML");
}
return words.join(" "); // add the spaces here
}
随着这些更改 textWrapper
不再使用,您可以删除该功能。
查看 this fiddle
中应用的更改