登录时Toast提示不显示问题:TypeError读取null的classList
问题根源
登录时调用showToast时,Toast的DOM结构还未加载完成,导致getElementById("liveToast")和getElementById("toastBody")返回null,进而触发TypeError: Cannot read properties of null (reading 'classList')错误。
核心原因:
- 你通过jQuery的
$("#alert").load("/staticHtml/toast.html")异步加载Toast的DOM,这个操作不会阻塞后续代码执行 - 登录逻辑绑定在
DOMContentLoaded事件中,该事件触发时,异步加载toast.html的请求可能还未完成,Toast元素还未插入到页面中 - 退出登录时,页面已经完全加载完成,
toast.html早已加载完毕,所以调用showToast能正常找到元素
解决方案
方案1:将登录逻辑放到Toast加载完成的回调中
修改load方法,添加回调函数,确保Toast DOM加载完成后再执行登录相关逻辑:
<script> $("#alert").load("/staticHtml/toast.html", function() { // Toast加载完成后触发自定义事件 document.dispatchEvent(new CustomEvent('toastReady')); }); </script> <script> // 监听Toast加载完成事件,再执行登录逻辑 document.addEventListener('toastReady', async () => { try { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const token = urlParams.get("token"); if (token) { const id = urlParams.get("id"); const username = urlParams.get("username"); let params = { _id: id, username, token, }; showToast("text-bg-success", `${username}, you have successfully signed in! Check out your <a href="/profile/${username}">profile</a>!`); localStorage.setItem("user", JSON.stringify(params)); } } catch (err) { console.log(err) showToast("text-bg-danger", "Something went wrong"); } }); </script>
方案2:内嵌Toast DOM到页面中
直接将toast.html的内容内嵌到页面的#alert容器中,避免异步加载的时序问题:
<div id="alert"> <div class="toast-container position-fixed bottom-0 end-0 p-3"> <div id="liveToast" class="toast align-items-center" role="alert" aria-live="assertive" aria-atomic="true"> <div class="d-flex"> <div class="toast-body" id="toastBody">Hello, world! This is a toast message.</div> <i class="fa fa-times me-2 m-auto" data-bs-dismiss="toast" aria-hidden="true"></i> </div> </div> </div> </div>
同时移除原来的$("#alert").load("/staticHtml/toast.html")代码。
方案3:在showToast中添加元素存在校验(兜底方案)
如果无法修改加载时序,可以在showToast函数中添加重试逻辑,确保元素存在后再执行操作:
function showToast(toastType, message) { function attemptShow() { const toastLiveExample = document.getElementById("liveToast"); const toastBody = document.getElementById("toastBody"); if (!toastLiveExample || !toastBody) { // 元素未加载完成,100ms后重试 setTimeout(attemptShow, 100); return; } const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample); toastLiveExample.classList.add(toastType); toastBody.innerHTML = message; toastBootstrap.show(); } attemptShow(); }
内容的提问来源于stack exchange,提问作者Shinpi Tekita
相关产品推荐
相关产品推荐

