javascript - 扩展 <script> 元素的自定义 HTML 元素?

标签 javascript element extends

习惯<script type="text/template"> tag for client-side processing对我的目的来说还不够,因为 it isn't nestable .所以我试图扩展它来解决这个限制。

基本上我有一些带有嵌入图像的原始html,我想使用javascript解析内容客户端。我喜欢脚本标签,因为浏览器不会加载其中的图像。但是当 html 包含脚本标签时,它们会破坏我的应用程序。这是我尝试扩展标签的方式:

    <script>
        var scriptData = document.registerElement('script-data', {
            prototype: HTMLScriptElement.prototype
        });
        captureStart();
    </script>

执行时,chrome 会抛出以下错误:
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. 

更新:

质疑我的意图或建议替代方法很好,但是我仍然想回答我最初的问题:如何扩展脚本标签?

我如何使用它实际上更复杂。我基本上是用它来“捕获”我的 HTML 文档的整个主体,这样我就可以在它们显示之前对其进行操作。这是非常规的,我知道。但我正在探索它作为一种学术研究。

这种方法的好处包括:
  • html 验证
  • 该代码是轻量级的,我希望比 mobify.js
  • 等解决方案得到更好的支持
  • 我可以在浏览器加载图片资源之前修改内容

  • 这种方法的挑战包括:
  • 文档的正文可以包含带有脚本标签或 html 注释的 3rd 方模块/小部件。
  • 我无法转义内联脚本标签。它们需要保持原样,因为禁用 javascript 的浏览器将正常显示文档。

  • 我对这些问题提出的解决方案:
  • 扩展脚本标签的原型(prototype)将允许我使用我知道不会出现在其他组件中的自定义标签。

  • 这是一个更大的代码示例:
    <!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>-->
    

    最佳答案

    简短回答:使用Object.create()对于原型(prototype)对象。以下代码允许您扩展 script元素,表示方式document.registerElement()是用来使用的。

    var scriptData = document.registerElement('script-data', {
        prototype: Object.create(HTMLScriptElement.prototype);
    });
    

    长答案

    考虑原始代码的这种变化:

    var scriptDataProto = HTMLScriptElement.prototype;
    // The next statement throws a DOMException of type "NotSupportedError".
    var scriptData = document.registerElement('script-data', {
        prototype: scriptDataProto
    });
    

    此处说明了异常的来源:

    scriptDataProto === HTMLScriptElement.prototype; // true
    

    您提供了对 HTMLScriptElement.prototype 的引用,这意味着您希望对正在创建的自定义脚本元素使用完全相同的原型(prototype)。它的文档还不是很好,但是您提供的原型(prototype)不能作为对任何内置 HTML[*]Element 的引用。原型(prototype);你必须提供一个新的原型(prototype)对象。

    如果你想继承 <script>标签的原型(prototype),那么你必须创建一个新的原型(prototype)对象继承自 HTMLScriptElement.prototype通过使用 Object.create() .

    var scriptDataProto = Object.create(HTMLScriptElement.prototype);
    scriptDataProto === HTMLScriptElement.prototype; // false
    

    如果您愿意,您可以在不影响基础 HTMLScriptElement.prototype 的情况下向此原型(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;
    

    如需进一步阅读,HTML5 Rocks has a well-written article这真的帮助我理解了自定义元素是如何工作的。

    关于javascript - 扩展 &lt;script&gt; 元素的自定义 HTML 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25007568/

    相关文章:

    带有类型参数的 Java 类

    javascript - 如何在 React Native 中按百分比定义宽度?

    javascript - 多个弹出模态框

    javascript - Bootstrap 4 记住选项卡

    java List 扩展了抽象

    java - 我如何知道对象中存在哪些变量?

    javascript - 如何从angularjs访问变量express

    c - 初始化元素在加载时不可计算

    javascript - 如何将项目插入数组而不删除最后一个元素

    Javascript获取json对象的最后一个值