请考虑以下事项:
我有contenteditable
div:
<div id="contentEditableDiv" contenteditable="true">
<p id="content0e">Lorem ipsum...</p>
<p id="content1e">Lorem ipsum...</p>
</div>
我添加一个MutationObserver来观察JavaScript中此div中的DOM更改:
var mutationObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
manipulateAddedContent(mutation);
});
});
mutationObserver.observe(jQuery("#contentEditableDiv")[0],
{ attributes: true, childList: true, characterData: true });
解决此问题后,我想manipulateAddedContent
。然而,函数声明如下:
function manipulateAddedContent(mutation){
jqMutation = jQuery(mutation);
if(jqMutation.prop("addedNodes").length > 0){
for (i = 0; i < jqMutation.prop("addedNodes").length; i++) {
console.log(mutation.addedNodes[i]);
}
}
}
在contenteditable
div中,可以通过在现有p
元素中按Enter键来添加新的p
DOM元素,因此HTML看起来像:
Inspector:
<div id="contentEditableDiv" contenteditable="true" style="...">
<p id="content0e">Lorem ipsum...</p>
<p id="content1e">Lorem ipsum...</p>
<p></p>
</div>
但MutationObserver使用p
记录已存在的id="content1e"
元素。
嗯,由于期望MutationObserver不能正确行事,如果你能给我一个替代解决方案,我也很高兴。
下面是一个Stack Snippet。如果单击其中一个现有p
元素内的光标并按Enter键,则会创建一个新的p
元素。 MutationObserver记录已存在的p
元素,但不记录新创建的元素。
Stack Snippet:
var mutationObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
manipulateAddedContent(mutation);
});
});
mutationObserver.observe(jQuery("#contentEditableDiv")[0],
{ attributes: true, childList: true, characterData: true });
function manipulateAddedContent(mutation){
jqMutation = jQuery(mutation);
if(jqMutation.prop("addedNodes").length > 0){
for (i = 0; i < jqMutation.prop("addedNodes").length; i++) {
console.log(mutation.addedNodes[i]);
}
}
}
#contentEditableDiv {
border: 1px solid black;
min-height: 200px;
width: 200px;
}
#contentEditableDiv p{
border: 1px solid red;
margin-left: 5px;
margin-right: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="contentEditableDiv" contenteditable="true" >
<p id="content0">Lorem ipsum...</p>
<p id="content1">Lorem ipsum...</p>
</div>
那么为什么MutationObserver会记录错误的元素?
我该如何解决? =&GT;如何获取新添加的p
元素(没有id)?
答案 0 :(得分:0)
一种解决方案非常简单。我只是让我得到返回的一个DOM元素:
var mutationObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
manipulateAddedContent(mutation);
});
});
mutationObserver.observe(jQuery("#contentEditableDiv")[0],
{ attributes: true, childList: true, characterData: true });
function manipulateAddedContent(mutation){
jqMutation = jQuery(mutation);
if(jqMutation.prop("addedNodes").length > 0){
for (i = 0; i < jqMutation.prop("addedNodes").length; i++) {
if(typeof jQuery(mutation.addedNodes[i]).next()[0] !== "undefined"){
console.log(jQuery(mutation.addedNodes[i]).next()[0]);
}
}
}
}
#contentEditableDiv {
border: 1px solid black;
min-height: 200px;
width: 200px;
}
#contentEditableDiv p{
border: 1px solid red;
margin-left: 5px;
margin-right: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="contentEditableDiv" contenteditable="true" >
<p id="content0">Lorem ipsum...</p>
<p id="content1">Lorem ipsum...</p>
</div>
但我不接受我的回答,因为我仍然不知道为什么mutationObserver
会返回错误的元素。
答案 1 :(得分:0)
这与 MutationObserver
无关,它没有返回错误的元素。当您在 contenteditable
容器内的任何元素内按 Enter 时,它会被复制,这就是 MutationObserver
报告的元素具有相同 ID 的原因。如果您尝试通过 DevTools 定位该元素,它会向您显示最近添加的元素 - 因为它具有相同的 id。
#uniqueOrIsIt {
border: 1px solid gold;
}
.paragraph {
border: 1px solid blue;
}
<div contenteditable="true">
<p id="uniqueOrIsIt">text</p>
<p class="paragraph">text</p>
<p style="border: 1px solid green;color:green">text</p>
</div>
所有三个 p
元素都将使用完全相同的属性进行复制。
解决方案取决于您要完成的任务 - 您是否希望每个插入的 p
元素都有一个新的唯一 ID?在这种情况下,您可以为每个突变检查 addedNodes
中的任何一个是否为 p
元素,如果是,则为它们分配一个唯一的 id。保持简单的 let counter = 1
并将 ID 设置为 addedNode.setAttribute('id', ('content' + counter++))