Drupal - Yoast SEO片段预览无法渲染:原生DOM元素上出现TypeError:“attr不是一个函数”
我在一个Drupal 11站点上使用 Yoast SEO模块(drupal/yoast_seo 2.2.0)。实时SEO字段小部件在表单显示上有两个可选设置:“启用标题编辑”和“启用描述编辑”,本应允许编辑者直接在节点编辑表单的“片段预览”框内覆盖元标题/描述。
在启用任一设置后(Structure → Content types → [type] → Manage form display → widget settings for the Yoast SEO field),节点编辑表单的“片段预览”区域只渲染了标签,下面却一无所有——没有可编辑的标题、没有URL、没有元描述。紧挨着它的“内容分析”区域仍然正常工作并能实时更新。
在编辑节点时打开浏览器控制台会显示:
TypeError: snippetTitle.attr is not a function
(或针对 snippetMeta 的等效输出,取决于启用的是哪个设置)
复现步骤:
- 在任意内容类型的Yoast SEO字段小部件上启用“启用标题编辑”和/或“启用描述编辑”。
- 编辑该类型的一个节点。
- 展开“Real-time SEO”详细信息元素。
- 观察:包含“Snippet preview”的标签显示,但实际的片段/可编辑区域是空白。
- 检查浏览器控制台:
TypeError。
我发现:
在模块的 js/yoast_seo.js 中,函数 Orchestrator.prototype.updatePreview 使用原生DOM API构建片段预览:
const snippetTitle = document.createElement('span');
...
if (this.config.enable_editing.title) {
snippetTitle.classList.add("editable");
snippetTitle.attr('contenteditable', 'true'); // <-- bug
}
snippetTitle 这里是一个原生的 HTMLElement(通过 document.createElement 创建),不是jQuery对象——所以 .attr() 不存在于它上面。那是一个jQuery方法,不是DOM方法。相同的模式在更下方的 snippetMeta(描述元素)处也重复。
因为这在函数执行到实际把预览插入到页面的那一行之前就抛出异常(document.getElementById(this.config.targets.snippet).replaceChildren(previewSnippet)),所以整个片段预览会悄悄无法渲染——但只有在启用编辑时才会出现,这也是在正常测试中容易被忽视的原因。
解决方案
问题在于对纯DOM元素调用.attr()(这是jQuery的方法)。请将js/yoast_seo.js中的两处代码行替换
// Change this --> (both occurrences) -->
snippetTitle.attr('contenteditable', 'true');
snippetMeta.attr('contenteditable', 'true');
// To this -->
snippetTitle.setAttribute('contenteditable', 'true');
snippetMeta.setAttribute('contenteditable', 'true');
然后创建一个composer patch,使修复在模块更新中仍然有效,并运行drush cr来清空JS缓存。