Javascript:替换元素与更改元素属性(Javascript: Replace Element vs Change Element Property)

在阅读Image Lazy Loading脚本时,我注意到有这样的操作(我添加了评论):

function loadImage (el) { var img = new Image() , src = el.getAttribute('data-src'); img.onload = function() { if (!! el.parent) el.parent.replaceChild(img, el) // Replace Element else el.src = src; // Change Element Property } img.src = src; }

为什么不简单地改变元素属性? 它简单得多。 为什么要创建一个新元素并替换旧元素(两个元素都是图像,无论如何)? 有什么好处?

function loadImage (el) { src = el.getAttribute('data-src'); el.src = src; // Change Element Property }

While reading an Image Lazy Loading script, I noticed that there are such operations(comments added by me):

function loadImage (el) { var img = new Image() , src = el.getAttribute('data-src'); img.onload = function() { if (!! el.parent) el.parent.replaceChild(img, el) // Replace Element else el.src = src; // Change Element Property } img.src = src; }

Why does not it simply Change Element Property? It is much simpler. Why create a new element and replace the old element (both elements are images,anyway)? What are the advantages?

function loadImage (el) { src = el.getAttribute('data-src'); el.src = src; // Change Element Property }

最满意答案

它可能以这种方式提供屏幕外加载和浏览器效率目的(尽管具体实现在这方面存在缺陷)。

似乎延迟加载希望图像的实际加载“发生在视线外”。 因此,出于这个原因,创建了一个新的Image对象,并在.src上设置了.src 。

然后,一旦加载了新图像,浏览器实际使用该新图像对象就更有效,而不是更改DOM中图像上的.src 。 因此,如果图像看起来至少是一个DOM片段(例如,如果它有一个父片段),那么新图像将被交换到它的位置,浏览器必须做的唯一事情是DOM操作然后重新绘制。

如果图像没有父图像,则无法更换原始图像,因此只需在.src上设置.src 。 设置.src属性将导致浏览器再次请求图像URL。 它会在本地缓存中找到该URL,但它仍然必须从缓存中获取图像并解析图像格式(这比仅交换DOM元素更有用)。


似乎代码中对el.parent的引用应该是el.parentNode 。 如果我进入延迟加载演示页面并在自己的代码中设置断点,它永远不会使用if语句的.replaceChild()选项,因为el.parent不是标准的DOM属性,因此在我试过的浏览器中总是undefined - Chrome,Firefox,IE11和Edge。

It is probably done this way to provide off-screen loading and for browser efficiency purposes (though the specific implementation is flawed in this regard).

It seems likely that the lazy loading wants the actual loading of the image to happen "out of view". So, for that reason, a new Image object is created and the .src is set on that.

Then, once that new image has been loaded, it is more efficient for the browser to actually use that new image object rather than change the .src on the image that is in the DOM. So, if the image appears to be in at least a DOM fragment (e.g. if it has a parent), then the new image is swapped into its place and the only thing the browser has to do is a DOM operation and then a repaint.

If the image has no parent, then there is no way to swap out the original, so it just sets the .src on it. Setting the .src property will cause the browser to request the image URL again. It will find that URL in a local cache, but it will still have to get the image from the cache and parse the image format (which is more work than just swapping the DOM element).


It also appears that the reference to el.parent in the code should be el.parentNode. If I go to the lazyloading demo page and set a breakpoint in their own code, it never does the .replaceChild() option of the if statement because el.parent is not a standard DOM property and is thus always undefined in the browsers I tried - Chrome, Firefox, IE11 and Edge.

更多推荐