The customary <script type="text/template">
tag for client-side processing isn't sufficient for my purposes because it isn't nestable . So I'm trying to extend it to work around this limitation.
Basically I have some raw html with embedded images that I want to parse the content client-side using javascript. I like the script tag because images inside it are not loaded by the browser. But when the html contains script tags, they break my application. Here's how I'm trying to extend the tag:
<script>
var scriptData = document.registerElement('script-data', {
prototype: HTMLScriptElement.prototype
});
captureStart();
</script>
When executed, chrome throws the following error:
Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'script-data'. The prototype is already in-use as an interface prototype object.
Update:
Disputing my intentions or suggesting alternative methods is fine, however I still want an answer to my initial question: how does one extend the script tag?
How I'm using this is actually more complicated. I'm basically using this to "capture" the whole body of my HTML document, so that I can manipulate things before they are displayed. It's unconventional, I know. But I'm exploring it as a type of academic study.
The benefits to this approach include:
The challenges to this approach include:
My proposed solution to these problems:
Here's a larger sample of the code:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Script Test</title>
<style>
html, body {
margin: 0;
padding: 0;
}
</style>
<script>document.write("<script type='text/html' id='text-html'>");</script>
</head>
<body>
<img src="http://placehold.it/600x400" alt="" width="600" height="400"/>
</body>
</html>
<!--</script>
<script>
var content = document.getElementById("text-html");
document.write(content.innerHTML);
content.parentNode.removeChild(content);
</script>-->
Short answer: Use Object.create()
for the prototype object. The following code allows you to extend the script
element, and represents the way document.registerElement()
is meant to be used.
var scriptData = document.registerElement('script-data', {
prototype: Object.create(HTMLScriptElement.prototype);
});
Consider this variation on your original code:
var scriptDataProto = HTMLScriptElement.prototype;
// The next statement throws a DOMException of type "NotSupportedError".
var scriptData = document.registerElement('script-data', {
prototype: scriptDataProto
});
The source of the exception is illustrated here:
scriptDataProto === HTMLScriptElement.prototype; // true
You're providing a reference to HTMLScriptElement.prototype
, meaning that you want to use the exact same prototype for the custom script element you're creating. It's not very well documented yet, but the prototype you provide can't be a reference to any of the built-in HTML[*]Element
prototypes; you have to provide a new prototype object.
If you want to inherit from the <script>
tag's prototype, then you have to create a new prototype object that inherits from HTMLScriptElement.prototype
by using Object.create()
.
var scriptDataProto = Object.create(HTMLScriptElement.prototype);
scriptDataProto === HTMLScriptElement.prototype; // false
If you'd like, you can then add new members to this prototype without affecting the base HTMLScriptElement.prototype
.
scriptDataProto.foo = function() {
alert('Hello world!');
};
var scriptData = document.registerElement('script-data', {
prototype: scriptDataProto
});
var element = new scriptData();
element.foo(); // alerts "Hello world!"
document.body.appendChild(element);
element.onclick = element.foo;
For further reading, HTML5 Rocks has a well-written article that really helped me understand how custom elements work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.