Reputation: 12098
I'm playing the the Shadow DOM 101 tutorial at html5rocks.
I'm using Chrome 25.0.1364.172 and
when I try to appendChild
to the Shadow DOM root (as shown in the tutorial) I get an
Uncaught Error: NotFoundError: DOM Exception 8
.
I guess I'm missing something obvious but I can't figure out what. Here's
the code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test the shadow dom</title>
</head>
<body>
<div id="myName">Alon</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script id="myNameTemplate" type="text/x-tmpl-template">
<style>
.outer {
border:2px solid brown;
border-radius: 1em;
background: red;
font-size: 28pt;
width: 12em;
height:2em;
text-align: center;
}
.boilerplate {
color:white;
font-family: sans-serif;
padding:0.5em;
}
.name {
color:black;
background: white;
font-family: "Marker Felt", cursive;
font-size: 45pt;
padding-top:0.2em;
}
</style>
<div class="outer">
<div class="boilerplate">
Hi! my name is
</div>
<div class="name">
alon
</div>
</div>
</script>
<script>
$(document).ready(function(){
var shadow = document.querySelector("#myName").webkitCreateShadowRoot();
console.log(shadow);// I get #shadow-root in the console
var template = $("#myNameTemplate").html();//also tried text(), without jQuery with innerHTML and other options
console.log(template);//I get the content of the template in the console
shadow.appendChild(template); //this part breaks
});
</script>
</body>
</html>
Since my browser doesn't support the new <template>
tag shown in the tutorial I changed it to <script type="text/x-tmpl">
.
Edit: I get the same error from the console when I try:
shadow.appendChild('<div></div>')
Error: NotFoundError: DOM Exception 8
Upvotes: 0
Views: 493
Reputation: 713
You have got some of the markup wrong and a few lines in the script that select the template are incorrect. I have modified the code so it works.
<script id="myNameTemplate" type="text/x-tmpl-template">
...
</script>
to this
<template id="myNameTemplate">
...
</template>
And in your script at the bottom of the page I modified your template var, it was using jQuery for some reason and not querySelector()
. So this code below
$(document).ready(function(){
var shadow = document.querySelector("#myName").webkitCreateShadowRoot();
console.log(shadow);// I get #shadow-root in the console
var template = $("#myNameTemplate").html();//also tried text(), without jQuery with innerHTML and other options
console.log(template);//I get the content of the template in the console
shadow.appendChild(template); //this part breaks
});
becomes this
$(document).ready(function(){
var shadow = document.querySelector("#myName").webkitCreateShadowRoot();
var template = document.querySelector("#myNameTemplate");
shadow.appendChild(template.content);
});
Here is the complete markup
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test the shadow dom</title>
</head>
<body>
<div id="myName">Alon</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<template id="myNameTemplate">
<style>
.outer {
border:2px solid brown;
border-radius: 1em;
background: red;
font-size: 28pt;
width: 12em;
height:2em;
text-align: center;
}
.boilerplate {
color:white;
font-family: sans-serif;
padding:0.5em;
}
.name {
color:black;
background: white;
font-family: "Marker Felt", cursive;
font-size: 45pt;
padding-top:0.2em;
}
</style>
<div class="outer">
<div class="boilerplate">
Hi! my name is
</div>
<div class="name">
alon
</div>
</div>
</template>
<script>
$(document).ready(function(){
var shadow = document.querySelector("#myName").webkitCreateShadowRoot();
console.log(shadow);// I get #shadow-root in the console
var template = document.querySelector("#myNameTemplate");//also tried text(), without jQuery with innerHTML and other options
console.log(template);//I get the content of the template in the console
shadow.appendChild(template.content); //this part breaks
});
</script>
</body>
You cannot use anything other than the .content
of the template AFAIK because template is a Document Fragment and to access that fragment you are required to select the inner content of the HTML5 element <template>
.
The way I look at it is that the <template>
tag is basically a static HTML way of creating a document fragment that you can grab with the javascript method querySelector()
. You could create the fragment using createDocumentFragment()
if you wanted to append the DOM through an extension or whatever but that's another bucket of frogs.
Upvotes: 0
Reputation: 76
appendChild()
has never worked like that
document.body.appendChild('<div></div>')
will give you the same error.
What you want is shadow.innerHTML = template;
Upvotes: 3