I'd like to normalize table rows. This works like a charm, except in IE (tested with IE 11).
I've created a demo snippet to demonstrate the issue:
$(function() {
$("table tbody tr span").each(function() {
var $this = $(this);
var $parent = $this.parent();
$this.replaceWith($this.html());
$parent[0].normalize();
});
});
<link href="https://cdn.jsdelivr.net/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>President</th>
<th>Birthplace</th>
</tr>
</thead>
<tbody>
<tr>
<td><span>Zach</span>ary Taylor</td>
<td>Barboursville, Virginia</td>
</tr>
</tbody>
</table>
This replaces the <span>
element with its content. After this step the node will look like:
Then, normalize()
is called to merge the splitted text nodes. However, in IE11 the text nodes are still splitted.
I can't see any issue from my side. What's the cause of this problem and what could be the solution?
As it turned out that this is a IE11 bug, I've filled in a bug report!
It seems like IE-11 can't normalize elements that are already part of your document If your developers toolbar is open.
This is also relevant for IE9 & 10 (emulated by using
meta http-equiv="X-UA-Compatible"
tag)
When you only create new nodes and you don't attach them to the document - everything works great (for both situations - developers toolbar is open and close):
d = document.createElement('div');
d.appendChild(document.createTextNode('text 1'));
d.appendChild(document.createTextNode('text 2'));
console.log(d.childNodes.length + ' - Should be 2')
d.normalize();
console.log(d.childNodes.length + ' - Should be 1')
If, however, you are working with nodes that are already part of your document, the normalize
function doesn't work if your developer toolbar is open:
d = document.getElementsByTagName('div')[0];
d.appendChild(document.createTextNode('text 1'));
d.appendChild(document.createTextNode('text 2'));
console.log(d.childNodes.length + ' - should be 2 on every browser')
d.normalize();
console.log(d.childNodes.length + ' - should be 1, however it\'s 2 on IE')
<div></div>
If you really want, what you can do is extract the nodes from the document and add them after you normalize them:
d = document.getElementsByTagName('div')[0];
d.appendChild(document.createTextNode('text 1'));
d.appendChild(document.createTextNode('text 2'));
console.log(d.childNodes.length + ' - should be 2 on every browser')
dNew = d.cloneNode(true)
dNew.normalize()
d.parentElement.replaceChild(dNew, d)
d = document.getElementsByTagName('div')[0];
console.log(d.childNodes.length + ' - should be 1 on every browser')
<div></div>
Update - 28/8
Answer was updated after the comment from @dude. It took some time to investigate the cause here, but I think that now I covered everything.
Note that for IE8 (forced by using
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">
in IE-11) thenormalize()
function works for both elements that are in the DOM tree and elements that are not, even with the developers toolbar was open.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With