【问题标题】:Is there a difference between `new Image()` and `document.createElement('img')`?`new Image()` 和 `document.createElement('img')` 之间有区别吗?
【发布时间】:2011-06-05 08:15:40
【问题描述】:

在javascript中,我可以做到:

img1 = new Image();
img2 = document.createElement('img');

我的问题是,这两种方法有区别吗?我在某处读到ImageFormElement 被称为主机对象,这是真的吗?如果是,什么是宿主对象?

哪种方法更可取?

【问题讨论】:

标签: javascript dom


【解决方案1】:

我找不到任何详细的参考资料,但根据 MDC - HTMLImageElement 示例中的评论,Image 似乎是 DOM 级别 0 的一部分,而 document.createElement is part of DOM level 2

DOM 级别 0 是由 Netscape 发明的,它提供了一种访问网站某些元素的方法。基本上所有浏览器都支持它以实现向后兼容性。
但老实说,我不明白 为什么 Image 构造函数存在那里,因为据我了解,没有办法操纵文档使用 DOM 级别 0。也许它只在浏览器内部用于创建对象。

DOM level 2 是 W3C 制定的官方标准。

有关 DOM 级别的更多信息,请查看 quirksmode.org - Level 0 DOMWikipedia


我在某处读到ImageFormElement 被称为主机对象,这是真的吗?

是的。

如果是,什么是宿主对象?

ECMAScript specification 以这种方式激励宿主对象:

ECMAScript 是一种面向对象的编程语言,用于在主机环境中执行计算和操作计算对象。此处定义的 ECMAScript 并非旨在实现计算自给自足;实际上,本规范中没有关于外部数据输入或计算结果输出的规定。相反,预计 ECMAScript 程序的计算环境将不仅提供本规范中描述的对象和其他设施,而且还提供某些特定于环境的宿主对象,其描述和行为超出了本规范的范围,除非指出:它们可以提供可以访问的某些属性和可以从 ECMAScript 程序调用的某些函数。

宿主对象
宿主环境提供的对象,用于完成 ECMAScript 的执行环境。
注意任何非本地对象都是宿主对象。

因此,规范中未定义并由环境提供的任何对象都是宿主对象。例如,在浏览器中(以及其他):windowdocumentconsole

【讨论】:

  • 不错的答案!我想问,为什么document 被认为是主机对象?它不是在 DOM 1 级规范中定义的吗? w3.org/TR/REC-DOM-Level-1/level-one-core.html#i-Document
  • @rickchristie:不要将 DOM 规范与 ECMAScript 规范混淆。 document 由浏览器提供,作为 JavaScript 访问 DOM 的接口。它不是 ECMAScript 规范(JavaScript 本身的)的一部分。
  • DOM0 是一个非正式名称,用于在浏览器中操作文档的前 DOM 级别 1 方法。使用Image 构造函数主要用于将页面内动态使用的图像“预加载”到浏览器缓存中,通常用于图像切换效果,例如翻转。它起源于 Netscape 3,它为动态文档操作(图像切换、表单元素操作和表单提交,以及更新状态栏文本,据我所知)提供了非常有限的机制。
  • 那么,在显示图像之前加载、缓存、操作图像哪个“更好”?
  • 这是一个很好的答案,下面的其他一些答案也是如此,但它们似乎都不完整。总而言之,我认为真正的差异可能通过创建每个对象来揭示,1)对所有属性和方法进行递归转储以比较它们,2)观察网络日志以验证缓存行为是否相同,以及 3)测试事件传播,因为一个答案表明可能没有任何(或不正确的)事件传播到 Image。这可能是图像等非标准化功能的结果。 4)一个答案提出了一个可能需要图像但可能是代码味道的情况。
【解决方案2】:

要求:

在我的团队中,我们正在构建 Angular 5 应用程序。 功能要求是在组件加载时预加载图像,以便在我们的单页应用程序的特定位置需要时重用它们而无需再次加载。

1。 img = 新图像();方式:

我们尝试通过 create new Image() 在 DOM 中预加载图像 但是当我们重用图像 src URL 时,浏览器总是重新加载源文件或检查标头是否被修改(如果启用缓存),这意味着预加载成功,但对于每个重用,再次进行到服务器的往返。

2。 img = document.createElement('img') 方式:

当我们对 document.createElement('img') 做同样的事情时 图片源没有重新加载,而是从文档的本地内存中重复使用,并且没有提出额外的请求 img src URL。

我不太明白为什么,但这是我们发现的一个主要区别。如果其他人需要重用预加载的图像,后者将是节省一些带宽和少量请求往返的方法:)

【讨论】:

  • 是的,当将它们与 Web 组件一起使用时,我肯定会看到两者之间存在一些很大的差异。 Relevant question.
【解决方案3】:

这两行是等效的,都创建 HTMLImageElement 对象。 唯一的区别在于具有混合命名空间的 XML 文档 - new Image() 总是返回带有 XHTML 命名空间的 <img> 元素,document.createElement('img') 并不总是这样做。

【讨论】:

【解决方案4】:

我个人会坚持使用 createElement,因为它不是制作图像的特殊情况,一切都以相同的方式制作,因为它们是相同的我还注意到 jquery 对所有内容都使用 appendChild(node) 方法,我不确定这与您问题中的两种方法之间的区别,但 jquery 确实可以跨浏览器工作

【讨论】:

    【解决方案5】:

    我不知道技术差异应该是什么,但我只是通过在以下代码中将new Image() 更改为document.createElement('img') 来修复IE8 错误。在 IE8 中,使用 Image 构造函数时不会触发 onload 回调。

    newImage = document.createElement('img');
    //newImage = new Image();
    
    newImage.onload = function () {
      callback(this.width, this.height);
    };
    
    newImage.src = image.src;
    

    【讨论】:

      【解决方案6】:

      当您使用 Web 组件时,这两种创建图像的方法之间存在一些显着差异。例如,如果您在导入的 HTML 文档中使用document.createElement 方法(使用<link rel="import" href="...">),则在将图像附加到主文档的 DOM 之前不会实际加载图像。详情请见this SO question/answer

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-12
        • 2017-10-17
        • 2011-05-27
        • 2012-02-16
        • 1970-01-01
        • 2018-02-25
        • 1970-01-01
        • 2016-09-10
        相关资源
        最近更新 更多