1 Star 11 Fork 2

刻晴的英雄/online_editor

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
index.html 20.23 KB
一键复制 编辑 原始数据 按行查看 历史
刻晴的英雄 提交于 2019-06-19 17:38 . 可以引入本地js文件
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
<!DOCTYPE html>
<html>
<head>
<!--
作者:xujun_bachlor@163.com
时间:2019-06-18
描述:更多详细信息可以参考https://zhuanlan.zhihu.com/p/22163474
code mirror官网: https://codemirror.net/
-->
<meta charset="utf-8" />
<title>在线编辑器</title>
<style>
/**
* 各种样式可以打开开发者模式进行查看
*/
.CodeMirror {
height: 100% !important;
font-size: 14px;
line-height: 18px;
}
#output {
width: 100%;
height: 100%;
}
#iframeResult {
display:block;
overflow:hidden;
border:0!important;
min-width:100px;
width:100%;
height:100%;
background-color:#fff
}
.windowLabel {
letter-spacing: 1px;
text-transform: uppercase;
border: 1px solid rgba(255,255,255,0);
background: rgba(243,245,246,.8);
display: inline-block;
position: absolute;
top: 7px;
right: 5px;
text-align: center;
font-size: 11px;
border-radius: 20px;
z-index: 30;
color: #7f94a1;
line-height: 23px;
padding: 0 7px;
}
.windowLabel .label {
color: #23527c;
}
.label {
display: inline;
padding: .2em .6em .3em;
font-size: 75%;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
}
.fa {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.btn {
display: inline-block;
font-weight: 400;
color: #4E5155;
text-align: center;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
padding: .438rem 1.125rem;
font-size: .894rem;
line-height: 1.54;
border-radius: .25rem;
transition: all 0.2s ease-in-out;
cursor: pointer;
}
.btn-primary {
background: #26b4ff;
}
.btn-primary:hover {
background: #24abf2;
}
.btn-primary, .btn-primary:hover {
border-color: transparent;
color: #fff;
}
.btn-sm{
padding: .188rem .6875rem;
font-size: .75rem;
line-height: 1.5;
border-radius: .25rem;
}
.tool-group {
margin: 10px;
display: flex;
align-items: center;
height: 33px;
}
.error-tip {
display: inline-block;
color: #a94442;
background-color: #f2dede;
padding: 6px;
border: 1px solid #ebccd1;
border-radius: 4px;
}
/*
* 文本框中placeholder的样式
*/
#splitContainer .cm-s-dracula.CodeMirror {
color: rgba(248, 248, 242,0.3) !important;
}
#select {
height: 26px;
outline: none;
border-radius: 3px;
padding-left: 15px;
margin-left: 5px;
}
.file-btn {
line-height: 22px;
width: 270px;
border: 1px solid #409EFF;
margin-left: 20px;
}
.inputfile {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.inputfile + label {
font-size: 14px;
color: #409eff;
background-color: #ecf5ff;
border: 1px solid #b3d8ff;
display: inline-block;
cursor: pointer; /* 小手光标*/
padding: 0 10px;
}
.inputfile:focus + label,
.inputfile + label:hover {
background: #409eff;
border-color: #409eff;
color: #fff;
}
.inputfile:focus + label {
outline: 1px dotted #000;
outline: -webkit-focus-ring-color auto 5px;
}
</style>
<!-- code mirror的样式 -->
<link rel="stylesheet" href="css/codemirror.css" />
<!--<link rel="stylesheet" href="css/dialog.css" />-->
<!-- 主题的样式 -->
<link rel="stylesheet" href="theme/3024-day.css">
<link rel="stylesheet" href="theme/3024-night.css">
<link rel="stylesheet" href="theme/abcdef.css">
<link rel="stylesheet" href="theme/ambiance.css">
<link rel="stylesheet" href="theme/base16-dark.css">
<link rel="stylesheet" href="theme/bespin.css">
<link rel="stylesheet" href="theme/base16-light.css">
<link rel="stylesheet" href="theme/blackboard.css">
<link rel="stylesheet" href="theme/cobalt.css">
<link rel="stylesheet" href="theme/colorforth.css">
<link rel="stylesheet" href="theme/dracula.css">
<link rel="stylesheet" href="theme/duotone-dark.css">
<link rel="stylesheet" href="theme/duotone-light.css">
<link rel="stylesheet" href="theme/eclipse.css">
<link rel="stylesheet" href="theme/elegant.css">
<link rel="stylesheet" href="theme/erlang-dark.css">
<link rel="stylesheet" href="theme/gruvbox-dark.css">
<link rel="stylesheet" href="theme/hopscotch.css">
<link rel="stylesheet" href="theme/icecoder.css">
<link rel="stylesheet" href="theme/isotope.css">
<link rel="stylesheet" href="theme/lesser-dark.css">
<link rel="stylesheet" href="theme/liquibyte.css">
<link rel="stylesheet" href="theme/lucario.css">
<link rel="stylesheet" href="theme/material.css">
<link rel="stylesheet" href="theme/mbo.css">
<link rel="stylesheet" href="theme/mdn-like.css">
<link rel="stylesheet" href="theme/midnight.css">
<link rel="stylesheet" href="theme/monokai.css">
<link rel="stylesheet" href="theme/neat.css">
<link rel="stylesheet" href="theme/neo.css">
<link rel="stylesheet" href="theme/night.css">
<link rel="stylesheet" href="theme/nord.css">
<link rel="stylesheet" href="theme/oceanic-next.css">
<link rel="stylesheet" href="theme/panda-syntax.css">
<link rel="stylesheet" href="theme/paraiso-dark.css">
<link rel="stylesheet" href="theme/paraiso-light.css">
<link rel="stylesheet" href="theme/pastel-on-dark.css">
<link rel="stylesheet" href="theme/railscasts.css">
<link rel="stylesheet" href="theme/rubyblue.css">
<link rel="stylesheet" href="theme/seti.css">
<link rel="stylesheet" href="theme/shadowfox.css">
<link rel="stylesheet" href="theme/solarized.css">
<link rel="stylesheet" href="theme/the-matrix.css">
<link rel="stylesheet" href="theme/tomorrow-night-bright.css">
<link rel="stylesheet" href="theme/tomorrow-night-eighties.css">
<link rel="stylesheet" href="theme/ttcn.css">
<link rel="stylesheet" href="theme/twilight.css">
<link rel="stylesheet" href="theme/vibrant-ink.css">
<link rel="stylesheet" href="theme/xq-dark.css">
<link rel="stylesheet" href="theme/xq-light.css">
<link rel="stylesheet" href="theme/yeti.css">
<link rel="stylesheet" href="theme/idea.css">
<link rel="stylesheet" href="theme/darcula.css">
<link rel="stylesheet" href="theme/yonce.css">
<link rel="stylesheet" href="theme/zenburn.css">
<!-- 代码折叠时的样式 -->
<link rel="stylesheet" href="css/foldgutter.css" />
<!-- 全屏时的样式 -->
<link rel="stylesheet" href="css/fullscreen.css" />
<!-- 唤出来的提示代码的样式 -->
<link rel="stylesheet" href="css/show-hint.css" />
<link rel="stylesheet" href="css/jqx.base.css" />
<script src="js/jquery-3.4.1.min.js"></script>
<!-- code mirror核心代码 -->
<script src="js/codemirror.js"></script>
<!-- javascript代码高亮样式 -->
<script src="js/javascript.js"></script>
<!-- 可以设置代码提示 -->
<script src="js/anyword-hint.js"></script>
<script src="js/show-hint.js"></script>
<script src="js/dialog.js"></script>
<!-- 代码折叠 -->
<script src="js/brace-fold.js"></script>
<script src="js/foldcode.js"></script>
<script src="js/foldgutter.js"></script>
<!--<script src="js/comment-fold.js"></script>-->
<!-- 全屏显示,好像没什么用 -->
<script src="js/fullscreen.js"></script>
<!-- 搜索完成后光标会消失 -->
<script src="js/searchcursor.js"></script>
<!-- 给编辑器添加搜索功能 -->
<script src="js/search.js"></script>
<!-- 使用后编写css会有各种高亮颜色提示 -->
<script src="js/css.js"></script>
<!-- html中混合使用css和js时也会有样式适配 -->
<script src="js/htmlmixed.js"></script>
<!-- 允许textarea中使用placeholder -->
<script src="js/placeholder.js"></script>
<!-- 使用后html代码会有各种颜色提示 -->
<script src="js/xml.js"></script>
<!-- 自动闭合标签 -->
<script src="js/closetag.js"></script>
<!-- 自动闭合括号 -->
<script src="js/closebrackets.js"></script>
<!-- 光标放在括号右边时,自动高亮对应的括号 -->
<script src="js/matchbrackets.js"></script>
<!-- 鼠标点击时,自动匹配成对的标签,需要先引入xml-fold.js,要不然会报错,引入xml-fold可以折叠html代码 -->
<script src="js/xml-fold.js"></script>
<script src="js/matchtags.js"></script>
<!-- 高亮光标所在的行 -->
<script src="js/active-line.js"></script>
<!-- 用于分割页面 -->
<script src="js/jqxcore.js"></script>
<script src="js/jqxsplitter.js"></script>
</head>
<body>
<div class="tool-group">
<span style="margin-right: 15px;">HTML/CSS/JS在线工具</span>
<button onclick="generateHtmlTemplate()" class="btn btn-primary btn-sm" style="margin-right: 15px;">html模板</button>
<button onclick="submitTryit()" class="btn btn-primary btn-sm" style="margin-right: 15px;">执行代码</button>
<input type="checkbox" value="" id="isautorun"/>自动执行
<span style="margin-left: 20px;">切换主题</span>
<select id="select" onchange="selectTheme(event)">
<option>default</option>
<option>3024-day</option>
<option>3024-night</option>
<option>abcdef</option>
<option>ambiance</option>
<option>base16-dark</option>
<option>base16-light</option>
<option>bespin</option>
<option>blackboard</option>
<option>cobalt</option>
<option>colorforth</option>
<option>darcula</option>
<option selected>dracula</option>
<option>duotone-dark</option>
<option>duotone-light</option>
<option>eclipse</option>
<option>elegant</option>
<option>erlang-dark</option>
<option>gruvbox-dark</option>
<option>hopscotch</option>
<option>icecoder</option>
<option>idea</option>
<option>isotope</option>
<option>lesser-dark</option>
<option>liquibyte</option>
<option>lucario</option>
<option>material</option>
<option>mbo</option>
<option>mdn-like</option>
<option>midnight</option>
<option>monokai</option>
<option>neat</option>
<option>neo</option>
<option>night</option>
<option>nord</option>
<option>oceanic-next</option>
<option>panda-syntax</option>
<option>paraiso-dark</option>
<option>paraiso-light</option>
<option>pastel-on-dark</option>
<option>railscasts</option>
<option>rubyblue</option>
<option>seti</option>
<option>shadowfox</option>
<option>solarized dark</option>
<option>solarized light</option>
<option>the-matrix</option>
<option>tomorrow-night-bright</option>
<option>tomorrow-night-eighties</option>
<option>ttcn</option>
<option>twilight</option>
<option>vibrant-ink</option>
<option>xq-dark</option>
<option>xq-light</option>
<option>yeti</option>
<option>yonce</option>
<option>zenburn</option>
</select>
<div class="file-btn">
<input type="file" id="file" class="inputfile" onchange="addLibJs(event)"/>
<label for="file">添加库</label>
<span class="inner"></span>
</div>
<div class="error-tip" style="display: none;margin-left: 20px;"><span ></span></div>
</div>
<div id="splitContainer">
<div>
<div id="leftSplitter">
<div>
<textarea placeholder="输入 HTML 代码……" id="code-html" class="form-control" name="code" rows="11"></textarea>
<a href="javascript:void(0);" class="windowLabel" data-panel="js">
<span class="label">
HTML
</span>
<i class="fa fa-cog">
</i>
</a>
</div>
<div>
<textarea placeholder="输入 JavaScript 代码……" id="code-js" class="form-control" name="code" rows="10"></textarea>
<a href="javascript:void(0);" class="windowLabel" data-panel="js">
<span class="label">
JavaScript
</span>
<i class="fa fa-cog">
</i>
</a>
</div>
</div>
</div>
<div>
<div id="rightSplitter">
<div>
<textarea placeholder="输入 CSS 代码……" id="code-css" class="form-control" rows="11"></textarea>
<a href="javascript:void(0);" class="windowLabel" data-panel="js">
<span class="label">
CSS
</span>
<i class="fa fa-cog">
</i>
</a>
</div>
<div id="output">
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(() => {
let winHeight = 0;
if(window.innerHeight) {
winHeight = window.innerHeight
}else if((document.body) && document.body.clientHeight) {
winHeight = document.body.clientHeight;
}
if(document.documentElement && document.documentElement.clientHeight) {
winHeight = document.documentElement.clientHeight;
}
$('#isautorun').prop('checked',true); // 是否在写代码时自动运行代码
let height = (winHeight - 60) * 0.86;
// 分割html、css、js代码区
$('#splitContainer').jqxSplitter({ height: height, width: '100%', orientation: 'vertical', panels: [{ size: '50%' }, { size: '50%' }] });
$('#leftSplitter').jqxSplitter({ height: '100%', width: '100%', orientation: 'horizontal', panels: [{ size: '50%' }, { size: '50%'}] });
$('#rightSplitter').jqxSplitter({ height: '100%', width: '100%', orientation: 'horizontal', panels: [{ size: '50%' }, { size: '50%'}] });
});
// 使用code mirror生成编辑器时配置
let cm_opt = {
mode: 'text/html', // 模式,表示对那种类型的代码进行样式渲染
gutter: false,
lineNumbers: true, // 行号
autoCloseBrackets:true, // 是否自动闭合括号
styleActiveLine: true, // 高亮当前行
theme:"dracula", // 编辑器主题
lineWrapping: true, // 是否换行
foldGutter: true, // 是否能折叠代码
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
extraKeys: {"Alt-/": "autocomplete"}, // 使用alt+/唤出代码提示
matchBrackets: true, // 是否能匹配成对的括号
matchTags: {bothTags: true}, // 鼠标点击时匹配成对的标签
autoCloseTags:true // 是否自动闭合标签
}
/**
* 作者:xujun_bachlor@163.com
时间:2019-06-18
描述:更多配置信息可以参考https://zhuanlan.zhihu.com/p/22163474
*/
let html_editor = CodeMirror.fromTextArea(document.getElementById("code-html"),cm_opt);
html_editor.on('change',function(inst,changes) {
if($('#isautorun').prop('checked')) {
submitTryit();
}
})
// 文本换行时顶部对齐
// let charWidth = html_editor.defaultCharWidth(), basePadding = 4;
// html_editor.on("renderLine", function(cm, line, elt) {
// var off = CodeMirror.countColumn(line.text, null, cm.getOption("tabSize")) * charWidth;
// elt.style.textIndent = "-" + off + "px";
// elt.style.paddingLeft = (basePadding + off) + "px";
// });
// html_editor.refresh();
Object.assign(cm_opt,{mode: 'text/css'});
let css_editor = CodeMirror.fromTextArea(document.getElementById("code-css"),cm_opt);
css_editor.on('change',function(inst,changes) {
if($('#isautorun').prop('checked')) {
submitTryit();
}
})
Object.assign(cm_opt,{mode: 'text/javascript'});
let js_editor = CodeMirror.fromTextArea(document.getElementById("code-js"),cm_opt);
js_editor.on('change',function(inst,changes) {
if($('#isautorun').prop('checked')) {
submitTryit();
}
})
// 获取上传文件的url
function getObjectURL(file) {
var url = null;
if (window.createObjcectURL != undefined) {
url = window.createOjcectURL(file);
} else if (window.URL != undefined) {
url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) {
url = window.webkitURL.createObjectURL(file);
}
return url;
}
function addLibJs(e) {
let _file = e.target.files[0];
//实例化fileReader,
let fd = new FileReader();
//获取当前选择文件的类型
let fileType = _file.type;
//调它的readAsDataURL并把原生File对象传给它,
fd.readAsDataURL(_file);
let html = html_editor.getValue();
fd.onload = function() {
if(html && /^text\/javascript$/.test(fileType)) {
$('.inner').text(_file.name);
let url = getObjectURL(_file);
let extra = `<!-- ${_file.name} -->\r\n<script src="${url}"><\/script>\r\n`;
html = extra + html;
html_editor.setValue(html);
}
}
}
// 执行所有编辑器的代码生成页面,代码可自己调试查看结果
function submitTryit() {
// 获取编辑器内容
let html = html_editor.getValue();
let css = css_editor.getValue();
let js = js_editor.getValue();
let src = html;
let array_matches_head_tag = null;
let array_matches_body_tag = null;
if(html) {
let patternHtmlTag = /<html([^>]*)>/im;
let array_matches_html_tag = patternHtmlTag.exec(html);
if(array_matches_html_tag) {
src = src.replace('<html>','<html'+array_matches_html_tag[1]+'>');
}
let patternHead = /<head[^>]*>((.|[\n\r])*)<\/head>/im;
array_matches_head_tag = patternHead.exec(src);
let patternBody = /<body([^>]*)>/im;
array_matches_body_tag = patternBody.exec(src);
if(array_matches_body_tag) {
src = src.replace('<body>', '<body ' + array_matches_body_tag[1] + '>');
}
}
if(~css.indexOf('<style>')) {
$('.error-tip span').text('CSS 编辑框不需要 <style> 标签');
$('.error-tip').show().delay(5000).fadeOut();
return;
}else if(~js.indexOf('<script>')) {
$('.error-tip span').text('JS 编辑框不需要 <script> 标签');
$('.error-tip').show().delay(5000).fadeOut();
return;
}else {
$('.error-tip').hide();
}
if(css) {
css = '<style>'+css+'</style>';
if(array_matches_head_tag) {
src = src.replace('</head>',css+'</head>');
}else if(array_matches_body_tag) {
src = src.replace('</body>',css+'</body>');
}else {
src += css;
}
}
if(js) {
js = '<script>'+js+'<\/script>';
if(array_matches_body_tag) {
src = src.replace('</body>',js+'</body>');
}else {
src += js;
}
}
let text = src;
let ifr = document.createElement('iframe');
ifr.setAttribute("frameborder", "0");
ifr.setAttribute("id", "iframeResult");
document.getElementById("output").innerHTML = "";
document.getElementById("output").appendChild(ifr);
var ifrw = (ifr.contentWindow) ? ifr.contentWindow: (ifr.contentDocument.document) ? ifr.contentDocument.document: ifr.contentDocument;
ifrw.document.open();
ifrw.document.write(text);
ifrw.document.close();
autodivheight();
}
// 生成默认的html模板
function generateHtmlTemplate() {
let html_code = "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<title>文档标题</title>\n</head>\n<body>\n\t<h1>我的第一个HTML页面</h1>\n\t<p>我的第一个段落。</p>\n</body>\n</html>\n";
html_editor.getDoc().setValue(html_code);
}
window.addEventListener("resize", autodivheight);
function autodivheight(){
var winHeight=0;
if (window.innerHeight) {
winHeight = window.innerHeight;
} else if ((document.body) && (document.body.clientHeight)) {
winHeight = document.body.clientHeight;
}
//通过深入Document内部对body进行检测,获取浏览器窗口高度
if (document.documentElement && document.documentElement.clientHeight) {
winHeight = document.documentElement.clientHeight;
}
height = height = (winHeight - 60) * 0.86;
document.getElementById("splitContainer").style.height= height +"px";
}
// 切换主题
function selectTheme(e) {
html_editor.setOption('theme',e.target.value);
css_editor.setOption('theme',e.target.value);
js_editor.setOption('theme',e.target.value);
}
</script>
</body>
</html>
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/xujun_bachlor/online_editor.git
git@gitee.com:xujun_bachlor/online_editor.git
xujun_bachlor
online_editor
online_editor
master

搜索帮助