Guide on showcasing html and css in a preview using a Data URL

Currently, I have implemented two tab interfaces: one for entering HTML text and another for inputting CSS content. Following this, I have included a Preview section to visualize the combined output of both HTML and CSS elements. However, I am encountering an issue where only the HTML content is being displayed in the preview, while the CSS styling remains invisible.

https://i.sstatic.net/opwMT.png

Within my JavaScript function, I have defined the following logic:

 function showPreview() {
    var htmlContent = document.getElementById("editor").innerText;
    var cssContent = "<style>" + document.getElementById("cssContent").value + "</style>";
    var frame = document.getElementById("preview-window");
  
    var dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(htmlContent + cssContent);
  
    frame.src = dataURL;
  }
  
  showPreview()

I need assistance in identifying the error within my code and finding a resolution to ensure that both the HTML and CSS content are displayed correctly in the preview.

Sample Code Section

function showPreview() {
  var htmlContent = document.getElementById("editor").innerText;
  var cssContent = "<style>" + document.getElementById("cssContent").value + "</style>";
  var frame = document.getElementById("preview-window");

  var dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(htmlContent + cssContent);

  frame.src = dataURL;
}

showPreview()
#editor,
#cssContent {
  width: 456px;
  height: 267px;
  padding: 10px;
  background-color: #d8d8d8;
  color: rgb(0, 0, 0);
  font-size: 14px;
  font-family: monospace;
  white-space: pre;
}
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="30525f5f44434442514070051e031e02">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://getbootstrap.com/docs/5.3/assets/css/docs.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="40222f2f34333432213000756e716e73">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>


<div class="container">

  <ul class="nav nav-tabs" id="myTab" role="tablist">
    <li class="nav-item" role="presentation">
      <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true">HTML</button>
    </li>
    <li class="nav-item" role="presentation">
      <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile" type="button" role="tab" aria-controls="profile" aria-selected="false">CSS</button>
    </li>
  </ul>

  <div class="tab-content" id="myTabContent">
    <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
      <div id="editor" contenteditable="true" oninput="showPreview();">&lt;div>This is a Div&lt;/div>
      </div>
    </div>


    <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
      <div id="cssContent" contenteditable="true" oninput="showPreview()">&ltstyle&gt div { background-color: blue; color: white; } &lt/style&gt

      </div>
    </div>


  <h3>PREVIEW</h3>
  <div class="preview-area">
    <iframe id="preview-window"></iframe>
  </div>

</div>

Answer №1

Updated the IDs and aria labels of the tabs to align with your project requirements.
Avoid embedding <style> tags in the editor and duplicating them in the CSS file. Utilize these tags only within the variable to prevent double inclusion of <style><style>.
Opt for Element.textContent over .innerText or .value when working with DIV elements that have the contenteditable attribute. Although not extensively tested, this code should provide a solid starting point for further development:

const elHTML = document.querySelector("#html");
const elCSS = document.querySelector("#css");
const elJS = document.querySelector("#js");
const elPreview = document.querySelector("#preview");

function showPreview() {
  const html = elHTML.textContent;
  const css = `<style>${elCSS.textContent}</style>`;
  const js = `<scr` + `ipt>${elJS.textContent}</scr` + `ipt>`;
  const dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(css + html + js);

  elPreview.src = dataURL;
}

showPreview()
.container-fluid {
  display: flex;
}

#editor {
  flex: 1;
}

#html,
#css,
#js {
  padding: 1rem;
  height: 160px;
  background-color: #d8d8d8;
  color: rgb(0, 0, 0);
  font-size: 14px;
  font-family: monospace;
  white-space: pre;
}

#preview {
  display: block;
  width: 100%;
}
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="17757878636463657667572239243925">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://getbootstrap.com/docs/5.3/assets/css/docs.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a1c3ceced5d2d5d3c0d1e1948f908f92">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>


<div class="container-fluid">

  <div class="area" id="editor">
    <ul class="nav nav-tabs" id="myTab" role="tablist">
      <li class="nav-item" role="presentation">
        <button class="nav-link active" id="html-tab" data-bs-toggle="tab" data-bs-target="#html" type="button" role="tab" aria-controls="html" aria-selected="true">HTML</button>
      </li>
      <li class="nav-item" role="presentation">
        <button class="nav-link" id="css-tab" data-bs-toggle="tab" data-bs-target="#css" type="button" role="tab" aria-controls="css" aria-selected="false">CSS</button>
      </li>
      <li class="nav-item" role="presentation">
        <button class="nav-link" id="js-tab" data-bs-toggle="tab" data-bs-target="#js" type="button" role="tab" aria-controls="js" aria-selected="false">JAVASCRIPT</button>
      </li>
    </ul>

    <div class="tab-content" id="myTabContent">

      <div id="html" class="tab-pane fade show active" role="tabpanel" aria-labelledby="html-tab" contenteditable="true" oninput="showPreview();">&lt;div>This is a DIV&lt;/div>
      </div>

      <div id="css" class="tab-pane fade" role="tabpanel" aria-labelledby="css-tab" contenteditable="true" oninput="showPreview()">* { margin: 0; box-sizing: border-box; }
div {
  background-color: blue;
  color: white;
}</div>

      <div id="js" class="tab-pane fade" role="tabpanel" aria-labelledby="js-tab" contenteditable="true" oninput="showPreview();">addEventListener("click", () => {
    alert("hello!");
});</div>
    </div>
  </div>
  
  <div class="area">
    <h3>PREVIEW</h3>
    <div class="preview-area">
      <iframe id="preview"></iframe>
    </div>
  </div>
</div>

If you're interested, you may refer to: Creating a basic code editor

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the most efficient approach to save a value for future utilization in a subsequent function? I've heard that exploiting global variables is highly unfavorable

So I have this code that can be found at http://jsfiddle.net/8j947/10/. It returns either true or false for the variable isLive. My main concern now is how to utilize the variable onLive in a subsequent function. While I've encountered some solutions ...

Have you considered showcasing all images in a carousel format?

I have a total of 6 picture blocks, but only the first 3 images are displayed in the carousel. I suspect there may be an issue with jQuery, but I'm unsure where to look. Any hints or guidance would be greatly appreciated. Thank you! Below are the blo ...

How can I securely store passwords for web scraping with Puppeteer to ensure maximum safety?

Looking for advice on scraping a website that requires login. The current code saves username and password in a config JSON file, which poses a security risk if the file is accessed by unauthorized individuals. Is there a more secure method, such as encr ...

Am I utilizing React hooks correctly in this scenario?

I'm currently exploring the example, but I have doubts about whether I can implement it in this manner. import _ from "lodash"; ... let [widget, setWidgetList] = useState([]); onRemoveItem(i) { console.log("removing", i); ...

Unable to showcase information in the center of an HTML document

Hello, I'm facing an issue with my HTML page that has a left vertical nav-bar. Despite my efforts, I can't seem to display content (text) in the center of the page as shown in the screenshot with the red oval. I've attempted inserting text ...

An improved method for fetching data from the server at regular intervals of x minutes

Is setInterval the best way to periodically check for updates in a database and update the UI accordingly, or are there better approaches that I should consider? I've read conflicting opinions on using setInterval for this purpose, with some sources ...

Using jQuery to encapsulate HTML within a div tag

I am looking to insert some HTML markup into my webpage using jQuery. I want to wrap the highlighted yellow code below with <div class="section">...</div>. Here is an example of what I need: <div class="section"> <div>...< ...

Vuex bombards with errors without any clear explanation during commit

Within my Plugin, I am faced with the following code snippet: import firebase from 'firebase' export default context => { firebase.auth().onAuthStateChanged(userObject => { // eslint-disable-next-line no-console console.log({ us ...

How can we determine the remaining balance in the user's wallet after making purchases using JavaScript?

There are three arrays containing data from the back-end, with unknown names or products. The task is to calculate the total amount spent by the user and how much money is left in their wallet. In case the user runs out of money, they can take a loan which ...

Marionette - Apply a class to the parent ItemView's tagname

I've been working with Bootstrap accordion panels and I'm trying to assign a class to the parent panel of the panel-collapse. Essentially, what I want to achieve is: if (child element) hasClass('panel-collapse.in') { this.addClass ...

Creating a responsive canvas and image container in fabric.js involves adjusting the layout and size of the

I am working with fabric.js and canvas to dynamically add an image from a URL. I would like to make the canvas responsive based on the resolution. How can this be achieved? Here is my current code: <canvas id="panel" width="700" height="350"></ ...

How to replace the parent configuration for Eslint within a git submodule

My goal is to use eslint within my project, but the configuration is inheriting from the parent project. How can I prevent this and set up a separate pipeline for my core project, avoiding interference from other contributors? > <a href="/cdn-cgi/l ...

Changing the color of the cursor in input fields in Ionic3

Is there a way to customize the color of the cursor in text input fields within my Ionic 3 app on Android? I am referring to the marker that indicates the current position within the text. In the screenshot below, you can see that the cursor is currently g ...

Exploring Source Map Explorer in Next.js: A Beginner's Guide

Looking for assistance in analyzing the Next.js build using source-map-explorer. Can anyone provide guidance on the script? For React (CRA), the script I use is: "build:analyze": "npm run build && source-map-explorer 'build/sta ...

Click the button on the form without actually submitting it

I have created a form that includes the use of two tags. The issue I am facing is that every time the user clicks on them, the form gets submitted. I tried using onclick="return false" to prevent this behavior, but the values are not being sent in the UR ...

What is the process for displaying all the commands that are at your disposal in package.json?

There are several commands that can be included in a package.json, such as npm start and npm test. However, there are typically many more commands available. Is there a method to display a complete list of all available commands? My current approach is u ...

Collecting data from Jitsi

After setting up a Jitsi server using packages, I am now trying to log connection statistics to a database. Specifically, I want to store data about significant bitrate changes during video calls. Although I have some familiarity with JavaScript and WebRT ...

Click on a button to display the corresponding DIV while hiding the rest, all achieved with the power of Vue

I'm seeking guidance as a newcomer to Vue, so please bear with me if my question appears simplistic. My scenario involves a set of buttons and corresponding div elements. The goal is to show a specific div when its associated button is clicked, while ...

Handling callback functions in JavaScript when using the $http.get method

My task involves retrieving multiple http.get requests from a server with different json sets. After processing each "physical" data set, I need to perform a calculation that requires the value from the corresponding "virtual" call. This calculation is ha ...

Elevate your frontend development game with the powerful combination of Vue js 3

I've been attempting to add this dependency, but I keep receiving an error message stating that it doesn't exist and Vue 3 is unable to resolve the component. Click here to visit the npm page for vue-phone-number-input Any assistance you can pr ...