使用JavaScript/jQuery从共同父节点定位子元素 解决Moodle图标修改问题
问题解答
核心问题修复
你遇到的报错原因非常明确:
- 调用
$("#targetchild101").parents()[3]时,通过索引[3]获取到的是原生DOM对象,不是jQuery封装的对象,原生DOM没有find()方法,所以会报类型错误。 - 另外jQuery对象不能直接用
.src设置属性,需要调用attr()方法,只有原生DOM元素可以直接操作.src属性。
可选解决方法
- 快速修复原有写法:把获取到的原生DOM转成jQuery对象即可
// 把原生DOM用$()包裹转成jQuery对象,再调用find和attr方法 $($("#targetchild101").parents()[3]).find("img").attr("src", "你的新图标地址");
- 更稳妥的jQuery写法,不用转对象:用
eq()方法获取指定索引的父元素,返回的依然是jQuery对象
$("#targetchild101").parents().eq(3).find("img").attr("src", "你的新图标地址");
- 最推荐的写法,不依赖固定层级:用
closest()直接向上匹配最近的活动容器节点,避免Moodle渲染结构变化导致层数不匹配失效
$("#targetchild101").closest("li.activity").find("img.activityicon").attr("src", "你的新图标地址");
附加问题解答
1. 更合理的锚点获取方式
完全不需要额外创建带id的span标签,有两种更简便的方案:
- 直接用Moodle自带的活动唯一id:每个Moodle活动模块的li标签都有唯一id,比如你示例中的
module-1083815,直接选择即可,不需要任何锚点:
$("#module-1083815 img.activityicon").attr("src", "你的新图标地址");
- 用当前脚本本身作为锚点:你可以直接用原生API
document.currentScript获取当前正在执行的script标签的DOM元素,完全不需要额外插入节点:
const currentScript = document.currentScript; $(currentScript).closest("li.activity").find("img.activityicon").attr("src", "你的新图标地址");
2. 类似$(document).current的功能
你需要的就是原生DOM API document.currentScript,它会返回当前正在执行的script元素的引用,完全可以替代你自己插入的span锚点,性能和可维护性都更高。
额外注意事项
建议把所有DOM操作代码包裹在jQuery的DOM就绪回调中,避免脚本加载完成时目标DOM还没渲染导致选择失效:
$(function() { // 这里放你的所有DOM操作代码 });
内容的提问来源于stack exchange,提问作者Famondir
相关产品推荐
相关产品推荐

