ChatGPT解决这个技术问题 Extra ChatGPT

Converting HTML string into DOM elements?

Is there a way to convert HTML like:

<div>
<a href="#"></a>
<span></span>
</div>

or any other HTML string into DOM element? (So that I could use appendChild()). I know that I can do .innerHTML and .innerText, but that is not what I want -- I literally want to be capable of converting a dynamic HTML string into a DOM element so that I could pass it in a .appendChild().

Update: There seems to be confusion. I have the HTML contents in a string, as a value of a variable in JavaScript. There is no HTML content in the document.

If you want something closer HTML instead of node, I suggeste to use the following function ;) ` var stringToHTML = function (str) { var dom = document.createElement('div'); dom.innerHTML = str; return dom; }; `

m
maerics

You can use a DOMParser, like so:

var xmlString = "

"; var doc = new DOMParser().parseFromString(xmlString, "text/xml"); console.log(doc.firstChild.innerHTML); // => Link... console.log(doc.firstChild.firstChild.innerHTML); // => Link


Thanks, it works great. After reading Mozilla article I realized that the browsers can also parse XML AJAX responses -- so browsers like IE that do not support DOMParser, I use synchronous AJAX calls with data URIs to parse the XML. :)
@maerics Why can't you just say text/html for HTML parsing?
@Djack You can, but then you get 'html' and 'body' tags automatically generated.
Note: I found it vital to use "text/html" instead of "text/xml", if placing the created nodes back to browser's DOM (Safari 9.1.2). Otherwise, the CSS rendering didn't work correctly. If you use this, use '.body' to bypass the auto-inserted body element.
b
bobince

You typically create a temporary parent element to which you can write the innerHTML, then extract the contents:

var wrapper= document.createElement('div');
wrapper.innerHTML= '<div><a href="#"></a><span></span></div>';
var div= wrapper.firstChild;

If the element whose outer-HTML you've got is a simple <div> as here, this is easy. If it might be something else that can't go just anywhere, you might have more problems. For example if it were a <li>, you'd have to have the parent wrapper be a <ul>.

But IE can't write innerHTML on elements like <tr> so if you had a <td> you'd have to wrap the whole HTML string in <table><tbody><tr>...</tr></tbody></table>, write that to innerHTML and extricate the actual <td> you wanted from a couple of levels down.


+1 this solution is likely more portable.
Keep in mind that this method will lose any event handlers or other properties that were assigned to it beforehand.
@bryc how does a string would have event handlers attached to it/
@Muhammad - perhaps by using something like onclick="..." although that won't work for event handlers not defined in the HTML of course, which is perhaps what you meant.
what if the string is like this some string at the start <div><a href="#">anchor text</a><span>inner text</span></div>string end?
R
Ram Y

Why not use insertAdjacentHTML

for example:

// <div id="one">one</div> 
var d1 = document.getElementById('one'); 
d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');

// At this point, the new structure is:
// <div id="one">one</div><div id="two">two</div>here

In the link there is an example - but I copy pasted in here as well
You are aware that you would have this element to be in the DOM for this to work right? and you don't really want this element anyway in the DOM, you only want to convert a string into HTML in memory
C
Community

Check out John Resig's pure JavaScript HTML parser.

EDIT: if you want the browser to parse the HTML for you, innerHTML is exactly what you want. From this SO question:

var tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlString;

While writing an example I noticed that simple HTML tags render properly (on IE7) but when I try to do it with a script, which is the case i'm working on, the script doesn't work. Example: Fiddle. You might have to run the code on a local html page (jsfiddle doesn't work very well with IE7).
This code has a minor issue: it doesn't work properly if htmlString likes to <tr>...</tr> :(
T
Tower

Okay, I realized the answer myself, after I had to think about other people's answers. :P

var htmlContent = ... // a response via AJAX containing HTML
var e = document.createElement('div');
e.setAttribute('style', 'display: none;');
e.innerHTML = htmlContent;
document.body.appendChild(e);
var htmlConvertedIntoDom = e.lastChild.childNodes; // the HTML converted into a DOM element :), now let's remove the
document.body.removeChild(e);

You don't need to add "e" to the document. You also don't need to do setAttribute on it.
F
Filling The Stack is What I DO

Here is a little code that is useful.

var uiHelper = function () {

var htmls = {};

var getHTML = function (url) {
                /// <summary>Returns HTML in a string format</summary>
                /// <param name="url" type="string">The url to the file with the HTML</param>

    if (!htmls[url])
    {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", url, false);
    xmlhttp.send();
    htmls[url] = xmlhttp.responseText;
     };
     return htmls[url];
    };

        return {
            getHTML: getHTML
        };
}();

--Convert the HTML string into a DOM Element

String.prototype.toDomElement = function () {

        var wrapper = document.createElement('div');
        wrapper.innerHTML = this;
        var df= document.createDocumentFragment();
        return df.addChilds(wrapper.children);
};

--prototype helper

HTMLElement.prototype.addChilds = function (newChilds) {
        /// <summary>Add an array of child elements</summary>
        /// <param name="newChilds" type="Array">Array of HTMLElements to add to this HTMLElement</param>
        /// <returns type="this" />
        for (var i = 0; i < newChilds.length; i += 1) { this.appendChild(newChilds[i]); };
        return this;
};

--Usage

 thatHTML = uiHelper.getHTML('/Scripts/elevation/ui/add/html/add.txt').toDomElement();

Uhhh... This is basically just @orip's answer but with a lot of utterly unnecessary cruft added, in addition to extending the native String and HTMLElement prototypes (something you generally really shouldn't do). This is irrelevant bordering on dangerous...
@aendrew this is to different examples. The prototype helper happens to be one of the best helpers I've got in my entire solution(s) I pass in an array of DOM elements [ele,ele,ele,ele,ele], so I beg to differ. And also, the first convert to DOM Element is awesome as well. Learn more about the DocumentFragment, "Which no one ever uses" and you see what's going on. THESE ARE HELPERS, in a util file. This is what is wrong with developers' in todays' world, if it is not a 3rd party they're clueless. I write all my JS from scratch.
And to expand on my last comment, performance is to be taken seriously in most of my JS apps.
I'm simply saying don't pollute the prototype of builtins. That's considered best practice these days and has absolutely nothing to do with writing JS from scratch, using libraries, or performance — it's about preventing bugs further down the road.
@FillingTheStackisWhatIDO, what is the difference between returning wrapper.firstChild from toDomElement and returning df.addChilds(wrapper.children), apart from the fact that the later return an array of Nodes.
S
Sarfraz

Just give an id to the element and process it normally eg:

<div id="dv">
<a href="#"></a>
<span></span>
</div>

Now you can do like:

var div = document.getElementById('dv');
div.appendChild(......);

Or with jQuery:

$('#dv').get(0).appendChild(........);

This is a jQuery example you gave. I think @rFactor was looking for a more straight up Javascript example.
@clarke78: Before down voting, you should have seen that i have already given an example of plain javascript.
The example does not work, because it applies to already existing DOM elements. Of course the situation is simple if the element is already a DOM element, but in my situation the HTML contents is the value of a variable, not part of the DOM.
@rFactor - are you willing/able to use jQuery? Parsing a string of HTML into DOM elements is very simple if you can use it
I am not using jQuery, but anything jQuery can do can be done with plain JavaScript, so, if you have any examples, let me know. Hmm, actually I think I found the answer my self. :P
w
william malo

You can do it like this:

String.prototype.toDOM=function(){
  var d=document
     ,i
     ,a=d.createElement("div")
     ,b=d.createDocumentFragment();
  a.innerHTML=this;
  while(i=a.firstChild)b.appendChild(i);
  return b;
};

var foo="<img src='//placekitten.com/100/100'>foo<i>bar</i>".toDOM();
document.body.appendChild(foo);