我发现首先看一下代码会更舒服:
jQuery(document).ready(function() {
var idCount = 0;
var divEditableMutationObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
manipulateAddedNode(mutation);
});
});
var childDivEditableMutationObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
manipulateChildContent(mutation);
});
});
var mutationObserverOptions = {childList: true, attributes: true, characterData: true};
divEditableMutationObserver.observe(jQuery("#contentEditableDiv")[0], mutationObserverOptions);
function manipulateChildContent(mutation){
console.log(mutation);
}
function manipulateAddedNode(mutation){
jqAddedNode = jQuery(mutation.addedNodes[0]);
if(!jqAddedNode.find("select").length){
childDivEditableMutationObserver.observe(jqAddedNode[0], mutationObserverOptions);
jqAddedNode.prepend(createTagSelector());
var addedNodeId = "content" + idCount + "e";
++idCount;
jqAddedNode.prop("id", addedNodeId);
}
}
function createTagSelector(){
tagSelector = jQuery(document.createElement("select"));
tagSelector.prop("contenteditable", false);
tagSelector.append("<option value='p'>p</option>");
tagSelector.append("<option value='div'>div</option>");
tagSelector.append("<option value='pre'>pre</option>");
return tagSelector;
}
jQuery("#contentEditableDiv").append("<p></p>");
});
#contentEditableDiv {
border: 1px solid black;
height: 200px;
width: 500px;
word-wrap: break-word;
overflow: auto;
}
#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" ></div>
说明:
首先我们初始化两个MutationObserver divEditableMutationObserver
和childDivEditableMutationObserver
。
divEditableMutationObserver
观察唯一的contentEditableDiv
元素,如果观察到突变则调用函数manipulateAddedNode
。
manipulateAddedNode
函数向节点添加select
元素和id
,并将添加的元素添加到childDivEditableMutationObserver
(通过observe
)。< / p>
运行Stack Snippet时,将遵循所描述的行为。
以下是问题:
如果您在p
元素内单击并按Enter键,则会创建一个新的p
元素,并且childDivEditableMutationObserver
会记录整个3个新的突变。
但这是一个可怕的错误:
manipulateAddedNode
函数。在提及我的last question时,您必须注意,在这种情况下,添加新的p
元素,mutation
的{{1}}会记录已存在的divEditableMutationObserver
p
标识为content0e
的元素。这也很明显,因为新的p
元素没有select
元素。manipulateAddedNode
永远不会被新的p
元素调用,所以childDivEditableMutationObserver
不应该观察它。关于MutationObserver
的规范,它应该只记录子对象的突变而不是被观察对象本身的突变,甚至是被观察对象的兄弟。但正如您所看到的,新记录的3个突变的target
属性为<p>…</p>
(新元素)。或者我错了吗?最可怕的问题:在新创建的p
元素的3个记录变异的2.中select
元素记录在removedNodes
下。但是,新的p
元素从未在子元素中使用select
元素:
"removedNodes": {
"0": <select contenteditable="false">…</select>,
"item": /**ref:3**/,
"length": 1
},
第3点对我来说是最有问题的,因为在我的js应用程序中,manipulateChildContent
应检测已删除的select
元素并删除整个父p
元素,如果以下查询等于真:
mutation.removedNodes.length && mutation.removedNodes[0].nodeName == "SELECT"
很明显,问题与新p
元素的创建有一些共同点,就像它被复制一样或类似的东西。
问题:
p
段落元素的已删除元素是否已经存在select
,因此整个p
元素将被删除。如何在所描述的情况下确定这一点(2.突变符合要求)?p
元素? AND 感谢您的帮助!