document.createElement 未在 DOM 中加载

document.createElement without loading in DOM

有没有办法在没有 运行 代码的情况下创建可解析的 Dom?我会解释未来;

我收到一大堆 CK 编辑器创建的代码作为 HTML,但我想从中解析元素以创建指定的视图。例如,我喜欢将第一段理解为简介,将第一张图片理解为主要图像。我还想检索所有图像以创建图库。

为此,我创建了一个简单但有效的函数:

export const getFromContent = (html, qsa) => {
    const elm = document.createElement("DIV");
    elm.innerHTML = html;
    let r = elm.querySelectorAll(qsa);
    return r;
}

这项工作几乎完美 - 唯一的问题是将所有内容添加到 DOM(我是否正确使用该术语?),这意味着所有资源都会被加载,即使它没有显示在页.

在我的示例中,我想通过 //res.cloudinary.com/ com compress images before shown 加载所有图像,但由于所有图像都已加载,因此没有必要这样做。

有没有办法只用基本的 JS 来保持这个好的“版本”?

PS:我知道我可以用 REGEX 将所有“src”重写为“presrc”,但我真的很想在不更改代码的情况下这样做,从而创建 space错误。

此致 理查德

This work almost perfect- the only issue is that is adds everything to the DOM...

它创建 DOM 个元素(这就是你这样做的原因!),但它 不会 将它们添加到 window 的文档。该代码不会加载 src 引用的图像或 href 引用的样式表,也不会在 script 元素中加载 运行 代码。这些 img/link/script 元素将在您创建的 div 中,但 div 不在文档中。在图像和样式表的情况下,如果您将 div 放在文档中,它们就会被加载(即使那样 script 元素也不会被执行),但之前不会。

也就是说,您可能想看看使用 DOMParser

export const getFromContent = (html, qsa) => {
    const dom = DOMParser.parseFromString(html, "text/html");
    let r = dom.querySelectorAll(qsa);
    return r;
}

再次请注意,您 return 从中引用的任何图像或样式表或类似元素(与选择器匹配并 return 在 NodeList 中编辑的元素querySelectorAll) 如果将这些元素添加到 window 的 document.

中,将被加载

注意: 当接受用户输入并将其呈现为 HTML 时,在使用前 清理 通常很重要它,删除不需要的内容。例如,我提到 script 元素不会被评估,这是真的,但如果内容中有 <img src="javascript:doSomethingNefarious()">,并且您将该图像附加到文档(直接或间接),那么doSomethingNefarious() 代码将被执行。同样,<div onclick="doSomethingNefarious()">x</div>.

如果您搜索“HTML sanitizer”,您会发现很多不同的图书馆都说他们会为您做这件事。不过,这个问题已经够严重了,一种实现它的方法正在被标准化为 Sanitization API。还处于早期阶段,但这是一个非常有前途的发展。使用当前(非常草稿)形式的 API,您可以:

export const getFromContent = (html, qsa) => {
    const div = document.createElement("div");
    div.setHTML(html);  // <== `setHTML` is a new method that sanitizes.
                        // Here I'm using the default sanitizer, but you
                        // could create one with your own custom settings
                        // and pass it as the second argument
    let r = div.querySelectorAll(qsa);
    return r;
}

但 API 仍在不断变化。