【问题标题】:Make a p element both content editable and JQuery UI Sortable使 p 元素既可编辑内容又可排序 JQuery UI
【发布时间】:2017-09-14 06:26:09
【问题描述】:
是否可以使 p 元素既可编辑内容又可排序 JQuery UI?
在下面我的简单示例中,p 元素是可排序的,但您不能编辑它们的文本。有没有办法克服这个问题?
请注意,我已尝试将 p 嵌套在容器中,以便容器可排序且 p 可编辑,但我仍然无法编辑内部 p。
$(document).ready(function() {
$( ".elements" ).sortable({
connectWith: ".elements"
});
});
p {
height: 100px;
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="../dist/js/visual-designer.min.js"></script>
<div class="elements">
<p id="foo" contenteditable="true">Foo. Help! I can be sorted but cannot be edited.</p>
<!-- Even if I nest p's in a container they still are not editable -->
<div class="test-container">
<p id="bar" contenteditable="true">Bar. Help! I can be sorted but cannot be edited.</p>
</div>
</div>
【问题讨论】:
标签:
javascript
jquery
jquery-ui
contenteditable
【解决方案1】:
通过一些随机尝试使其工作,我发现将焦点设置在元素上,然后将光标移动到可编辑内容的末尾(如 here 所示 Nico Burns)足以获得内容可编辑工作。
我的猜测是,由于某种event.preventDefault 或cancelBubble,可排序内容会阻止可编辑内容获得焦点。
$(document).ready(function() {
$(".elements").sortable({
connectWith: ".elements"
});
$(".elements p").on("click", function(e) {
$(this).focus();
setEndOfContenteditable(e.target);
});
});
function setEndOfContenteditable(contentEditableElement) {
var range, selection;
if (document.createRange) //Firefox, Chrome, Opera, Safari, IE 9+
{
range = document.createRange(); //Create a range (a range is a like the selection but invisible)
range.selectNodeContents(contentEditableElement); //Select the entire contents of the element with the range
range.collapse(false); //collapse the range to the end point. false means collapse to end rather than the start
selection = window.getSelection(); //get the selection object (allows you to change selection)
selection.removeAllRanges(); //remove any selections already made
selection.addRange(range); //make the range you have just created the visible selection
} else if (document.selection) //IE 8 and lower
{
range = document.body.createTextRange(); //Create a range (a range is a like the selection but invisible)
range.moveToElementText(contentEditableElement); //Select the entire contents of the element with the range
range.collapse(false); //collapse the range to the end point. false means collapse to end rather than the start
range.select(); //Select the range (make it the visible selection
}
}
p {
height: 50px;
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="../dist/js/visual-designer.min.js"></script>
<div class="elements">
<p id="foo" contenteditable="true">Foo. Help! I can be sorted but cannot be edited.</p>
<div>
<p id="bar" contenteditable="true">Bar. Help! I can be sorted but cannot be edited.</p>
</div>
</div>
【解决方案3】:
这里是一个例子,当点击元素时,p标签被转换为input标签,当焦点丢失时,它被转换回p标签!
$(document).ready(function() {
// How to associate a handle that sits outside the element to be dragged?
$( ".elements" ).sortable({
connectWith: ".foo"
});
function focusout(){
var val = $('input[contenteditable*="true"]').val();
var replacement2 = $('<p contenteditable="true">'+val+'</p>');
$('input[contenteditable*="true"]').replaceWith(replacement2);
replacement2.on("click", clicked);
}
function clicked(){
var replacement = $('<input contenteditable="true" value="'+this.innerHTML+'"/>');
$(this).replaceWith(replacement);
replacement.on("focusout", focusout);
$('input[contenteditable*="true"]').focus();
}
$('p[contenteditable*="true"]').on("click", clicked);
});
p {
height: 100px;
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="elements">
<p id="foo" contenteditable="true">Foo. Help! I can be sorted but cannot be edited.</p>
<!-- Even if I nest p's in a container they still are not editable -->
<div class="test-container">
<p id="bar" contenteditable="true">Bar. Help! I can be sorted but cannot be edited.</p>
</div>
</div>