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

求助:ACE Editor光标重置至行首导致输入内容反转问题

问题诊断与修复方案

你的ACE Editor输入内容反转、光标跳行首的问题,核心原因是编辑器内容重复设置导致循环触发+光标位置错误,再加上重复初始化Editor实例引发的冲突。

具体问题点

  1. 重复初始化Editor:代码开头和DOMContentLoaded回调里各初始化了一次ace.edit("editor"),导致实例状态冲突。
  2. onEditorChange逻辑冗余且错误:用户输入触发change事件后,你调用updateCode再次设置Editor内容,而setValue的第二个参数传了-1(强制把光标移到内容开头),导致下一次输入都在开头插入,内容自然反转。
  3. updateCode里重复获取Editor实例:用ace.edit("editor")而非复用已定义的editor变量,容易引发状态不一致。

修复后的代码

document.addEventListener("DOMContentLoaded", () => {
    const socket = io();
    const codingSpace = document.getElementById("codingSpace");
    const roomName = window.location.pathname.slice(1);
    let editorChangeInProgress = false;

    socket.emit("joinRoom", roomName);

    // 仅初始化一次ACE Editor
    const editor = ace.edit("editor");
    editor.setTheme("ace/theme/cobalt");
    editor.getSession().setMode("ace/mode/javascript");

    const codeRef = ref(db, "code");

    const fetchAndDisplayInitialData = async () => {
        try {
            const dataSnapshot = await get(child(codeRef, roomName));
            if (dataSnapshot.exists()) {
                const initialCode = dataSnapshot.val();
                codingSpace.value = initialCode;
                // 设置初始内容后光标移到末尾
                editor.setValue(initialCode, 1);
            }
        } catch (error) {
            console.error("Error fetching initial data:", error);
        }
    };
    fetchAndDisplayInitialData();

    const updateCode = (newCode) => {
        editorChangeInProgress = true;
        codingSpace.value = newCode;
        // 设置内容后光标固定在末尾
        editor.setValue(newCode, 1);
        editorChangeInProgress = false;
        // 复用已创建的editor实例调整光标
        editor.moveCursorTo(-1, -1);
    };

    const onEditorChange = (event) => {
        if (!editorChangeInProgress) {
            const newCode = editor.getValue();
            // 无需重复设置编辑器内容,直接同步到后端和codingSpace
            socket.emit("codeChange", { roomName, newCode });
            update(codeRef, { [roomName]: newCode });
            codingSpace.value = newCode;
        }
    };

    editor.getSession().on("change", onEditorChange);

    socket.on("codeChange", (newCode) => {
        if (!editorChangeInProgress) {
            updateCode(newCode);
        }
    });

    codingSpace.addEventListener("input", () => {
        const newCode = codingSpace.value;
        socket.emit("codeChange", { roomName, newCode });
        update(codeRef, { [roomName]: newCode });
        // 同步编辑器内容时标记状态,避免循环触发事件
        editorChangeInProgress = true;
        editor.setValue(newCode, 1);
        editorChangeInProgress = false;
    });
});

关键修复说明

  • 移除了DOMContentLoaded外的重复Editor初始化代码,保证只有一个Editor实例运行。
  • 修改onEditorChange逻辑:不再重复设置编辑器内容,直接将最新值同步到后端和codingSpace,避免额外触发change事件和光标错位。
  • 所有editor.setValue的第二个参数改为1,设置内容后光标自动移到末尾,彻底解决输入反转问题。
  • 统一复用已定义的editor实例,避免重新获取实例导致的状态不一致。
  • 优化codingSpace的input事件处理,同步编辑器内容时标记editorChangeInProgress,防止循环触发事件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:50:10