diff --git a/src/layout/components/footer.vue b/src/layout/components/footer.vue index eb6aa8d..f39cc5c 100644 --- a/src/layout/components/footer.vue +++ b/src/layout/components/footer.vue @@ -54,6 +54,7 @@ const store = useStore(); const footerSlogan = computed(() => decodeURIComponent(config.nazhua?.footerSlogan || '')); const dynamicContentRef = ref(); +const executedScripts = ref(new Set()); // 记录已执行的脚本,避免重复执行 const dynamicContent = computed(() => { if (store.state.setting?.config?.custom_code) { @@ -69,24 +70,69 @@ const dynamicContent = computed(() => { const executeScripts = () => { nextTick(() => { if (!dynamicContentRef.value) return; + const scripts = dynamicContentRef.value.querySelectorAll('script'); + scripts.forEach((script) => { - const newScript = document.createElement('script'); - newScript.type = 'text/javascript'; - if (script.src) { - newScript.src = script.src; // 拷贝外部脚本的 src - } else { - newScript.textContent = script.textContent; // 拷贝内联脚本 + try { + // 生成脚本唯一标识,避免重复执行 + const scriptIdentifier = script.src || script.textContent || ''; + if (!scriptIdentifier || executedScripts.value.has(scriptIdentifier)) { + return; + } + + const newScript = document.createElement('script'); + newScript.type = script.type || 'text/javascript'; + + // 复制所有相关属性 + if (script.async !== undefined) newScript.async = script.async; + if (script.defer !== undefined) newScript.defer = script.defer; + if (script.crossOrigin) newScript.crossOrigin = script.crossOrigin; + if (script.integrity) newScript.integrity = script.integrity; + if (script.noModule !== undefined) newScript.noModule = script.noModule; + if (script.referrerPolicy) newScript.referrerPolicy = script.referrerPolicy; + + if (script.src) { + // 外部脚本:监听加载完成事件 + newScript.src = script.src; + newScript.onload = () => { + executedScripts.value.add(scriptIdentifier); + }; + newScript.onerror = (error) => { + console.error('Failed to load external script:', script.src, error); + }; + document.body.appendChild(newScript); + } else { + // 内联脚本:直接执行 + newScript.textContent = script.textContent; + document.body.appendChild(newScript); + executedScripts.value.add(scriptIdentifier); + // 内联脚本执行后可以安全移除 + document.body.removeChild(newScript); + } + } catch (error) { + console.error('Error executing dynamic script:', error); } - document.body.appendChild(newScript); - document.body.removeChild(newScript); // 可选:移除以保持整洁 }); }); }; -watch(dynamicContent, () => { - if (dynamicContent.value) { - executeScripts(); +// 清理已执行脚本的记录(当内容变化时) +const cleanupScripts = () => { + executedScripts.value.clear(); +}; + +watch(dynamicContent, (newVal, oldVal) => { + // 内容变化时,清理旧的执行记录 + if (newVal !== oldVal) { + cleanupScripts(); + } + + if (newVal) { + // 确保 DOM 已更新 + nextTick(() => { + executeScripts(); + }); } });