跳转至内容
  • 最新
  • 版块
  • 标签
  • 热门
  • 用户
  • 群组
  • 太微中文教程
  • 新插件投票看板
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(不使用皮肤)
  • 不使用皮肤
折叠
太微中文论坛icon

太微中文论坛

  1. 首页信息流
  2. 版块
  3. 讨论
  4. codemirror6插件为什么不能选中文本一直拉下来删除

codemirror6插件为什么不能选中文本一直拉下来删除

已定时 已固定 已锁定 已移动 已解决 讨论
11 帖子 3 发布者 145 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • 机杼机 离线
    机杼机 离线
    机杼
    写于 最后由 编辑
    #2

    现在问题变得复杂了。因为插件官网那边复现不出来。我这边也检查了各个插件,检查了一晚上也没检查出来。

    目前问题是,使用codemirror6插件,只有屏幕尺寸在移动端大小的时候可以往下拉,而超过屏幕尺寸的就无法往下拉。但如果转换成默认编辑器,则同样是可以往下拉的。如果使用之前的codemirror5插件,也是可以往下拉的。

    我检查了各种问题,但最终似乎还是codemirror6插件的问题。但我卸载了重新安装一遍,仍然会有这个问题。但我在插件官网那边却一直复现不出来。

    比较离谱。

    1 条回复 最后回复
    0
    • 机杼机 离线
      机杼机 离线
      机杼
      写于 最后由 编辑
      #3

      下次开腾讯会议的时候可以演示一下。我这边还是能够稳定复现的。

      1 条回复 最后回复
      0
      • WhiteFallW 离线
        WhiteFallW 离线
        WhiteFall
        写于 最后由 WhiteFall 编辑
        #4

        当你在一个内容超出编辑器大小的区域中复制内容时,浏览器会自动处理滚动和复制操作。以下是这一过程中可能调用的 API 和机制:


        一、复制操作触发的滚动机制

        1. Selection API

          • 当你用鼠标或键盘选择内容时,浏览器会调用 Selection API 来管理选中范围。
          • 如果选中范围超出当前视口,浏览器会自动滚动以确保选中内容可见。
          • 相关 API:
            • window.getSelection():获取当前选中范围。
            • Range 对象:表示选中的文本范围。
            • range.selectNodeContents():选择某个节点的内容。
        2. Scroll APIs

          • 当选中范围超出编辑器视口时,浏览器会调用 scrollIntoView() 或 scrollTo() 方法,将选中内容滚动到可见区域。
          • 示例:
            const range = document.createRange();
            range.selectNodeContents(document.getElementById('editor'));
            const selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange(range);
            // 浏览器会自动滚动到选中范围
            range.startContainer.parentElement.scrollIntoView({ behavior: 'auto', block: 'nearest' });
            
        3. Clipboard API

          • 当你按下 Ctrl+C(或右键复制)时,浏览器会调用 Clipboard API 将选中内容复制到剪贴板。
          • 相关 API:
            • navigator.clipboard.writeText():异步写入文本到剪贴板。
            • document.execCommand('copy'):传统方法,同步复制内容。

        二、具体流程

        1. 用户选择内容:

          • 使用鼠标拖动选择或键盘(Shift+方向键)选择内容。
          • 浏览器通过 Selection API 管理选中范围。
        2. 自动滚动:

          • 如果选中范围超出编辑器视口,浏览器调用 scrollIntoView() 或 scrollTo() 将选中内容滚动到可见区域。
          • 这是浏览器内置行为,无需开发者额外干预。
        3. 复制内容:

          • 按下 Ctrl+C 或右键复制时,浏览器调用 Clipboard API 将选中内容复制到剪贴板。
          • 如果使用 document.execCommand('copy'),浏览器会同步执行复制操作。

        三、代码示例

        以下是一个模拟编辑器复制滚动行为的代码示例:

        // 获取编辑器元素
        const editor = document.getElementById('editor');
        
        // 创建一个 Range 对象
        const range = document.createRange();
        range.selectNodeContents(editor); // 选择编辑器的全部内容
        
        // 获取 Selection 对象
        const selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range); // 将 Range 添加到 Selection
        
        // 浏览器会自动滚动到选中范围
        range.startContainer.parentElement.scrollIntoView({ behavior: 'auto', block: 'nearest' });
        
        // 复制内容到剪贴板
        document.addEventListener('copy', (e) => {
          e.clipboardData.setData('text/plain', selection.toString());
          e.preventDefault();
        });
        document.execCommand('copy'); // 触发复制操作
        

        四、注意事项

        1. 浏览器兼容性:

          • Clipboard API 是现代浏览器的特性,旧版浏览器可能仅支持 document.execCommand('copy')。
          • scrollIntoView() 的 behavior 参数(如 smooth)在某些浏览器中可能不支持。
        2. 用户手势要求:

          • 复制操作(如 execCommand('copy'))必须由用户手势(如点击或按键)触发,否则会被浏览器阻止。
        3. 性能问题:

          • 如果编辑器内容非常大,频繁滚动和复制可能影响性能,建议优化选中范围或分块处理。

        总结

        在编辑器中复制超出视口的内容时,浏览器主要调用以下 API:

        1. Selection API:管理选中范围。
        2. Scroll APIs:自动滚动到选中内容。
        3. Clipboard API:将选中内容复制到剪贴板。

        这些操作是浏览器内置行为,开发者可以通过 JavaScript 模拟或扩展这些功能。

        1 条回复 最后回复
        0
        • WhiteFallW 离线
          WhiteFallW 离线
          WhiteFall
          写于 最后由 WhiteFall 编辑
          #5

          面对这种复杂且难以复现的问题,确实令人头疼。不过我们可以通过以下步骤系统性地排查和解决。根据你的描述,问题可能与 CodeMirror 6 的响应式设计、CSS 冲突或特定配置 相关,以下是详细分析和解决方案:


          问题定位思路

          1. 排除其他插件干扰

            • 在浏览器中开启「无痕模式」或禁用所有其他扩展,仅保留 CodeMirror 6 相关代码,测试是否问题依旧。
            • 如果问题消失,可能是其他插件(如广告拦截器、CSS 注入工具)干扰了 CodeMirror 6 的滚动行为。
          2. 检查 CSS 样式冲突

            • CodeMirror 6 高度依赖 CSS 控制滚动容器。使用浏览器开发者工具的 元素检查器,重点关注:
              • CodeMirror 容器的 height、max-height、overflow 属性。
              • 是否存在全局 CSS 规则(如 * { overflow: hidden; })意外覆盖了 CodeMirror 的样式。
              • 移动端和大屏模式下,容器尺寸的计算方式是否不同(如百分比 vs 固定值)。
          3. CodeMirror 6 的配置差异

            • CodeMirror 6 的配置与 CodeMirror 5 有显著差异,检查以下关键配置:
              // 示例配置项
              new EditorView({
                extensions: [
                  // 确保启用垂直滚动
                  EditorView.scrollMargins.of({ bottom: 100 }), // 滚动边距
                  EditorView.contentAttributes.of({ style: "overflow-y: auto" }), // 显式设置滚动
                ],
                // 确保父容器高度有效
                parent: document.getElementById("editor-container")
              });
              
            • 特别注意 viewportMargin 参数(控制视口外预渲染内容的高度),如果设置过小可能导致滚动异常。
          4. 动态尺寸监听问题

            • CodeMirror 6 依赖浏览器 ResizeObserver 监听容器尺寸变化。如果容器尺寸是通过 JavaScript 动态计算的(而非 CSS 响应式),可能需要手动触发更新:
              // 强制刷新编辑器布局
              const view = new EditorView({ /* ... */ });
              view.requestMeasure();
              
          5. 浏览器控制台报错

            • 打开浏览器控制台(F12),检查是否有以下错误:
              • CodeMirror 初始化失败(如未正确引入依赖)。
              • CSS 文件加载失败或语法错误。
              • ResizeObserver 相关错误(如循环布局更新)。

          针对性解决方案

          1. 强制设置滚动容器样式

          如果 CodeMirror 6 的滚动容器(通常是 .cm-scroller 类)未正确应用样式,可手动覆盖:

          /* 确保滚动容器允许垂直滚动 */
          .cm-scroller {
            overflow-y: auto !important;
            height: 100% !important;
          }
          
          /* 父容器必须有明确的高度 */
          #editor-container {
            height: 600px; /* 或根据业务动态设置 */
            max-height: 100vh;
          }
          

          2. 检查动态高度计算

          如果编辑器高度依赖父容器动态计算(如通过 JavaScript),需确保父容器尺寸变化时同步更新 CodeMirror:

          // 示例:监听窗口大小变化
          window.addEventListener("resize", () => {
            const container = document.getElementById("editor-container");
            container.style.height = `${window.innerHeight - 100}px`;
            // 通知 CodeMirror 更新布局
            if (view) view.requestMeasure();
          });
          

          3. 对比 CodeMirror 5 和 6 的初始化逻辑

          CodeMirror 6 的 API 设计更模块化,检查是否缺少必要的扩展(如 scrollPastEnd):

          import { EditorView } from "@codemirror/view";
          import { EditorState } from "@codemirror/state";
          
          // 确保添加滚动相关扩展
          const extensions = [
            EditorView.scrollMargins.of({ bottom: 200 }), // 允许滚动到内容末尾后继续滚动一段距离
            EditorState.readOnly.of(false) // 确保编辑器非只读
          ];
          
          const view = new EditorView({
            state: EditorState.create({ extensions }),
            parent: document.getElementById("editor-container")
          });
          

          4. 最小化复现环境

          创建一个仅包含 CodeMirror 6 的最简 HTML 文件,逐步添加业务代码,直到问题复现。例如:

          <!DOCTYPE html>
          <html>
          <head>
            <meta charset="utf-8">
            <!-- 引入 CodeMirror 6 基础样式 -->
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.0.1/codemirror.min.css">
            <style>
              #editor-container { height: 400px; border: 1px solid #ccc; }
            </style>
          </head>
          <body>
            <div id="editor-container"></div>
          
            <script type="module">
              import { EditorView } from "https://cdn.skypack.dev/@codemirror/view";
              import { EditorState } from "https://cdn.skypack.dev/@codemirror/state";
          
              const view = new EditorView({
                state: EditorState.create({ doc: "Test content\n".repeat(100) }),
                parent: document.getElementById("editor-container")
              });
            </script>
          </body>
          </html>
          

          如果此代码正常,则问题出在项目特定配置中。


          终极排查策略

          1. 对比 CodeMirror 官网配置
            访问 CodeMirror 6 官方示例,检查其 HTML/CSS/JS 与你的项目差异,尤其是:

            • 引入的 CSS 文件顺序。
            • 是否使用 <!DOCTYPE html> 声明(影响布局模式)。
            • 是否缺少 height: 100% 或 flex 布局支持。
          2. 检查打包工具影响
            如果使用 Webpack/Vite 等工具,可能是 Tree Shaking 移除了关键模块。尝试:

            • 显式引入所有依赖:
              import { EditorView, keymap, lineNumbers } from "@codemirror/view";
              
            • 禁用代码压缩,检查是否有运行时错误。
          3. 联系 CodeMirror 社区
            如果问题仍无法解决,可在 CodeMirror GitHub Issues 中提交详细复现步骤,包括:

            • 浏览器版本、操作系统。
            • 最小化复现代码。
            • 屏幕尺寸阈值(如 768px 以上失效)。

          总结

          问题可能根源:

          • CSS 样式冲突:CodeMirror 6 的滚动容器样式被意外覆盖。
          • 动态尺寸计算缺陷:父容器高度未正确同步到编辑器。
          • 缺失关键扩展:未启用滚动相关模块(如 scrollPastEnd)。
          • 打包工具干扰:关键代码被优化或未正确引入。

          通过逐步隔离环境、对比官方示例、最小化复现,可以最终定位到具体原因。如果时间紧迫,可暂时回退到 CodeMirror 5,同时持续跟踪 CodeMirror 6 的更新。

          1 条回复 最后回复
          0
          • 机杼机 离线
            机杼机 离线
            机杼
            写于 最后由 编辑
            #6

            今天发现了另一个相关的问题,那就是在我既装了codemirror5,又装了codemirror6插件之后,当我使用codemirror5插件时,我发现即使我设置了内容超过屏幕时换行,也仍然会出现无法换行的情况。

            我感觉就是这种不换行的情况,影响了插件。

            而原因可能源自于我使用了下面的代码来进行一个全局代码可重复的样式。

            .copy-code{
                font-family: Consolas;
            }.copy-code dt{
                background: #f5f5f5;
                border: solid 1px #cccccc;
                border-bottom:unset;
                padding: 0.5em;
                border-radius: 3px 3px 0 0;
                font-size: 1.1em;
            }.copy-code dt:empty, .copy-code dd small.hide{
                display: none;
            }.copy-code dd{
                margin: 0;
            }.copy-code dd>pre{
                border-radius: 3px;
                background-color:#f8f8f8;
                height: inherit;
                overflow-y: auto;
            }.copy-code dt:not(:empty)+dd>pre{
                border-radius: 0 0 3px 3px;
                margin-top: 0em;
            }.copy-code dd{
                position: relative;
                display: block;
            }.copy-code dd :is(button, small) {
                position: absolute;
                opacity: 0.3;
                padding: 5px;
            }.copy-code dd button:hover{
                transition: opacity 150ms ease-in-out;
                opacity: 1;
            }.copy-code dd button {
                font-size: 0;
                right:0;
                display: flex;
                align-items:flex-start;
                justify-content:flex-end;
                pointer-events:none;
            }.copy-code dd button svg {
                width: 20px;
                height: auto;
                pointer-events:all;
            }.copy-code dd small {
                inset: auto 0 0 auto;
                text-transform: uppercase;
                font-weight: bold;
                font-size: 1em;
            }
            

            现在我感觉上面的代码可能有问题。

            1 条回复 最后回复
            0
            • 机杼机 离线
              机杼机 离线
              机杼
              写于 最后由 编辑
              #7

              是我犯蠢了。之前找codemirror6插件的bug时,我关闭了代码区换行。现在重新打开就可以解决了。但codemirror6的bug我感觉还是没解决。

              1 条回复 最后回复
              0
              • 机杼机 离线
                机杼机 离线
                机杼
                写于 最后由 编辑
                #8

                https://github.com/oeyoews/tiddlywiki-codemirror6/discussions/151

                问题己解决,是下面条目的影响,插件不知道为什么被我设置成这样了。默认安装是没有影响的。

                title: $:/themes/tiddlywiki/vanilla/metrics/storytop
                
                {{$:/plugins/inmysocks/iconmenus/icon_menu_settings!!top_bar_height}}
                

                排查方法很简单,也很原始。就是顺着git commit去找。

                d18926f9-2e96-4e3c-8eae-b5ec13d862a9-image.png

                59348c43-ac85-4fbc-a161-593903c29600-image.png

                首先找到一个没有这种问题的git commit,然后再找离这最近有问题git commit。我是先找了最近一个月的,然后找了六个月前的,再找了五个月前的,再找了四个月前的。总之忙了一下午,终于是找到了有问题的git commit,然后就去查是什么提交出现了问题。

                当然这种办法也有不利因素,那就是有一些文件不会被git追踪,具体可参考 .gitignore文件夹。当然这需要一些git知识。

                GitHub desktop,没有直接显示太多信息,再加上是英文的。所以后面我就用vscode的源代码管理插件进行查看。

                b9880882-337c-42f8-9d2f-c6943dfc360c-image.png

                经验教训

                • 对插件要足够熟悉,修改了什么插件内容要记录
                • git提交推送时,尽量写些辅助信息
                • 耐心排查问题
                1 条回复 最后回复
                👍
                1
                • 机杼机 机杼 将这个主题标记为已解决,在
                • oeyoewsO 离线
                  oeyoewsO 离线
                  oeyoews
                  写于 最后由 编辑
                  #9

                  今天发现全屏模式下滚动确实失效了,修了一版

                  1 条回复 最后回复
                  0
                  • oeyoewsO 离线
                    oeyoewsO 离线
                    oeyoews
                    写于 最后由 编辑
                    #10

                    顺便加上了根据tiddler标题生成文章的功能,暂时用的是智谱的ai. 需要在cm6设置里配置apikey,输入@cmd:ai 就可以生成文章了

                    1 条回复 最后回复
                    0
                    • oeyoewsO 离线
                      oeyoewsO 离线
                      oeyoews
                      写于 最后由 编辑
                      #11

                      https://github.com/oeyoews/tiddlywiki-codemirror6/pull/154#issuecomment-2954938423

                      屏幕录制 2025-06-09 153116.mp4

                      1 条回复 最后回复
                      0

                      • 登录

                      • 没有帐号? 注册

                      • 登录或注册以进行搜索。
                      Powered by NodeBB Contributors
                      • 第一个帖子
                        最后一个帖子
                      0
                      • 最新
                      • 版块
                      • 标签
                      • 热门
                      • 用户
                      • 群组
                      • 太微中文教程
                      • 新插件投票看板