Turbo框架下Frame加载后如何重新执行指定JS文件?
解决方案
方法一:绑定Turbo事件(推荐)
Turbo提供了专门的事件用于监听页面或Frame的加载完成,你可以把JS中的初始化逻辑(比如Bootstrap Tooltip激活)绑定到这些事件上,替代原来的DOMContentLoaded或直接执行的代码。
修改你的phoenix.js:
// 封装需要重复执行的初始化逻辑 function initPhoenixFeatures() { // 激活Bootstrap Tooltip $('[data-bs-toggle="tooltip"]').tooltip(); // 其他渲染后需要执行的逻辑... } // 页面首次加载时执行 document.addEventListener('DOMContentLoaded', initPhoenixFeatures); // Turbo Frame加载完成后执行 document.addEventListener('turbo:frame-load', initPhoenixFeatures); // 可选:页面通过Turbo导航加载完成时执行 document.addEventListener('turbo:load', initPhoenixFeatures);
这样不管是首次页面加载,还是Turbo Frame更新后,初始化逻辑都会自动重新执行,无需重新加载整个JS文件。
方法二:在Frame中嵌入内联脚本(适合局部逻辑)
如果仅特定Frame需要执行专属JS,可以直接在Frame的HTML内容中添加内联脚本:
<%= turbo_frame_tag "target-frame" do %> <!-- Frame内容 --> <script> // 仅初始化当前Frame内的Tooltip $('[data-bs-toggle="tooltip"]', document.getElementById('target-frame')).tooltip(); </script> <% end %>
注意:若你的CSP配置限制了内联脚本,需要调整对应规则。
方法三:自定义脚本重载逻辑(不推荐)
Turbo本身没有turbo_reload: true这类内置选项,但可以通过自定义逻辑实现类似效果:
- 在ERB中给脚本标签添加自定义属性:
<%= javascript_include_tag "phoenix/assets/js/phoenix.js", data: { turbo_reload: true } %>
- 在全局JS中监听Frame加载事件,重新加载标记的脚本:
document.addEventListener('turbo:frame-load', function(event) { const reloadScripts = document.querySelectorAll('script[data-turbo-reload="true"]'); reloadScripts.forEach(script => { const newScript = document.createElement('script'); // 加时间戳避免缓存问题 newScript.src = script.src + '?t=' + Date.now(); newScript.dataset.turboReload = true; script.parentNode.replaceChild(newScript, script); }); });
此方法可能引发重复加载、变量冲突等问题,仅在必要时使用。
内容的提问来源于stack exchange,提问作者fguillen
相关产品推荐
相关产品推荐

