Issue
I have two tab controls: one to insert HTML text and the other to insert CSS text. Then I have a Preview to view the output (HTML + CSS). The problem is that in the preview I only display the HTML of the content, but I don't also display the CSS of the content.
I am using this function in JavaScript:
function showPreview() {
var htmlContent = document.getElementById("editor").innerText;
var cssContent = "<style>" + document.getElementById("cssContent").value + "</style>";
var frame = document.getElementById("preview-window");
// var jsContent = "<scri" + "pt>" + document.getElementById("jsCode").value + "</scri" + "pt>";
// Create a data URL with the HTML content
var dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(htmlContent + cssContent);
// Set the iframe src attribute to the data URL
frame.src = dataURL;
}
showPreview()
What am I doing wrong? How to solve?
Code Snippet
function showPreview() {
var htmlContent = document.getElementById("editor").innerText;
var cssContent = "<style>" + document.getElementById("cssContent").value + "</style>";
// var jsContent = "<scri" + "pt>" + document.getElementById("jsCode").value + "</scri" + "pt>";
var frame = document.getElementById("preview-window");
// Create a data URL with the HTML content
var dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(htmlContent + cssContent);
// Set the iframe src attribute to the data URL
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/bootstrap@5.3.2/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/bootstrap@5.1.3/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();"><div>This is a Div</div>
</div>
</div>
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
<div id="cssContent" contenteditable="true" oninput="showPreview()"><style> div { background-color: blue; color: white; } </style>
</div>
</div>
<h3>PREVIEW</h3>
<div class="preview-area">
<iframe id="preview-window"></iframe>
</div>
</div>
Solution
Modified the tabs IDs and aria labels to match what you're building.
Don't hardcode <style>
in the editor and again when porting it to css
. Use those tags only in the variable. Otherwise you'll end up having <style><style>
twice.
Make proper use of Element.textContent
instead of .innerText
or .value
(since you're using contenteditable attribute on DIV Elements).
Not thoroughly tested but should give you a firm point to move forward:
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/bootstrap@5.3.2/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/bootstrap@5.1.3/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();"><div>This is a DIV</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>
Also you might find interesting: Make a simple code editor
Answered By - Roko C. Buljan
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.