首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MutationObserver记录错误的DOM元素(可编辑的div)

MutationObserver记录错误的DOM元素(可编辑的div)
EN

Stack Overflow用户
提问于 2016-10-07 19:29:47
回答 2查看 397关注 0票数 0

请考虑以下几点:

我有一个contenteditable div:

代码语言:javascript
运行
复制
<div id="contentEditableDiv" contenteditable="true">
    <p id="content0e">Lorem ipsum...</p>
    <p id="content1e">Lorem ipsum...</p>
</div>

我添加了一个MutationObserver来观察JavaScript中这个div中DOM的变化:

代码语言:javascript
运行
复制
var mutationObserver = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        manipulateAddedContent(mutation);
    });
});

mutationObserver.observe(jQuery("#contentEditableDiv")[0], 
    { attributes: true, childList: true, characterData: true });

在解决了这个问题之后,我想要manipulateAddedContent。然而,这个函数是这样声明的:

代码语言:javascript
运行
复制
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元素,因此p看起来如下:

代码语言:javascript
运行
复制
Inspector:
    <div id="contentEditableDiv" contenteditable="true" style="...">
        <p id="content0e">Lorem ipsum...</p>
        <p id="content1e">Lorem ipsum...</p>
        <p></p>
    </div>

但是MutationObserver用id="content1e"记录已经存在的p元素。

嗯,由于预期MutationObserver不会做好它,我也很高兴,如果你能给我一个替代解决方案。

下面是一个堆栈片段。如果在现有的p元素中使用光标单击并按enter,将创建一个新的p元素。MutationObserver记录已经存在的p元素,但不记录新创建的元素。

堆栈片段:

代码语言:javascript
运行
复制
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]);
		}
	}
}
代码语言:javascript
运行
复制
	#contentEditableDiv {
		border: 1px solid black;
		min-height: 200px;
		width: 200px;
	}

	#contentEditableDiv p{
		border: 1px solid red;
		margin-left: 5px;
		margin-right: 5px;
	}
代码语言:javascript
运行
复制
<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会记录错误的元素呢?

如何修复它?=>如何获得新添加的p元素(没有id)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-09 17:24:16

有一个解决办法很简单。我只是让我获得返回的一个DOM元素:

代码语言:javascript
运行
复制
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]);
		    }
		}
	}
}
代码语言:javascript
运行
复制
	#contentEditableDiv {
		border: 1px solid black;
		min-height: 200px;
		width: 200px;
	}

	#contentEditableDiv p{
		border: 1px solid red;
		margin-left: 5px;
		margin-right: 5px;
	}
代码语言:javascript
运行
复制
<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返回错误的元素。

票数 0
EN

Stack Overflow用户

发布于 2021-01-14 14:32:47

这与MutationObserver无关,它没有返回错误的元素。当您在contenteditable容器中的任何元素中按enter键时,它会被复制,这就是为什么MutationObserver报告的元素具有相同的id。如果您试图通过DevTools定位元素,它将显示最近添加的元素--因为它具有相同的id。

代码语言:javascript
运行
复制
#uniqueOrIsIt {
 border: 1px solid gold;
}
.paragraph {
 border: 1px solid blue;
}
代码语言:javascript
运行
复制
<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吗?在这种情况下,您可以对每个突变检查是否有任何addedNodesp元素,如果是,则为它们分配一个唯一的id。保持一个简单的let counter = 1,并将ids设置为addedNode.setAttribute('id', ('content' + counter++))

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39924545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档