将p元素设置为内容可编辑和JQuery UI Sortable

时间:2017-09-14 06:26:10

标签: javascript jquery jquery-ui contenteditable

是否可以将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>

3 个答案:

答案 0 :(得分:2)

通过一些随机尝试使其工作,我发现将焦点设置在元素上,然后将光标移动到内容的可编辑末尾(如here所示Nico Burns)是足以使内容可编辑工作。

我的猜测是,由于某种event.preventDefaultcancelBubble,可排序会阻止可编辑内容获得焦点。

&#13;
&#13;
$(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
  }
}
&#13;
p {
  height: 50px;
  background-color: red;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

可能它不允许该版本,因为Jquery会覆盖默认情况下在 contenteditable = true 元素中启用的某些事件回调。

您可以尝试覆盖 focusin 焦点事件,以便允许该版本。在下面的链接中查看他们是如何做到的:

Focus / blur events on contenteditable elements

我希望它会帮助你;)

答案 2 :(得分:0)

下面是一个示例,当点击该元素时,p标记会转换为input标记,当焦点丢失时,会将其转换回p标记!

&#13;
&#13;
$(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);
  
});
&#13;
p {
	height: 100px;
	background-color: red;
}
&#13;
<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>
&#13;
&#13;
&#13;