You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Ace编辑器占满全屏高度?添加打开/另存为工具栏按钮

Ace编辑器全屏高度设置与工具栏按钮扩展

一、解决编辑器高度无法占满全屏的问题

你的代码里有两个核心问题导致高度失效:

  1. 编辑器配置了minLines: 30和maxLines: 30,这会强制固定编辑器行数,覆盖CSS的高度设置
  2. 工具栏和编辑器是并列元素,直接给编辑器设100vh会和工具栏重叠或超出页面

修复步骤:

  1. 修改CSS布局:用flex布局让body垂直排列,工具栏占固定空间,编辑器自动填充剩余高度
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.ace_editor {
  font-weight: bold;
  width: 100%;
  flex-grow: 1; /* 占满剩余高度 */
}

.toolbar {
  border: 1px solid gray;
  background: #333;
  padding: 8px;
}
  1. 调整编辑器配置:删除固定行数的限制,保留必要配置
var editor = ace.edit();
editor.setOptions({
    theme: "ace/theme/monokai",
    mode: "ace/mode/html",
    autoScrollEditorIntoView: true,
    // 移除 minLines 和 maxLines
});

二、添加「打开文件」和「另存为」按钮

1. 扩展工具栏DOM

在buildDom的工具栏数组中添加两个按钮:

buildDom(["div", { class: "toolbar" },
    // ... 原有按钮 ...
    ["button", {
        ref: "openButton",
        onclick: openFile
    }, "打开文件"],
    ["button", {
        ref: "saveAsButton",
        onclick: saveAsFile
    }, "另存为"],
], document.body, refs);

2. 实现按钮功能

添加以下函数到你的脚本中:

从本地存储(localStorage)读取文件

function openFile() {
    const savedContent = localStorage.savedValue;
    if (savedContent) {
        editor.session.setValue(savedContent);
        editor.session.getUndoManager().markClean();
        updateToolbar();
    } else {
        alert("暂无已保存的文件");
    }
}

另存为本地文件(下载到电脑)

function saveAsFile() {
    const content = editor.getValue();
    // 根据编辑器模式调整文件类型,比如text/javascript、text/css等
    const blob = new Blob([content], { type: "text/html" });
    const url = URL.createObjectURL(blob);
    
    const downloadLink = document.createElement("a");
    downloadLink.href = url;
    downloadLink.download = "editor-content.html"; // 默认文件名
    downloadLink.click();
    
    URL.revokeObjectURL(url);
}

可选:支持选择本地文件打开

如果需要读取用户电脑上的文件,替换openFile函数为:

function openFile() {
    const fileInput = document.createElement("input");
    fileInput.type = "file";
    fileInput.accept = "text/*,.html,.js,.css"; // 支持的文件类型
    
    fileInput.onchange = function(e) {
        const file = e.target.files[0];
        if (!file) return;
        
        const reader = new FileReader();
        reader.onload = function(event) {
            editor.session.setValue(event.target.result);
            editor.session.getUndoManager().markClean();
            updateToolbar();
        };
        reader.readAsText(file);
    };
    
    fileInput.click();
}

完整修改后的代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

  <style type="text/css" media="screen">
    * {
      box-sizing: border-box;
    }
    
    body {
      margin: 0;
      display: flex;
      flex-direction: column;
      height: 100vh;
    }
    
    .ace_editor {
      font-weight: bold;
      width: 100%;
      flex-grow: 1;
    }
    
    .toolbar {
      border: 1px solid gray;
      background: #333;
      padding: 8px;
    }
    
    .toolbar button {
      color: white;
      background: #555;
      border: none;
      padding: 4px 8px;
      margin-right: 4px;
      cursor: pointer;
    }
    
    .toolbar button:hover {
      background: #777;
    }
  </style>
</head>

<body>
  
  <!-- load ace -->
  <script src="http://ajaxorg.github.io/ace-builds/src/ace.js"></script>
  <!-- load ace language_tools extension -->
  <script src="http://ajaxorg.github.io/ace-builds/src/ext-language_tools.js"></script>
  <script>
    var buildDom = ace.require("ace/lib/dom").buildDom;
    var editor = ace.edit();
    editor.setOptions({
        theme: "ace/theme/monokai",
        mode: "ace/mode/html",
        autoScrollEditorIntoView: true,
    });
    var refs = {};
    function updateToolbar() {
        refs.saveButton.disabled = editor.session.getUndoManager().isClean();
        refs.undoButton.disabled = !editor.session.getUndoManager().hasUndo();
        refs.redoButton.disabled = !editor.session.getUndoManager().hasRedo();
    }
    editor.on("input", updateToolbar);
    editor.session.setValue(localStorage.savedValue || "Welcome to ace Toolbar demo!")
    
    function save() {
        localStorage.savedValue = editor.getValue(); 
        editor.session.getUndoManager().markClean();
        updateToolbar();
    }
    
    // 打开文件函数(本地文件版本)
    function openFile() {
        const fileInput = document.createElement("input");
        fileInput.type = "file";
        fileInput.accept = "text/*,.html,.js,.css";
        
        fileInput.onchange = function(e) {
            const file = e.target.files[0];
            if (!file) return;
            
            const reader = new FileReader();
            reader.onload = function(event) {
                editor.session.setValue(event.target.result);
                editor.session.getUndoManager().markClean();
                updateToolbar();
            };
            reader.readAsText(file);
        };
        
        fileInput.click();
    }
    
    // 另存为本地文件函数
    function saveAsFile() {
        const content = editor.getValue();
        const blob = new Blob([content], { type: "text/html" });
        const url = URL.createObjectURL(blob);
        
        const downloadLink = document.createElement("a");
        downloadLink.href = url;
        downloadLink.download = "editor-content.html";
        downloadLink.click();
        
        URL.revokeObjectURL(url);
    }
    
    editor.commands.addCommand({
        name: "save",
        exec: save,
        bindKey: { win: "ctrl-s", mac: "cmd-s" }
    });
    
    buildDom(["div", { class: "toolbar" },
        ["button", {
            ref: "saveButton",
            onclick: save
        }, "保存"],
        ["button", {
            ref: "openButton",
            onclick: openFile
        }, "打开文件"],
        ["button", {
            ref: "saveAsButton",
            onclick: saveAsFile
        }, "另存为"],
        ["button", {
            ref: "undoButton",
            onclick: function() {
                editor.undo();
            }
        }, "撤销"],
        ["button", {
            ref: "redoButton",
            onclick: function() {
                editor.redo();
            }
        }, "重做"],
        ["button", {
            style: "font-weight: bold",
            onclick: function() {
                editor.insertSnippet("**${1:$SELECTION}**");
                editor.renderer.scrollCursorIntoView()
            }
        }, "加粗"],
        ["button", {
            style: "font-style: italic",
            onclick: function() {
                editor.insertSnippet("*${1:$SELECTION}*");
                editor.renderer.scrollCursorIntoView()
            }
        }, "斜体"],
    ], document.body, refs);
    document.body.appendChild(editor.container)
    
    window.editor = editor;
  </script>
  
</body>

</html>

内容的提问来源于stack exchange,提问作者Diaa Sh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 09:45:03