CodeMirror触发change事件时如何获取其所在父div元素的ID
问题描述
现有多个div元素,每个div中都包含一个CodeMirror编辑器实例,需要在内部CodeMirror内容发生变更时,获取对应父级div的ID属性。目前已通过jQuery完成CodeMirror初始化并绑定change事件,可正常获取编辑器输入内容,但不清楚如何在change事件回调中获取对应父元素的ID,相关代码如下:
原有JS逻辑
$(document).ready(function(){ $(".code").each(function (i, editorEl) { CodeMirror.fromTextArea(editorEl, { lineNumbers: true, mode: "xml" }).on("change", function(editorEl) { //console.log(editorEl.getValue());// 这行可以正常获取编辑器内容 console.log("HOW I GET THE PARENT ELEMENT ID HERE"); }); }); });
对应HTML结构
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.js"></script> <div id="poo"><textarea class="code" mode="text/html"></textarea></div> <div id="foo"><textarea class="code" mode="text/html"></textarea></div> <div id="boo"><textarea class="code" mode="text/html"></textarea></div> <!-- 更多同结构编辑器容器 --> <div id="nnn"><textarea class="code" mode="text/html"></textarea></div>
实现方法
核心是利用each循环的闭包特性,初始化编辑器时就提前缓存当前编辑器对应的父容器ID,不需要在change事件触发时再做复杂的DOM关联查找,性能更好也不会出现匹配错误。
原有代码存在两个容易踩坑的点:
- change回调的入参是CodeMirror实例对象,和外层each循环拿到的textarea DOM元素重名,会造成变量覆盖、逻辑混淆
- 没有利用遍历阶段的元素上下文缓存关联关系,平白增加后续事件触发时的DOM查找成本
修正后的可运行代码:
$(document).ready(function(){ $(".code").each(function (i, textareaEl) { // 初始化阶段直接获取当前textarea的父div ID,缓存到闭包中 const parentContainerId = $(textareaEl).parent().attr('id'); const editorInstance = CodeMirror.fromTextArea(textareaEl, { lineNumbers: true, mode: "xml" }); editorInstance.on("change", function(cm) { // 正常获取编辑器输入内容 const content = cm.getValue(); // 直接读取缓存好的父容器ID即可 console.log('当前编辑器父容器ID:', parentContainerId); }); }); });
如果存在初始化后编辑器父容器可能变动的特殊场景,不适合提前缓存ID,也可以在change回调内通过CodeMirror自带的API获取实例DOM,再向上查找父元素:
editorInstance.on("change", function(cm) { // getWrapperElement() 返回CodeMirror渲染生成的最外层包裹DOM节点 const parentContainerId = $(cm.getWrapperElement()).parent().attr('id'); console.log('当前编辑器父容器ID:', parentContainerId); });
这种写法效果和缓存方案一致,但每次内容变更都会触发DOM查询,性能略差,按需选择即可。
内容的提问来源于stack exchange,提问作者Bakyto
相关产品推荐
相关产品推荐

