You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony+Turbo环境下复用Twig模板时jQuery未定义问题

问题原因

Symfony UX Turbo 基于Turbo Drive实现,它会拦截页面导航请求,仅更新页面<body>区域(以及<head>中变化的元素),不会重新执行整个页面的JavaScript代码。如果你的jQuery逻辑是直接写在页面内联<script>中,首次加载页面时能正常执行,但Turbo切换到新页面后,这些内联脚本不会自动触发,且若jQuery未在全局作用域稳定存在,就会抛出$ is not defined错误。

解决方案

1. 用Stimulus控制器封装jQuery逻辑(推荐,符合Symfony UX生态)

利用Stimulus的生命周期钩子,在Turbo切换页面后自动重新初始化逻辑:

  • 创建Stimulus控制器文件assets/controllers/jquery-init_controller.js:
import { Controller } from '@hotwired/stimulus';
import $ from 'jquery';

export default class extends Controller {
    connect() {
        // 在这里编写你的jQuery业务逻辑
        $(this.element).find('.data-table').DataTable();
        // 其他需要初始化的jQuery操作
    }
}
  • 在复用的Twig模板中绑定控制器:
<div data-controller="jquery-init">
    <!-- 页面内容,比如数据表格、交互元素等 -->
</div>

2. 绑定Turbo页面加载事件

如果需要保留内联脚本,将原$(document).ready()替换为Turbo专属的turbo:load事件,确保每次页面切换后重新执行逻辑:

<script>
document.addEventListener('turbo:load', function() {
    if (typeof $ !== 'undefined') {
        // 你的jQuery代码
        $('.target-element').tooltip();
    }
});
</script>

3. 确保jQuery全局可用

检查Webpack Encore配置,将jQuery暴露到全局作用域,避免Turbo切换后上下文丢失:
在webpack.config.js中添加:

const webpack = require('webpack');

Encore
    // ...其他已有配置
    .addPlugin(new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery'
    }))
;
排查注意事项
  • 检查基础Twig模板(如base.html.twig)中JS的加载位置:若jQuery放在<head>中,全局作用域会一直保留;若放在<body>末尾,需确保Turbo切换后不会被重复加载或丢失。
  • 确认复用模板中的内联脚本是否依赖旧页面的DOM元素:Turbo会替换整个<body>,旧页面的事件绑定会失效,必须在新页面加载后重新绑定。

内容的提问来源于stack exchange,提问作者Lissam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 13:09:58