当父元素是 contentEditable 时,是不是可以防止子元素被删除?
Posted
技术标签:
【中文标题】当父元素是 contentEditable 时,是不是可以防止子元素被删除?【英文标题】:Is it possible to prevent child elements from being deleted when their parent is contentEditable?当父元素是 contentEditable 时,是否可以防止子元素被删除? 【发布时间】:2019-02-20 06:33:20 【问题描述】:当元素为contentEditable
时,可以删除其子元素。如果这些子元素之一是 not contentEditable
,则无法编辑子元素的内容,但仍可以删除元素本身。您可以在以下示例中看到这一点。
是否可以防止这些子元素被删除?
div
height: 100px;
border: 1px solid #CCC;
margin: 5px;
padding: 5px;
width: 300px;
span
color: #999;
<div contentEditable="true">Hello <span contentEditable="false">world</span>!</div>
【问题讨论】:
好问题!我唯一能想到的就是实际创建单独的 div,并将外部的 div 标记为 contentEditable:<div><span contentEditable="true">Hello </span><span contentEditable="false">world</span><span contentEditable="true">!</span></div>
感谢您的建议。虽然这在技术上可行,但会导致我希望避免的繁琐用户体验。
【参考方案1】:
如果你可以使用类,那就很容易了。
<div class="contentEditable">Hello <span class="contentNotEditable">world</span>!</div>
<div class="saveContent" style="display: none;"></div>
javascript/Jquery 部分
<script>
$(".contentEditable").on("click",function()
// make blank .saveContent
$(".saveContent").html("");
// copy all contentNotEditable class which inside selected contentEditable class.
$( this ).find(".contentNotEditable").clone().appendTo( ".saveContent" );
// make blank contentEditable
$( this ).html("");
// clone contentNotEditable to contentEditable
$( ".saveContent" ).find(".contentNotEditable").clone().appendTo( ".contentEditable" );
);
</script>
【讨论】:
它在我的测试中运行良好。但它需要jquery。当你点击 .contentEditable 区域时,它只显示 contentNotEditable 区域。 @Fatihd 您应该在工作代码 sn-p 中演示它。【参考方案2】:是否可以防止这些子元素被删除?
不,但这里有一个替代解决方案。
演示:
由于我们不能有直接的子元素,我们需要创建两个独立的元素。
<div class="editor">
<label class="editor-label">You can't remove me</label>
<div class="editor-area" contentEditable="true"></div>
</div>
然后,我们从流程中移除 label,使其不会对 area 产生任何影响。
.editor
border: solid 1px #CCC;
position: relative; // context for label
line-height: 1.5;
.editor-area
min-height: 100px;
padding: 5px;
.editor-label
position: absolute; // out of the flow
padding: 5px 0 0 5px;
user-select: none;
最后,为了使插入符号在 label 文本之后开始,我们需要知道它的宽度并将其应用于 area 的 text-indent
值。
var editorLabel = document.querySelector('.editor-label');
var editorArea = document.querySelector('.editor-area');
var editorLabelRect = editorLabel.getBoundingClientRect();
editorArea.style.textIndent = editorLabelRect.width + 'px';
editorArea.innerHTML = ' ';
完整代码:
var editorLabel = document.querySelector('.editor-label');
var editorArea = document.querySelector('.editor-area');
var editorLabelRect = editorLabel.getBoundingClientRect();
editorArea.style.textIndent = editorLabelRect.width + 'px';
editorArea.innerHTML = ' ';
.editor
border: solid 1px #CCC;
position: relative;
line-height: 1.5;
.editor-area
min-height: 100px;
padding: 5px;
.editor-label
position: absolute;
margin: 5px 0 0 5px;
user-select: none;
<div class="editor">
<label class="editor-label">You can't remove me</label>
<div class="editor-area" contentEditable="true"></div>
</div>
【讨论】:
以上是关于当父元素是 contentEditable 时,是不是可以防止子元素被删除?的主要内容,如果未能解决你的问题,请参考以下文章
contenteditable:使用行/列修饰符时检测元素变化
KnockoutJS - 禁用绑定 - 当父元素有值时如何禁用子元素