HelloWorld HelloWorld - 3 years ago 72
Javascript Question

How to apply CSS styles to content rendered after AJAX call

I'm writing an app which grabs a bunch of JSON data via AJAX, then renders the view which is constructed from the same data in an es6 template literal. Really simple version to demonstrate:



let mountPoint = document.getElementById("mountPoint");
let view = document.createElement("section");
view.id = "view";
view.innerHTML = `<section>${returnedAjaxData}</section>`;
mountPoint.innerHTML = view;

#mountPoint {
background: #000000;
}

#view {
background: #444444
}

<html lang="en">
<head>
<meta charset="utf-8">
<title>My App</title>
</head>
<body>
<section id="mountPoint"></section>
</body>
</html>





Where ${returnedAjaxdata} is the data returned from the Ajax call (not shown here but working fine)

The problem is that "#mountPoint" has a black background but "#view" does not have a grey background. It seems that the CSS file is run before the "#view" renders since it waits for the Ajax data before rendering.

EDIT
I know how to change CSS on AJAX success for a specific element. My question is how do I run the entire stylesheet after the AJAX call returns AND the DOM is rendered. For context - the entire app will be inside "#mountPoint" so updating a single element wont help much

One possible solution would be to write the styles.min.css file after "#view" is rendered but that seems hacky... I'm wondering: how does React and other view rendering frameworks do this? They render HTML after the CSS files are read as well right? Is there a good pattern out there for this which I can learn?

Answer Source

Element#innerHTML parses a string, and sets it as the html content of a node. The node you've created using Document#createElement is not a string. When you try to add it to mountPoint using Element#innerHTML, it's converted to string, and the string doesn't have the id view.

You need to append the node to the view using Node#appendChild or ParentNode#append (not supported by MS browsers).

In addition css selectors (id for example) are case sensitive, and mountpoint in the css is not the same as mountPoint in the html.

let mountPoint = document.getElementById("mountPoint");
let view = document.createElement("section");
view.id = "view";
view.innerHTML = `<section>returnedAjaxData</section>`;
mountPoint.appendChild(view); // append as a child of mountPoint
#mountPoint { /** renamed to mountPoint **/
  height: 40px; /** just for the example **/
  background: #000000;
}

#view {
  background: #444444
}
<section id="mountPoint"></section>

If the id in the CSS and the HTML are exactly the same Element#innerHTML will work as well:

let mountPoint = document.getElementById("mountPoint");
mountPoint.innerHTML = '<section id="view">returnedAjaxData</section>';
#mountPoint { /** renamed to mountPoint **/
  height: 40px; /** just for the example **/
  background: #000000;
}

#view {
  background: #444444
}
<section id="mountPoint"></section>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download