【工具】前端JavaScript代码在线执行器 方便通过网页 手机测试js代码
- 自动补全
- js代码格式化
- 代码色彩
- 打印日志
- 清空日志
- 待补充
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JS执行器</title>
<!-- 引入 CodeMirror 的 CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.9/codemirror.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.9/theme/material-darker.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.9/addon/hint/show-hint.min.css">
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
button {
margin-top: 10px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
#output {
margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
background-color: #f9f9f9;
white-space: pre-wrap;
height: 400px; /* 提高日志区域高度 */
overflow-y: scroll;
}
.CodeMirror {
border: 1px solid #ccc;
height: 400px; /* 调高默认高度 */
}
.collapsible {
cursor: pointer;
background-color: #f9f9f9;
border: none;
outline: none;
text-align: left;
padding: 5px;
width: 100%;
}
.collapsible:after {
content: '\25BC'; /* Arrow down */
float: right;
}
.collapsible.active:after {
content: '\25B2'; /* Arrow up */
}
.content {
padding: 0 18px;
display: none;
overflow: hidden;
background-color: #f1f1f1;
}
.log-time {
font-size: 0.9em;
color: gray;
}
</style>
</head>
<body>
<h1>JavaScript 执行器</h1>
<textarea id="codeInput" placeholder="在此输入JavaScript代码..."></textarea>
<button onclick="executeCode()">执行代码</button>
<button onclick="formatCode()">格式化代码</button>
<button onclick="clearLogs()">清空日志</button>
<button onclick="triggerAutocomplete()">触发自动补全</button> <!-- 新增手动触发补全按钮 -->
<div id="output"></div>
<!-- 引入 CodeMirror 和 JavaScript 解析器 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.9/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.9/mode/javascript/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.9/addon/edit/closebrackets.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.9/addon/hint/show-hint.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.9/addon/hint/javascript-hint.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prettier@2.7.1/standalone.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prettier@2.7.1/parser-babel.js"></script>
<script>
// 初始化 CodeMirror 文本编辑器
const editor = CodeMirror.fromTextArea(document.getElementById('codeInput'), {
lineNumbers: true,
mode: 'javascript',
theme: 'material-darker',
autoCloseBrackets: true,
extraKeys: {
"Ctrl-Space": "autocomplete",
"Alt-Space": "autocomplete" // 在移动设备上尝试不同的键触发补全
}
});
// 自动补全提示功能
editor.on('inputRead', function(cm) {
if (!cm.state.completionActive) { // 如果没有激活补全
CodeMirror.commands.autocomplete(cm); // 主动触发补全
}
});
// 重定向 console 方法到页面上
(function() {
const outputDiv = document.getElementById('output');
const methods = ['log', 'info', 'warn', 'error'];
methods.forEach(method => {
const original = console[method];
console[method] = function(...args) {
const logItem = document.createElement('div');
const timestamp = document.createElement('span');
timestamp.className = 'log-time';
timestamp.textContent = `[${new Date().toLocaleTimeString()}] `;
logItem.appendChild(timestamp);
args.forEach(arg => {
if (typeof arg === 'object') {
logItem.appendChild(createCollapsibleObject(arg));
} else {
logItem.textContent += `[${method.toUpperCase()}] ` + arg + '\n';
}
});
outputDiv.appendChild(logItem);
outputDiv.scrollTop = outputDiv.scrollHeight; // 保持滚动条在最底部
original.apply(console, args);
};
});
})();
// 创建折叠对象的函数
function createCollapsibleObject(obj) {
const btn = document.createElement('button');
btn.className = 'collapsible';
btn.textContent = 'Object';
const contentDiv = document.createElement('div');
contentDiv.className = 'content';
const pre = document.createElement('pre');
pre.textContent = JSON.stringify(obj, null, 2);
contentDiv.appendChild(pre);
btn.addEventListener('click', function() {
this.classList.toggle('active');
contentDiv.style.display = contentDiv.style.display === 'block' ? 'none' : 'block';
});
const wrapper = document.createElement('div');
wrapper.appendChild(btn);
wrapper.appendChild(contentDiv);
return wrapper;
}
// 执行代码函数
function executeCode() {
const code = editor.getValue();
const outputDiv = document.getElementById('output');
try {
eval(code); // 执行代码
} catch (error) {
const errorLog = document.createElement('div');
errorLog.textContent = '错误: ' + error.message;
outputDiv.appendChild(errorLog);
}
}
// 格式化代码函数
function formatCode() {
const unformattedCode = editor.getValue();
try {
const formattedCode = prettier.format(unformattedCode, {
parser: "babel", // 使用 babel 解析器处理 JavaScript
plugins: prettierPlugins
});
editor.setValue(formattedCode);
} catch (error) {
console.error('格式化错误:', error.message);
}
}
// 清空日志函数
function clearLogs() {
const outputDiv = document.getElementById('output');
outputDiv.innerHTML = ''; // 清空日志内容
}
// 手动触发自动补全的函数
function triggerAutocomplete() {
CodeMirror.commands.autocomplete(editor);
}
</script>
</body>
</html>