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

如何在Monaco Editor中保留切换内容后的书签装饰?

解决Monaco Editor切换文档后书签丢失的问题

核心逻辑

给每个文档绑定独立的书签存储,切换文档前先保存当前书签状态,加载目标文档时再从存储中读取并恢复书签。

具体实现步骤

1. 定义全局书签存储对象

用对象存储各文档的书签行号,键为文档唯一标识(比如列表项ID或文档路径):

var bookmarkStore = {};

2. 同步书签操作与存储

如果是通过点击Glyph Margin添加/移除书签,在点击事件里同步更新存储:

// 假设editor是你的Monaco Editor实例
editor.on('mouseDown', function(e) {
    // 判断点击区域为Glyph Margin
    if (e.target.type === 2) {
        var lineNumber = editor.getPositionAt(e.target.position).lineNumber;
        var docId = $('.left-panel-list-item.active').data('doc-id'); // 获取当前激活的文档ID
        var lineDecorations = editor.getLineDecorations(lineNumber);
        
        // 检查该行是否已有书签
        var hasBookmark = lineDecorations.some(deco => deco.options.className === 'BookmarkGlyphMarginClass');
        
        if (hasBookmark) {
            // 移除书签并更新存储
            var removeIds = lineDecorations.filter(deco => deco.options.className === 'BookmarkGlyphMarginClass').map(deco => deco.id);
            editor.deltaDecorations(removeIds, []);
            bookmarkStore[docId] = bookmarkStore[docId].filter(line => line !== lineNumber);
        } else {
            // 添加书签并更新存储
            var decoId = editor.deltaDecorations([], [{
                range: new monaco.Range(lineNumber, 1, lineNumber, 1),
                options: { glyphMarginClassName: 'BookmarkGlyphMarginClass' }
            }]);
            if (!bookmarkStore[docId]) bookmarkStore[docId] = [];
            bookmarkStore[docId].push(lineNumber);
        }
    }
});

3. 切换文档时保存当前书签

在左栏列表项的点击事件中,先保存当前编辑器的书签,再加载新文档:

$('.left-panel-list-item').click(function() {
    // 保存当前文档的书签
    var currentDocId = $('.left-panel-list-item.active').data('doc-id');
    var currentBookmarks = editor.getLineDecorations()
        .filter(deco => deco.options.className === 'BookmarkGlyphMarginClass')
        .map(deco => deco.range.startLineNumber);
    bookmarkStore[currentDocId] = currentBookmarks;
    
    // 加载新文档
    var newDocId = $(this).data('doc-id');
    loadDocument(newDocId);
    $(this).addClass('active').siblings().removeClass('active');
});

4. 加载文档后恢复书签

在加载文档内容到编辑器的函数末尾,添加书签恢复逻辑:

function loadDocument(docId) {
    // 原有加载文档内容的逻辑
    $.get('/get-document-content?docId=' + docId, function(content) {
        editor.setValue(content);
        
        // 恢复书签
        var savedBookmarks = bookmarkStore[docId] || [];
        var decorations = savedBookmarks.map(line => ({
            range: new monaco.Range(line, 1, line, 1),
            options: { glyphMarginClassName: 'BookmarkGlyphMarginClass' }
        }));
        editor.deltaDecorations([], decorations);
    });
}

可选:持久化书签(页面刷新不丢失)

如果需要书签在页面刷新后保留,把存储同步到localStorage:

// 初始化时从localStorage读取
var bookmarkStore = JSON.parse(localStorage.getItem('monacoBookmarks')) || {};

// 定义同步函数,在书签变更、切换文档后调用
function syncBookmarksToStorage() {
    localStorage.setItem('monacoBookmarks', JSON.stringify(bookmarkStore));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:05:17