如何将Spring Controller的字符串列表传递给JavaScript实现点击切换题目
解决方案
现有代码快速修正
你当前代码不生效的核心原因是Thymeleaf默认不会解析普通script标签内的变量表达式,需要开启JavaScript内联配置,操作如下:
- 修改页面中存储questionText的script标签,添加
th:inline="javascript"属性,Thymeleaf会自动将Java List转换为合法的JS数组,同时自动处理特殊字符转义:
<script th:inline="javascript"> // 注释内的默认值是为了本地静态打开HTML页面时不会报错 var questionText = /*[[${questionText}]]*/ []; </script>
- 补充JS边界判断逻辑,避免数组越界出现undefined:
var i = 0; function myFunction() { const textEl = document.getElementById("thetext"); // 已经到最后一题时可根据需求调整逻辑,比如回到第一题/禁用按钮 if (i >= questionText.length) { textEl.innerHTML = "所有题目已完成!"; document.getElementById("startButton").disabled = true; return; } textEl.innerHTML = questionText[i]; i++; }
其他可行实现方案
方案1:自定义属性存储数据
不需要写内联script,所有JS逻辑可统一放到外部文件,更符合前端规范:
- 在HTML任意元素上通过
data-*属性存储序列化后的题目列表:
<div class="container mx-auto" id="questionContainer" th:data-questions="${#json.serialize(questionText)}"> <!-- 原有页面内容 --> </div>
- 外部JS中读取属性并解析为数组:
const questionContainer = document.getElementById('questionContainer'); const questionText = JSON.parse(questionContainer.dataset.questions); // 后续逻辑保持不变
方案2:异步接口动态获取
适合题目量较大、需要动态更新题目的场景,避免初始页面体积过大:
- 后端新增REST接口返回题目列表:
@GetMapping("/api/questions") @ResponseBody public List<String> getQuestionList() { List<Question> questions = frageRepository.findAllQuestions(); return questions.stream().map(Frage::getText).toList(); }
- 前端异步请求获取数据:
var questionText = []; var i = 0; // 页面加载完成后请求题目列表 window.onload = async () => { const res = await fetch('/api/questions'); questionText = await res.json(); } function myFunction() { // 原有逻辑保持不变 }
内容的提问来源于stack exchange,提问作者CT11
相关产品推荐
相关产品推荐

