英文:
Thymeleaf inline JavaScript is completely ignored
问题
以下是您要翻译的代码部分:
<!doctype html>
<html th:replace="~{fragments/layout :: layout(~{::title}, ~{}, ~{}, ~{::main})}">
<head>
<title>Reports Page</title>
</head>
<body>
<main role="main" class="flex-shrink-0">
<!-- some HTML code here -->
<select class="form-select" id="year" aria-label="Year dropdown" th:onchange="reloadPage()">
<option
th:each="yearRow : ${years}"
th:value="${yearRow}"
th:selected="(${yearRow} == ${year})"
th:text="${yearRow}">
</option>
</select>
<!-- other HTML code here -->
</main>
<script th:inline="javascript" type="text/javascript">
function reloadPage() {
alert("You selected a year");
}
</script>
</body>
</html>
希望这能帮助您。如果您有其他翻译需求,请随时提出。
英文:
I'm trying to include a basic vanilla JS script into a Thymeleaf view but it seems to be completely ignored - I don't even see it when I inspect the page. I assume the issue is related with the fact that the view is part of a layout template but I cannot figure out where the problem is.
The View:
<!doctype html>
<html th:replace="~{fragments/layout :: layout(~{::title}, ~{}, ~{}, ~{::main})}">
<head>
<title>Reports Page</title>
</head>
<body>
<main role="main" class="flex-shrink-0">
<!-- some HTML code here -->
<select class="form-select" id="year" aria-label="Year dropdown" th:onchange="reloadPage()">
<option
th:each="yearRow : ${years}"
th:value="${yearRow}"
th:selected="(${yearRow} == ${year})"
th:text="${yearRow}">
</option>
</select>
<!-- other HTML code here -->
</main>
<script th:inline="javascript" type="text/javascript">
function reloadPage() {
alert("You selected a year");
}
</script>
</body>
</html>
The Layout fragment:
<!DOCTYPE html>
<html class="h-100" th:fragment="layout (title, css_assets, js_assets, content)" xmlns:th="http://www.thymeleaf.org">
<head>
<!-- Usual head stuff - meta tags, links to Bootstrap CSS & fonts libraries etc -->
<!-- Common CSS Styles -->
<link rel="stylesheet" th:href="@{/css/styles.css}">
<!-- Per-page placeholder for additional links -->
<th:block th:replace="${css_assets}" />
<title th:replace="${title}">Layout Title</title>
</head>
<body class="d-flex flex-column h-100">
<header th:replace="~{fragments/header :: header}"></header>
<div th:replace="${content}">
<p>Layout content</p>
</div>
<footer th:replace="~{fragments/footer :: footer}"></footer>
<!-- Common scripts -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<!-- Per-page placeholder for additional scripts -->
<th:block th:replace="${js_assets}" />
</body>
</html>
Inspecting the code, I don't see the inline script:
.. and in the console the Javascript function is not found:
Of course, probably I can use the ${js_assets} to inject my JS function from an external JS file but it bothers me why is it not working with the inline syntax. Am I missing something?
I'm pretty new to Spring Boot and Thymeleaf so please be understanding. Thanks!
答案1
得分: 0
以下是代码的中文翻译部分:
感谢 andrewJames,我意识到从我的视图注入到最终HTML的唯一HTML代码是在 main 标签之间包含的部分 - 其他一切不是布局中的片段都会被替换。最简单的解决办法是将内联脚本包含在 main 标签内。
但由于我想要在关闭 body 标签之前拥有它,我最终利用了我已经内建到我的页面的用于每个页面JS的占位符。
以下是视图的新代码(请注意,布局中发送的 js_assets 参数现在指向页面中的片段):
<!doctype html>
<html th:replace="~{fragments/layout :: layout(~{::title}, ~{}, ~{::js_assets}, ~{::main})}">
<head>
<title>Reports Page</title>
</head>
<body>
<main role="main" class="flex-shrink-0">
<!-- 这里有一些HTML代码 -->
<select class="form-select" id="year" aria-label="Year dropdown" th:onchange="reloadPage()">
<option
th:each="yearRow : ${years}"
th:value="${yearRow}"
th:selected="(${yearRow} == ${year})"
th:text="${yearRow}">
</option>
</select>
<!-- 这里还有其他HTML代码 -->
</main>
<th:block th:fragment="js_assets">
<script th:inline="javascript" type="text/javascript">
function reloadPage() {
alert("您选择了一年");
}
</script>
</th:block>
</body>
</html>
英文:
Thanks to andrewJames I realized that the only HTML code that gets injected from my view into the final HTML is the one included between the main tags - everything else that is not a fragment in the layout is replaced. The easiest fix would have been to include my inline script inside main.
But since I want to have it right before the closing body tag I ended up leveraging the placeholder I already built into my layout for page-by-page JS.
Here's the new code for view (notice that the parameter for js_assets sent in the layout is pointing now to the fragment in the page)
<!doctype html>
<html th:replace="~{fragments/layout :: layout(~{::title}, ~{}, ~{::js_assets}, ~{::main})}">
<head>
<title>Reports Page</title>
</head>
<body>
<main role="main" class="flex-shrink-0">
<!-- some HTML code here -->
<select class="form-select" id="year" aria-label="Year dropdown" th:onchange="reloadPage()">
<option
th:each="yearRow : ${years}"
th:value="${yearRow}"
th:selected="(${yearRow} == ${year})"
th:text="${yearRow}">
</option>
</select>
<!-- other HTML code here -->
</main>
<th:block th:fragment="js_assets">
<script th:inline="javascript" type="text/javascript">
function reloadPage() {
alert("You selected a year");
}
</script>
</th:block>
</body>
</html>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论