开发Wikidata小工具:如何等待Wikibase编辑链接加载完成?
解决Wikidata小工具等待编辑链接加载完成的问题
嘿,这个坑我之前踩过!Wikidata的前端加载逻辑确实有点“分层”,光等wikibase.view.ViewFactoryFactory模块加载完根本不够——这个模块只是负责创建视图工厂的工具,实际的语句编辑链接、工具栏这些控件,是在实体视图动态渲染的过程中才生成的,所以你的代码会跑在它们初始化之前。
下面给你两个靠谱的解决方案,按需选择:
方案一:利用Wikibase官方钩子(推荐)
Wikibase在实体页面加载完成后会触发特定的钩子事件,我们可以监听这些钩子来确保所有编辑控件都已就绪。最靠谱的是wikibase.entityPage.entityViewReady,它会在实体视图完全渲染(包括所有编辑按钮、工具栏)后触发。
具体代码示例:
mw.loader.using([ 'wikibase.entityPage', 'wikibase.view.EntityView' ]).then(function() { // 监听实体视图就绪的钩子 mw.hook('wikibase.entityPage.entityViewReady').add(function(entityView) { // 现在可以放心操作所有编辑链接了 const editButtons = document.querySelectorAll('.wikibase-statementgroupview .wikibase-toolbar-button-edit'); editButtons.forEach(button => { // 这里写你的业务逻辑,比如给按钮加自定义监听 button.addEventListener('click', function(e) { console.log('触发自定义编辑逻辑:', this.dataset); }); }); }); });
这个方案的优势是完全贴合Wikibase的官方加载流程,不会出现“误判元素是否存在”的情况,稳定性最高。
方案二:用MutationObserver监听DOM变化(通用 fallback)
如果因为某些版本差异,官方钩子不好用,还可以用DOM变化监听的方式,直接等编辑链接元素出现在页面中再执行代码:
mw.loader.using('wikibase.view.ViewFactoryFactory').then(function() { // 定义目标元素的选择器:语句旁的编辑按钮 const targetEditButton = '.wikibase-statementgroupview .wikibase-toolbar-button-edit'; // 检查元素是否已存在,存在则执行逻辑 function executeWhenReady() { const buttons = document.querySelectorAll(targetEditButton); if (buttons.length > 0) { // 你的业务逻辑 buttons.forEach(btn => { console.log('编辑按钮已就绪:', btn); }); return true; } return false; } // 先做一次即时检查 if (executeWhenReady()) return; // 如果元素还没出现,监听实体内容区域的DOM变化 const entityContent = document.querySelector('.wikibase-entityview-content'); if (entityContent) { const observer = new MutationObserver(function() { if (executeWhenReady()) { observer.disconnect(); // 完成后停止监听,避免性能浪费 } }); observer.observe(entityContent, { childList: true, subtree: true }); } });
这个方法更通用,不管Wikibase的钩子有没有触发,只要元素出现在页面里,代码就会执行,适合兼容性要求较高的场景。
总结一下:优先用方案一的官方钩子,它是最贴合Wikibase加载逻辑的方式;如果钩子不生效,再用方案二的DOM监听兜底。
内容的提问来源于stack exchange,提问作者Yuri Astrakhan
相关产品推荐
相关产品推荐

