PyScript动态REPL代码块:如何获取激活块及提取内部代码?
解决PyScript REPL代码块激活状态判断与代码提取问题
一、确定当前激活的REPL代码块
- 基于
cm-activeLine类定位
每次操作前,通过DOM查询找到带有cm-activeLine的行元素,再向上追溯到对应的REPL代码块容器(需根据PyScript REPL实际的容器类名调整,比如常见的pyscript-repl):
// 获取当前激活行所属的REPL容器 const activeReplBlock = document.querySelector('.cm-activeLine').closest('.pyscript-repl');
- 绑定激活事件记录(更可靠)
给每个动态创建的REPL代码块绑定focus事件,实时记录当前激活的代码块:
// 假设动态创建REPL时,每个容器都有自定义标识比如data-repl-id document.querySelectorAll('.pyscript-repl').forEach(repl => { repl.addEventListener('focus', () => { // 用全局变量记录当前激活的REPL window.currentActiveRepl = repl; }); });
二、提取编辑器内的代码
PyScript REPL基于CodeMirror实现,有两种提取方式:
- 通过CodeMirror实例获取(推荐)
CodeMirror提供实例查询方法,找到对应REPL的编辑器实例后调用getValue()获取完整代码:
// 从REPL容器中找到对应的文本区域或编辑器根元素 const editorElement = activeReplBlock.querySelector('textarea, .cm-editor'); const editor = CodeMirror.findInstance(editorElement); const code = editor.getValue();
- 直接从DOM元素提取(备用)
如果无法获取CodeMirror实例,可直接读取编辑器内容区域的文本:
const contentLines = activeReplBlock.querySelectorAll('.cm-line'); const code = Array.from(contentLines).map(line => line.textContent).join('\n');
三、调整代码块顺序的实现步骤
- 获取当前激活的代码块和目标交换代码块(比如通过按钮点击事件获取目标)
- 分别提取两个代码块的代码(使用上述方法)
- 将代码互相写入对方的编辑器:
- 若能拿到编辑器实例,用
setValue()写入:// 假设targetEditor是目标代码块的编辑器实例,activeCode是激活代码块的代码 targetEditor.setValue(activeCode); activeEditor.setValue(targetCode); - 若用DOM方式,清空目标内容后插入新行:
// 清空目标代码块内容 targetReplBlock.querySelector('.cm-content').innerHTML = ''; // 插入新代码行 activeCode.split('\n').forEach(lineText => { const line = document.createElement('div'); line.className = 'cm-line'; line.textContent = lineText; targetReplBlock.querySelector('.cm-content').appendChild(line); });
- 若能拿到编辑器实例,用
- 调整DOM中代码块的位置,比如用
insertBefore交换两个容器的顺序:
// 假设parent是所有REPL代码块的父容器 const parent = activeReplBlock.parentElement; const targetReplBlock = document.querySelector('.target-repl'); // 交换位置 parent.insertBefore(activeReplBlock, targetReplBlock.nextSibling);
内容的提问来源于stack exchange,提问作者Jamshaid Tariq
相关产品推荐
相关产品推荐

