简体   繁体   English

没有在 DOM 中加载的 document.createElement

[英]document.createElement without loading in DOM

Is there a way to create a parsable Dom without running the code?有没有办法在不运行代码的情况下创建可解析的 Dom? I'll explain future;我会解释未来;

I receive a whole bunch of CK-editor created code as a HTML, but want to parse elements from this to create a specified view.我收到了一大堆 CK 编辑器创建的 HTML 代码,但想从中解析元素以创建指定的视图。 For example I'll like to grasp the first paragraph as an Intro and the first Image as a primary image.例如,我想将第一段作为介绍,将第一幅图像作为主要图像。 I'n addition I want to retrieve all images to create a gallery.我另外我想检索所有图像来创建一个画廊。

For doing this I've created a simple, but effective function:为此,我创建了一个简单但有效的函数:

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

This work almost perfect- the only issue is that is adds everything to the DOM (do I use the term correctly?), which means that all resources gets loaded even if it does not show on the Page.这项工作几乎完美 - 唯一的问题是将所有内容添加到 DOM(我正确使用该术语吗?),这意味着所有资源都会被加载,即使它没有显示在页面上。

In my example I would like to load all images through //res.cloudinary.com/ com compress images before shown, but since all images already is loaded, this wont be necessary.在我的示例中,我想在显示之前通过 //res.cloudinary.com/ com 压缩图像加载所有图像,但由于所有图像都已加载,因此没有必要这样做。

Is there a way to get to keep the good "version" of this with just basic JS?有没有办法只用基本的JS来保持这个好的“版本”?

PS: I know that I could rewrite all "src" to "presrc" with a REGEX, but I would really like to do this without changing the code, and thereby create space for errors. PS:我知道我可以使用 REGEX 将所有“src”重写为“presrc”,但我真的很想在不更改代码的情况下这样做,从而为错误创造空间。

Best regards Richard最好的问候理查德

This work almost perfect- the only issue is that is adds everything to the DOM...这项工作几乎完美 - 唯一的问题是将所有内容添加到 DOM ...

It creates DOM elements (that's why you're doing it!😀), but it doesn't add them to the window's document.它创建 DOM 元素(这就是你这样做的原因!😀),但它不会将它们添加到窗口的文档中。 That code will not load images referenced by src or stylesheets referenced by href , and will not run code in script elements.该代码不会加载src引用的图像或href引用的样式表,也不会在script元素中运行代码。 Those img / link / script elements will be in the div you've created, but that div is not in the document.那些img / link / script元素将在您创建的div ,但该div不在文档中。 In the case of the images and stylesheets, they'd be loaded if you put the div in the document (the script elements would not be executed even then), but not before.在图像和样式表的情况下,如果您将div放在文档中(即使在那时script元素也不会执行),它们将被加载,但之前不会。

That said, you might want to look at using DOMParser instead.也就是说,您可能想考虑使用DOMParser

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

Note that, again, any images or stylesheets or similar referenced by the elements you return from that (the ones matched by the selector and returned in the NodeList from querySelectorAll ) will be loaded if those elements are added to a window's document .请再次注意,如果这些元素被添加到窗口的document ,那么您从中返回的元素(与选择器匹配并从querySelectorAll返回到NodeList的元素)引用的任何图像或样式表或类似内容都将被加载。


Note: When accepting user input and rendering it as HTML, it's often important to sanitize that input before using it, to remove unwanted content.注意:当接受用户输入并将其呈现为 HTML 时,在使用之前清理该输入通常很重要,以删除不需要的内容。 For instance, I mentioned that script elements wouldn't be evaluated, and that's true, but if the content had <img src="javascript:doSomethingNefarious()"> in it, and you appended that image to a document (directly or indirectly), that doSomethingNefarious() code would be executed.例如,我提到不会评估script元素,这是真的,但是如果内容中有<img src="javascript:doSomethingNefarious()">并且您将该图像附加到文档中(直接或间接),那么doSomethingNefarious()代码将被执行。 Similarly, <div onclick="doSomethingNefarious()">x</div> .同样, <div onclick="doSomethingNefarious()">x</div>

If you search for "HTML sanitizer" you'll find a lot of different libraries out there that say they'll do it for you.如果您搜索“HTML sanitizer”,您会发现很多不同的库都说它们会为您完成。 The problem is significant enough, though, that a means of doing it is in the process of being standardized as the Sanitization API .然而,这个问题已经足够严重了,一种方法正在被标准化为Sanitization API Early days yet, but it's a very promising development.尚处于早期阶段,但这是一个非常有前途的发展。 With the API in its current (very draft) form, you could do:使用当前(非常草稿)形式的 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;
}

But the API is still in flux.但 API 仍在不断变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM