Tuesday, August 21, 2018
OuterHTML breaks DOM?
Change the outerHTML of (say) a td element using the DOM within Javascript.
See the content change on the page.
Then try to make a further change to the td and get bizarre results.
Has changing the outerHTML broken the DOM?
No - but it has wrecked the definition of the td that you are using to set or get properties.
Solution - after setting outerHTML - EVEN if the new outerHTML specifies the same id as the cell currently uses - you MUST redefine the object that your Javascript is using to refer to that cell.
In the example below, you can change the initial text to EITHER interim or final text. But once you have made the change, a subsequent change won't work - until you have redefined the variable "targetCell" which is used to refer to the td
(And note that if you are applying outerHTML to a cell that does not have a parent, even redefinition won't help: "If the element has no parent element, setting its outerHTML property will not change it or its descendants" - source)
<html>
<head>
<meta charset="UTF-8">
<script>
var targetCell;
function doInterim(){
var newHTML="<td id='target'>Interim content</td>";
targetCell.outerHTML=newHTML;
alert("targetCell has innerHTML of "+targetCell.innerHTML);
}
function doFinal(){
var newHTML="<td id='target'>Final content</td>";
targetCell.outerHTML=newHTML;
alert("targetCell has innerHTML of "+targetCell.innerHTML);
}
function defineTarget(){
targetCell=document.getElementById('target');
alert("targetCell has innerHTML of "+targetCell.innerHTML);
}
</script>
</head>
<body onload='defineTarget();'>
<table id='tab1'>
<tr id='row1'>
<td id='target'>Original Content</td>
</tr>
</table>
<p><a href='javascript: doInterim();'>CHANGE to Interim</a></p>
<p><a href='javascript: doFinal();'>CHANGE targetCell to Final</a></p>
<p><a href='javascript: defineTarget();'>Re-define targetCell</a></p>
</body>
</html>
See the content change on the page.
Then try to make a further change to the td and get bizarre results.
Has changing the outerHTML broken the DOM?
No - but it has wrecked the definition of the td that you are using to set or get properties.
Solution - after setting outerHTML - EVEN if the new outerHTML specifies the same id as the cell currently uses - you MUST redefine the object that your Javascript is using to refer to that cell.
In the example below, you can change the initial text to EITHER interim or final text. But once you have made the change, a subsequent change won't work - until you have redefined the variable "targetCell" which is used to refer to the td
(And note that if you are applying outerHTML to a cell that does not have a parent, even redefinition won't help: "If the element has no parent element, setting its outerHTML property will not change it or its descendants" - source)
<html>
<head>
<meta charset="UTF-8">
<script>
var targetCell;
function doInterim(){
var newHTML="<td id='target'>Interim content</td>";
targetCell.outerHTML=newHTML;
alert("targetCell has innerHTML of "+targetCell.innerHTML);
}
function doFinal(){
var newHTML="<td id='target'>Final content</td>";
targetCell.outerHTML=newHTML;
alert("targetCell has innerHTML of "+targetCell.innerHTML);
}
function defineTarget(){
targetCell=document.getElementById('target');
alert("targetCell has innerHTML of "+targetCell.innerHTML);
}
</script>
</head>
<body onload='defineTarget();'>
<table id='tab1'>
<tr id='row1'>
<td id='target'>Original Content</td>
</tr>
</table>
<p><a href='javascript: doInterim();'>CHANGE to Interim</a></p>
<p><a href='javascript: doFinal();'>CHANGE targetCell to Final</a></p>
<p><a href='javascript: defineTarget();'>Re-define targetCell</a></p>
</body>
</html>