I find it more comfortable to take a look at the code first:
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>
Explanation:
At first we initialise two MutationObserver divEditableMutationObserver and childDivEditableMutationObserver.
The divEditableMutationObserver observes the the only contentEditableDiv element and calls the function manipulateAddedNode if a mutation has been observed.
The manipulateAddedNode function adds a select element and an id to the node and adds the added element to the childDivEditableMutationObserver (via observe).
When you run the Stack Snippet the described behaviour is complied.
Here are the issues:
If you click inside the p element and press enter a new p element gets created and the childDivEditableMutationObserver logs entirety 3 new mutation.
But this is horrible wrong:
- The
manipulateAddedNodefunction never gets called. In reference to my last question you have to notice that in this type of circumstances with adding a newpelement themutationof thedivEditableMutationObserverrecords the already existingpelement with the idcontent0e. This is also obvious, because the newpelement does not have aselectelement. - This is far more important: Because the
manipulateAddedNodenever gets called with the newpelement it should not get observed by thechildDivEditableMutationObserver. With respect to the specification of theMutationObserverit should only record mutations which are of child objects not the observed object itself or even siblings of the observed objects. But as you can see thetargetattribute of the newly 3 logged mutations is<p>…</p>(the new element). Or am I wrong? The most horrible issue: In the 2. of the 3 logged mutation of the new created
pelement aselectelement is recorded underremovedNodes. However the newpelement never had aselectelement as a child:"removedNodes": { "0": <select contenteditable="false">…</select>, "item": /**ref:3**/, "length": 1 },
The 3. point is for me the most problematic, because in my js application the manipulateChildContent should detect a removed select element and deletes the whole parent p element if the following query equals true:
mutation.removedNodes.length && mutation.removedNodes[0].nodeName == "SELECT"
It is obvious that the problem(s) has(/have) something todo with the creation of the new p element, like it gets copied or something like that.
Questions:
- Like I described in the forelast sentence I need a way to determine that the removed element of an
pparagraph element is an already EXISTINGselectso the entirepelement gets deleted. How can I determine this in the circumstances described (the 2. mutation hits the requirements) ? - How the hell does Javascript creates the new
pelement? AND - Why does it gets recorded by the mutation observer ?
I appreciate your help!