javascript - 将跨度字段更改为输入字段以更新信息

标签 javascript jquery replace

我正在创建一种编辑动态内容的方法。我在这里发现了一个问题,让我开始将文本(在我的例子中为跨度)更改为输入字段。

目前,我无法解决以下问题。当您单击“编辑”(右侧)时,输入字段将替换跨度(这就是我想要的),但是当您单击输入外部时,输入字段将添加新的跨度字段而不是替换输入字段。

我希望样式和字段始终保持在原来的位置。

有人看出我做错了什么吗?

var projID = '';

	//Obtaining ID and Editing the projects
	$(document.body).on('click', '.recEdit', '[data-editable]', function() {
		projID = $(this).parent().data('recid');
		console.log('Project ID is..... ' + projID);

		var $el = $(this).parent().children().find('span');

		var $input = $('<input/>').val( $el.text() );
		$el.replaceWith( $input );

		var save = function(){
			var $p = $('<span data-editable class="recBaseFormat" />').text( $input.val() );
			$input.replaceWith( $p );
		};

  /**
    We're defining the callback with `one`, because we know that
    the element will be gone just after that, and we don't want 
    any callbacks leftovers take memory. 
    Next time `p` turns into `input` this single callback 
    will be applied again.
  */
		$input.one('blur', save).focus();
	});
.recentProjectCont {
	width: 98%;
	height: 85px;
	border-bottom: 1px solid #ccc;
	padding: 10px 0;
	margin: 0 10px;
	display: block;
	position: relative;
}
.recentProjectImg {
	width: 100px;
	height: 85px;
	display: inline-block;
	vertical-align: top;
}
.recentProjectImg img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.recProjInfoCont {
	display: inline-block;
	vertical-align: top;
	width: 80%;
	height: 100%;
	margin-left: 20px;
}
.recInfoCont1, .recInfoCont2 {
	height: 100%;
	display: inline-block;
	vertical-align: top;
}
.recInfoCont1 {
	width: 40%;
}
.recInfoCont2 {
	width: 52%;
	text-align: right;
}
.recBaseFormat, .projectViews {
	letter-spacing: .1rem;
	line-height: 1.4em;
	color: #2f2f2f;
	display: block;
	margin-bottom: 5px;
}
.recProjName {
	font-size: 1.1rem;
	font-family: 'Muli', sans-serif;
}
.recInfoStat, .projectViews {
	font-size: .7rem;
	font-family: 'Nunito', sans-serif;
}
.recEdit {
	position: absolute;
	top: 20%;
	left: 97%;
	cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="recentProjectCont">
	<div class="recProjInfoCont">
		<div class="recInfoCont1">
			<span class="recProjName recBaseFormat" data-editable>Name</span>
			<span class="recInfoStat recBaseFormat recAlt" data-editable>Alt</span>
			<span class="recInfoStat recBaseFormat recCat" data-editable>Category</span>
		</div>
		<div class="recInfoCont2">
			<span class="recInfoStat recBaseFormat" data-editable>Status</span>
			<span class="recInfoStat recBaseFormat" data-editable>Creator</span>
		</div>
	</div>
	<div class="recEdit">Edit</div>
</div>

最佳答案

这段代码绝对可以优化,但它应该让你朝着正确的方向前进。您的代码存在一些问题。我上面提到的问题是,您的选择器仅针对父元素中的最后一个 span 元素。我们可以通过使用 each method 来解决这个问题循环父级中的每个 span 。另一个问题是,当您用输入替换跨度的类时,您会丢失它们。我已经解决了这个问题,方法是先保存每个跨度的类列表,然后再将它们替换为输入,以便在将它们转换回跨度时可以重新应用它们。最后,您在任何输入模糊时为所有输入触发 save 函数,这意味着用户只能编辑一个范围,然后当他们单击时,所有输入都将被转换回来。相反,现在只有当您取消对每个特定输入的关注时,它才会转换回来。

var projID = '';

//Obtaining ID and Editing the projects
$(document.body).on('click', '.recEdit', '[data-editable]', function() {
	projID = $(this).parent().data('recid');
	console.log('Project ID is..... ' + projID);

	$(this).parent().children().find('span').each(function() {
		var classList = $(this).attr('class');
		$input = $('<input/>').val($(this).text());

		$(this).replaceWith($input);
		$input.on('blur',function() {
			$(this).replaceWith('<span data-editable class="' + classList + '">' + $(this).val() + '</span>');
		});
	});
});
.recentProjectCont {
	width: 98%;
	height: 85px;
	border-bottom: 1px solid #ccc;
	padding: 10px 0;
	margin: 0 10px;
	display: block;
	position: relative;
}
.recentProjectImg {
	width: 100px;
	height: 85px;
	display: inline-block;
	vertical-align: top;
}
.recentProjectImg img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.recProjInfoCont {
	display: inline-block;
	vertical-align: top;
	width: 80%;
	height: 100%;
	margin-left: 20px;
}
.recInfoCont1, .recInfoCont2 {
	height: 100%;
	display: inline-block;
	vertical-align: top;
}
.recInfoCont1 {
	width: 40%;
}
.recInfoCont2 {
	width: 52%;
	text-align: right;
}
.recBaseFormat, .projectViews {
	letter-spacing: .1rem;
	line-height: 1.4em;
	color: #2f2f2f;
	display: block;
	margin-bottom: 5px;
}
.recProjName {
	font-size: 1.1rem;
	font-family: 'Muli', sans-serif;
}
.recInfoStat, .projectViews {
	font-size: .7rem;
	font-family: 'Nunito', sans-serif;
}
.recEdit {
	position: absolute;
	top: 20%;
	left: 97%;
	cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="recentProjectCont">
	<div class="recProjInfoCont">
		<div class="recInfoCont1">
			<span class="recProjName recBaseFormat" data-editable>Name</span>
			<span class="recInfoStat recBaseFormat recAlt" data-editable>Alt</span>
			<span class="recInfoStat recBaseFormat recCat" data-editable>Category</span>
		</div>
		<div class="recInfoCont2">
			<span class="recInfoStat recBaseFormat" data-editable>Status</span>
			<span class="recInfoStat recBaseFormat" data-editable>Creator</span>
		</div>
	</div>
	<div class="recEdit">Edit</div>
</div>

最后,正如其他人提到的,另一种选择是使用 contenteditable attribute在你的跨度上。这是一个 HTML 解决方案,用于编辑默认情况下不可编辑的 HTML 元素。它本质上与您尝试使用 Javascript 执行的操作相同,但它更加简洁。它还具有 very good browser support 。该解决方案的一个缺点是,用户不会立即清楚该元素是可编辑的,就像使用显示“编辑”的实际按钮一样。但也有一些解决方案。

<span contenteditable="true">You can edit me</span>

关于javascript - 将跨度字段更改为输入字段以更新信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57699725/

相关文章:

javascript - 将副本添加到索引模板上的elasticsearch

javascript - highlight.js 内联模式可能吗?

javascript - 获取等高列 jQuery 插件和 Disqus 以发挥良好的作用

javascript - 查询/CSS : Change the css of a cloned tr

java - 在 ArrayList 中搜索字符串中的特定字符

javascript - 更改仅适用于表中的第一行

javascript - 使用 Jquery UI 的对话框出现问题

javascript - 返回对象在第二次迭代时返回未定义

javascript - 每次在字符串中找到匹配项时都会运行该函数

string - bash echo 中的 *G* 是什么意思?