我正在创建一种编辑动态内容的方法。我在这里发现了一个问题,让我开始将文本(在我的例子中为跨度)更改为输入字段。
目前,我无法解决以下问题。当您单击“编辑”(右侧)时,输入字段将替换跨度(这就是我想要的),但是当您单击输入外部时,输入字段将添加新的跨度字段而不是替换输入字段。
我希望样式和字段始终保持在原来的位置。
有人看出我做错了什么吗?
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/