如何用JavaScript实现基于details和summary的自定义spoiler标签
问题原因
document.getElementsByTagName返回的是类数组结构HTMLCollection,没有内置map方法,直接调用会触发JS报错,导致逻辑中断。elem.attributes.summary获取到的是属性节点对象,而非属性的文本值,直接拼接会输出[object Attr]的错误内容。- 若脚本在DOM解析完成前执行,会无法获取到页面中的
<spoiler>元素,逻辑不会生效。
修复代码(基于原有逻辑最小改动)
function create_tag(tagName, fn) { // 将类数组转为真实数组后遍历 Array.from(document.getElementsByTagName(tagName)).forEach(fn); } function spoiler(elem) { // 直接用getAttribute获取属性值,写法更简洁可靠 const summaryText = elem.getAttribute('summary'); if (summaryText) { elem.innerHTML = "<details><summary>" + summaryText + "</summary>" + elem.innerHTML + "</details>"; } } // 等待DOM完全加载后再执行转换逻辑 document.addEventListener('DOMContentLoaded', function() { create_tag("spoiler", spoiler); });
可选优化方案(原生自定义元素规范实现)
如果希望实现浏览器自动解析、无需手动触发转换,可以使用W3C标准的Custom Elements API实现,注意原生自定义标签要求名称必须包含短横线:
// 注册自定义元素 class SpoilerElement extends HTMLElement { // 元素挂载到DOM时自动触发 connectedCallback() { const summaryText = this.getAttribute('summary') || 'Spoiler'; this.innerHTML = `<details><summary>${summaryText}</summary>${this.innerHTML}</details>`; } } customElements.define('custom-spoiler', SpoilerElement);
使用时直接写标签即可,无需额外触发转换:
<custom-spoiler summary="Spoiler"> Spoiler text </custom-spoiler>
内容的提问来源于stack exchange,提问作者Ritwin
相关产品推荐
相关产品推荐

