簡單實現HTML在線編輯器

????????我們繼續來看一下如何開發一個簡單的html在線編輯器,要求很簡單 能夠同時編輯html,css,js代碼,并且運行之后可以同時預覽效果


一:前置知識

????????在H5中設置了一個新的標簽,<iframe>, 用于在當前 HTML 文檔中嵌入另一個獨立的 HTML 文檔。這是實現在線編輯器預覽功能的關鍵,因為它提供了一個沙箱環境,內部的 HTML、CSS、JS 不會直接影響到父頁面。所以我們來簡單學習一下該標簽元素的使用。

(1)核心屬性和方法 (用于向 iframe 寫入內容):

? iframe?比較特殊,因為它內部有自己獨立的?window?對象和?document?對象。你需要先訪問到它們:

  • previewFrame.contentWindow: 返回?iframe?的?window?對象。
  • previewFrame.contentDocument: 返回?iframe?的?document?對象。
    • 注意:在某些舊瀏覽器或特定情況下,contentDocument?可能不可用,更通用的方式是?previewFrame.contentWindow.document

假設我們先獲取了一個iframe元素

const previewFriame =document.getElementByID("preview-frame")
方法一 :使用document.write()

這是講HTML字符串斜土iframe內部文檔的傳統寫法

    const htmlCode = "<h1>Hello from iframe</h1><p>This is a test.</p>";const iframeDoc = previewFrame.contentWindow.document;iframeDoc.open();     // 1. 打開文檔流,準備寫入iframeDoc.write(htmlCode); // 2. 將 HTML 字符串寫入iframeDoc.close();    // 3. 關閉文檔流,瀏覽器會解析并顯示內容

通過沙箱的contentWindow獲取沙箱的內部環境再通過document寫入內容

?·?open(): 清除 `iframe` 中當前的所有內容,并打開一個新的文檔流準備接收數據。

?· write(): 將字符串寫入到打開的文檔流中。你可以多次調用 `write()` 來追加內容。

?· close(): 關閉文檔流。這個步驟很重要,它告訴瀏覽器所有內容都已寫入完畢,可以開始解析和渲染了。如果不調用 `close()`,`iframe` 可能會一直處于加載狀態。

方法二:使用`srcdoc` 屬性 (更現代,推薦)

`srcdoc` 屬性允許你直接將完整的 HTML 內容作為字符串賦值給它。瀏覽器會將其作為 `iframe` 的源文檔內容進行渲染。

  const htmlCode = "<h1>Hello via srcdoc</h1><p>Modern way!</p>";previewFrame.srcdoc = htmlCode;

使用這種方法也有一些優點:

?1.更安全:比 `document.write` 在某些情況下更安全,可以減少 XSS 風險(雖然在這個項目中你主要寫入自己控制的代碼,風險較低)。

2.更簡潔:一行代碼搞定。

3.行為更像加載一個真正的文檔

方法三:?操作 `iframe` 內部 DOM (如果只需要修改部分內容,而不是整個文檔)

如果你不是要替換整個?`iframe` 的內容,而是想修改它內部已有的某個元素,可以這樣做:

// 假設 iframe 內部已經有一個 id 為 "title" 的 h1 元素const iframeDocument = previewFrame.contentWindow.document;const titleElementInIframe = iframeDocument.getElementById('title');if (titleElementInIframe) {titleElementInIframe.textContent = 'New Title in Iframe';}

對于在線編輯器,通常我們是替換整個預覽內容,所以 `document.write()` 或 `srcdoc` 更常用。

其他屬性:

1.src屬性 指定iframe要加載的外部頁面的url。如果你要加載一個已有的網頁,會用這個。對于我們的編輯器 我們是動態生成內容 所以scrdoc或者document.write()

2.`width`, `height`: 設置 `iframe` 的寬高。

3. `sandbox`: (高級) 用于對 `iframe` 內容施加額外的限制,增強安全性。例如,阻止腳本執行、阻止表單提交等。


二 :開發過程

我們總結一下開發任務:

1. ?獲取 `textarea` 的引用

2. ?獲取 `iframe` 的引用

3. ?給 `textarea` 添加 `input` 事件監聽器。

4.? 在事件處理函數中:

? ? ? ?獲取 `textarea` 的 `.value` (用戶輸入的 HTML 代碼)。

? ? ? ?使用 `iframe.contentWindow.document.open()`, `.write()`, `.close()` **或者** `iframe.srcdoc` 將這段 HTML 代碼設置到 `iframe` 中,讓它顯示出來。

先從這兩個元素最核心的用法開始,等把 HTML 預覽功能實現了,我們再考慮 CSS 和 JavaScript 的集成,那會涉及到更多 `iframe` 內部的操作。

(1)前端頁面:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Html在線編譯器</title><link rel="stylesheet" href="./css/index.css"><link rel="stylesheet" href="./css/base.css">
</head>
<body class="body1"><div class="left"><div class="html"><button class="run-html">運行</button><div class="title">html編輯器</div><textarea name="html" id="1" class="htmlInput"></textarea></div><div class="css"><div class="title">css編輯器</div><textarea name="css" id="2" class="cssInput"></textarea></div><div class="js"><div class="title">js編輯器</div><textarea name="js" id="3" class="jsInput"></textarea></div></div><div class="right"><div class="show"><div class="title">在線預覽</div><!-- iframe標簽用于嵌入一個小的html文檔窗口 --><!-- iframe里面的內容和外部的相互獨立的 互不影響 --><iframe src="about:blank" frameborder="0">1</iframe><!-- frameborder :這個屬性用來指定是否顯示 <iframe> 的邊框。 0 表示沒有邊框, 1 表示顯示邊框 --></div></div><script src="./js/index.js"></script>
</body>
</html>

(2)css

*{margin: 0;padding: 0;box-sizing: border-box;font-family: Arial, Helvetica, sans-serif;
}
html, body {height: 100%;
}body{background-color: #454545;display: flex;
}
/* 左 */
.left{width: 50vw;height: 100%;/* background-color: pink; */padding: 5vh;
}
.left .html{width: 100%;height: 30vh;border-radius: 5px;background-color: #fff;margin-bottom: 1vh;display: flex;flex-direction: column;position: relative;
}
.run-html{transform: translate(-110%, -110%);top: 100%;left: 100%;position: absolute;width: 10vh;border-radius: 2vh;background-color: #95e330;
}
.run-html:hover{background-color: #88d228;
}
.run-html:active{background-color: #78c220;
}
.left .css{width: 100%;height: 30vh;border-radius: 5px;background-color: #fff;margin-bottom: 1vh;display: flex;flex-direction: column;}
.left .js{width: 100%;height: 30vh;border-radius: 5px;background-color: #fff;margin-bottom: 1vh;display: flex;flex-direction: column;}
.left .title{width: 100%;text-align: center;border: 0.5px solid #ccc;
}
.left textarea{padding: 2px;width: 100%;height: 100%;border: 0;box-sizing: border-box;flex-grow: 1;background-color: #ccc;
}.left textarea:focus {/* 點擊輸入框不會出現黑邊 */outline: none;
}
/* 右 */
.right{width: 50vw;height: 100%;/* background-color: skyblue; */padding: 5vh;
}.right .show{width: 100%;height: 92vh;background-color: #fff;
}.right .title{width: 100%;text-align: center;border: 0.5px solid #ccc;
}.right iframe{width: 100%;height: 100%;
}

(3)js

const html=document.querySelector('.htmlInput');
const css=document.querySelector('.cssInput');
const js=document.querySelector('.jsInput');const btnhtml=document.querySelector('.run-html');
const output=document.querySelector('.show iframe');
function run(){output.contentDocument.body.innerHTML = html.value + '<style>' + css.value + '</style>';const script = output.contentDocument.createElement('script');script.textContent = js.value;output.contentDocument.body.appendChild(script);
}
btnhtml.addEventListener('click',run);

就這樣吧 實現這個功能如果利用這個iframe標簽的話就非常簡單了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/87283.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/87283.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/87283.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Bluedroid】藍牙啟動之核心模塊(startProfiles )初始化與功能源碼解析

本文深入解析Android藍牙協議棧中 start_profiles 函數及其調用的核心模塊初始化邏輯,涵蓋 BNEP、PAN、A2DP、AVRC、HID Host、BTA_AR 等關鍵配置文件和應用層模塊。通過代碼分析與流程梳理,闡述各模塊如何通過全局控制塊、狀態機、回調機制實現功能初始化、連接管理及數據交…

RK3576 Android14 DMIC調制

一、背景 近期項目中有個DMIC調試的需求&#xff0c;擱置了較長時間&#xff0c;現今著手調試&#xff0c;遂作記錄。 二、開發環境 OS&#xff1a;Android14 Platform&#xff1a;RK3576 Linux Version&#xff1a;6.1.99 SDK Version&#xff1a;android-14.0-mid-rkr6 …

使用 Prometheus 監控 Spring Boot 應用

SpringBoot+Prometheus+Grafana實現監控 邏輯如圖 應用程序在生產環境中運行時,監控其運行狀況是非常必要的。通過實時了解應用程序的運行狀況,才能在問題出現之前得到警告,也可以通監控應用系統的運行狀況,優化性能,提高運行效率。 一、監控 Spring Boot 應用 下面我們…

簡易計算器 Python 實現

目錄 一、代碼逐步分析&#xff08;適合剛入門的朋友看&#xff09; 1.定義了一個名為simple_calculator的函數&#xff0c;封裝了整個計算器的邏輯。 二、深入分析代碼塊&#xff0c;用更加官方的語詞來說&#xff08;適合想要深入學習的朋友&#xff09; 主循環結構 退出…

開源編譯器介紹

文章目錄 基本構成傳統編譯器編譯器的發展歷史&#xff08;History of Compiler&#xff09;GCC 編譯過程與原理&#xff08;GCC Process and Principle&#xff09;LLVM/Clang 編譯過程與原理&#xff08;LLVM/Clang Process and Principle&#xff09;GCC與與 LLVM/Clang 的對…

C++ String知識點

當然可以&#xff01;下面我將以系統全面、通俗易懂、深入淺出的方式&#xff0c;為你講解 C 中非常核心但也容易被低估的內容 —— std::string。 &#x1f31f; C std::string 全面詳解 &#x1f4cc; 一、string 是什么&#xff1f; C 的 std::string 是 C 標準庫中封裝好…

全新NVIDIA Llama Nemotron Nano視覺語言模型在OCR基準測試中準確率奪冠

全新NVIDIA Llama Nemotron Nano視覺語言模型在OCR基準測試中準確率奪冠 PDF、圖表、圖形和儀表板等文檔是豐富的數據源&#xff0c;當這些數據被提取和整理后&#xff0c;能夠為決策制定提供有價值的洞察。從自動化財務報表處理到改進商業智能工作流程&#xff0c;智能文檔處…

gradle的 build時kaptDebugKotlin 處理數據庫模塊

gradle的 build時輸出&#xff1a; Task :app:kaptDebugKotlin 注: Processing class HDCoinBean 注: Processing class HDCurrencyBean 注: Processing class HDSelfAddCoin 注: Processing class MN 注: Creating DefaultRealmModule <—> 80% EXECUTING [7m 56s] IDLE…

二叉樹的節點操作算法

235. 二叉搜索樹的最近公共祖先 力扣題目鏈接(opens new window) 給定一個二叉搜索樹, 找到該樹中兩個指定節點的最近公共祖先。 百度百科中最近公共祖先的定義為:“對于有根樹 T 的兩個結點 p、q,最近公共祖先表示為一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度盡可能大…

【ubuntu驅動安裝】安裝nvidia驅動和cuda環境

1、安裝驅動 首先查看環境和顯卡&#xff1a; 更新apt 查看nouveau是否禁用 如果有返回值禁用nouveau(nouveau是通用的驅動程序)&#xff08;必須&#xff09;&#xff0c;兩種文件&#xff0c;22.04是下面那個 添加如下&#xff1a; 終端輸入后更新 重啟電腦sudo reboo…

力扣HOT100之終章:一些隨筆

今天終于把力扣HOT100系列給刷完了&#xff0c;每一道題都記錄了自己的思考過程和解題過程中參考的一些題解和視頻&#xff0c;方便自己以后再刷的時候快速復習&#xff0c;從2025年3月4日寫下第一篇博客&#xff0c;到2025年6月12日完成最后一題并寫下最后一篇博客&#xff0c…

榕壹云家政系統:基于Spring Boot與UniApp的智能家政服務解決方案

在數字化浪潮下&#xff0c;傳統家政行業正面臨效率與服務質量的升級挑戰。榕壹云公司依托前沿技術&#xff0c;推出了一款用戶端與師傅端二合一的家政服務小程序&#xff0c;通過整合預約上門、分銷、儲值、優惠券等功能&#xff0c;為家政服務行業提供了一套高效、靈活的數字…

CSRF擴展 JSONP劫持

介紹&#xff1a;JOSNP&#xff08;JSONP with Override Security Negotiation Protocol&#xff09;劫持是一種利用JSONP &#xff08;JSON with Padding&#xff09;跨域數據獲取機制的安全漏洞&#xff0c;攻擊者通過篡改或偽造JSONP回調函數竊 取用戶敏感數據。由于JSONP…

HTTP/HTTPS 協議解析

前言 在當今互聯網時代&#xff0c;HTTP/HTTPS 協議作為 Web 通信的基石&#xff0c;承載著幾乎所有的網絡內容傳輸。對于我們而言&#xff0c;深入理解這些協議不僅是技術素養的體現&#xff0c;更是構建高性能、安全、可靠 Web 應用的必要條件。 為什么我們需要深入了解 HT…

Flask-login 處理授權邏輯

認證 vs 授權&#xff1a; 在 Web 應用程序的安全機制中&#xff0c;認證&#xff08;Authentication&#xff09; 和 授權&#xff08;Authorization&#xff09; 是兩個核心概念&#xff0c;它們雖然緊密相關&#xff0c;但職責和作用不同。 認證&#xff08;Authenticatio…

xenomai3+linux構建linux實時操作系統-基于X86_64和arm

簡介&#xff1a; Xenomai是一個實時性解決方案&#xff0c;通過在Linux上添加實時內核Cobalt來增強實時性能。它有三個主要部分&#xff1a;libcobalt&#xff08;用戶空間實時庫&#xff09;、Cobalt&#xff08;內核空間實時內核&#xff09;和硬件架構特定層&#xff08;ip…

Linux核心文件(core file)詳解

一、核心文件&#xff08;core file&#xff09;概述 1.1 什么是核心文件 核心文件&#xff08;core file&#xff09;是Linux操作系統在程序崩潰時生成的一種轉儲文件。它包含了程序崩潰時的內存內容、寄存器狀態和執行狀態。通過分析核心文件&#xff0c;開發者可以找到程序…

java中跨域問題及解決方案

1. 什么是跨域 從不同的地址訪問另外一個地址就是跨域 2.跨域一定會有異常嗎 跨域異常只會在前端發生&#xff0c;后端跨域不會產生異常 因為瀏覽器有一個叫做同源策略的東西&#xff0c;它發現不同域之間的訪問是不安全的行為&#xff0c;會禁止&#xff0c;所以會拋出異常…

網絡層協議 IP 協議介紹 -- IP 協議,網段劃分,私有 IP 和 公網 IP,路由

目錄 1 IP 協議 1.1 IP 協議格式 2. 網段劃分 2.1 網絡號和主機號 2.2 傳統 IP 地址分類和 CIDR 技術 2.3 特殊的 IP 地址 2.4 IP 地址的數量限制 2.5 私有 IP 和公網 IP 3. 路由 網絡層主要作用是實現不同局域網之間的通信連接&#xff0c;并為數據在復雜網絡環境中的…

【案例分享】KMDA-7611-S001--高性能嵌入式電腦助力雙臂輪式人形機器人應用

智能制造時代&#xff0c;雙臂輪式機器人需求浮出水面 隨著制造業、物流業和電子商務的飛速發展&#xff0c;智能搬運機器人正成為行業降本增效的核心工具。它們不僅解決了傳統物流中效率低、成本高、安全性差等痛點&#xff0c;更通過智能化與可擴展性設計&#xff0c;通過自主…