点击按钮后Chatbot弹窗未显示问题排查求助
问题:Chatbot弹窗点击按钮无反应
跟随YouTube教程使用Python和JavaScript开发Chatbot,已在网站上实现聊天按钮,但点击后Chatbot弹窗未按预期显示。
相关代码
app.js
class Chatbox { constructor() { this.args = { openButton: document.querySelector(".chatbox__button"), sendButton: document.querySelector(".send__button"), }; this.state = false; this.messages = []; } toggleState(chatBox) { chatBox.classList.toggle("chatbox--active"); } onSendButton(chatBox) { var textField = chatBox.querySelector("input"); let text1 = textField.value; if (text1 === "") { return; } let msg1 = { name: "User", message: text1 }; this.messages.push(msg1); fetch($SCRIPT_ROOT + "/predict", { method: "POST", body: JSON.stringify({ message: text1 }), mode: "cors", headers: { "Content-Type": "application/json", }, }) .then((r) => r.json()) .then((r) => { let msg2 = { name: "Sam", message: r.answer }; this.messages.push(msg2); this.updateChatText(chatBox); textField.value = ""; }) .catch((error) => { console.error("Error:", error); this.updateChatText(chatBox); textField.value = ""; }); } updateChatText(chatBox) { var html = ""; this.messages .slice() .reverse() .forEach(function (item, index) { if (item.name === "Sam") { html += '<div class="messages__item messages__item--visitor">' + item.message + "</div>"; } else { html += '<div class="messages__item messages__item--operator">' + item.message + "</div>"; } }); const chatMessage = chatBox.querySelector(".chatbox__messages"); chatMessage.innerHTML = html; } display() { const { openButton, sendButton } = this.args; const chatBox = document.querySelector(".chatbox"); openButton.addEventListener("click", () => this.toggleState(chatBox)); sendButton.addEventListener("click", () => this.onSendButton(chatBox)); const inputNode = chatBox.querySelector("input"); inputNode.addEventListener("keyup", (event) => { if (event.key === "Enter") { this.onSendButton(chatBox); } }); } } const chatbox = new Chatbox(); chatbox.display();
base.html
<!DOCTYPE html> <html lang="en"> <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> <head> <meta charset="UTF-8"> <title>Chatbot</title> </head> <body> <div class="container"> <div class="chatbox"> <div class="chatbox__support"> <div class="chatbox__header"> <div class="chatbox__image--header"> <img src="https://img.icons8.com/color/48/000000/circled-user-female-skin-type-5--v1.png" alt="image"> </div> <div class="chatbox__content--header"> <h4 class="chatbox__heading--header">Chat support</h4> <p class="chatbox__description--header">Hi. My name is Sam. How can I help you?</p> </div> </div> <div class="chatbox__messages"> <div></div> </div> <div class="chatbox__footer"> <input type="text" placeholder="Write a message..."> <button class="chatbox__send--footer send__button">Send</button> </div> </div> <div class="chatbox__button"> <button><img src="{{ url_for('static', filename='images/chatbox-icon.svg') }}" /></button> </div> </div> </div> <script> var $SCRIPT_ROOT = "{{ request.script_root|tojson }}"; </script> <script type="text/javascript" src="{{ url_for('static', filename='app.js') }}"></script> </body> </html>
style.css
* { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Nunito', sans-serif; font-weight: 400; font-size: 100%; background: #F1F1F1; } *, html { --primaryGradient: linear-gradient(93.12deg, #581B98 0.52%, #9C1DE7 100%); --secondaryGradient: linear-gradient(268.91deg, #581B98 -2.14%, #9C1DE7 99.69%); --primaryBoxShadow: 0px 10px 15px rgba(0, 0, 0, 0.1); --secondaryBoxShadow: 0px -10px 15px rgba(0, 0, 0, 0.1); --primary: #581B98; } /* CHATBOX =============== */ .chatbox { position: absolute; bottom: 30px; right: 30px; } /* CONTENT IS CLOSE */ .chatbox__support { display: flex; flex-direction: column; background: #eee; width: 300px; height: 350px; z-index: -123456; opacity: 0; transition: all .5s ease-in-out; } /* CONTENT ISOPEN */ .chatbox--active { transform: translateY(-40px); z-index: 123456; opacity: 1; } /* BUTTON */ .chatbox__button { text-align: right; } .send__button { padding: 6px; background: transparent; border: none; outline: none; cursor: pointer; } /* HEADER */ .chatbox__header { position: sticky; top: 0; background: orange; } /* MESSAGES */ .chatbox__messages { margin-top: auto; display: flex; overflow-y: scroll; flex-direction: column-reverse; } .messages__item { background: orange; max-width: 60.6%; width: fit-content; } .messages__item--operator { margin-left: auto; } .messages__item--visitor { margin-right: auto; } /* FOOTER */ .chatbox__footer { position: sticky; bottom: 0; } .chatbox__support { background: #f9f9f9; height: 450px; width: 350px; box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.1); border-top-left-radius: 20px; border-top-right-radius: 20px; } /* HEADER */ .chatbox__header { background: var(--primaryGradient); display: flex; flex-direction: row; align-items: center; justify-content: center; padding: 15px 20px; border-top-left-radius: 20px; border-top-right-radius: 20px; box-shadow: var(--primaryBoxShadow); } .chatbox__image--header { margin-right: 10px; } .chatbox__heading--header { font-size: 1.2rem; color: white; } .chatbox__description--header { font-size: .9rem; color: white; } /* Messages */ .chatbox__messages { padding: 0 20px; } .messages__item { margin-top: 10px; background: #E0E0E0; padding: 8px 12px; max-width: 70%; } .messages__item--visitor, .messages__item--typing { border-top-left-radius: 20px; border-top-right-radius: 20px; border-bottom-right-radius: 20px; } .messages__item--operator { border-top-left-radius: 20px; border-top-right-radius: 20px; border-bottom-left-radius: 20px; background: var(--primary); color: white; } /* FOOTER */ .chatbox__footer { display: flex; flex-direction: row; align-items: center; justify-content: space-between; padding: 20px 20px; background: var(--secondaryGradient); box-shadow: var(--secondaryBoxShadow); border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; margin-top: 20px; } .chatbox__footer input { width: 80%; border: none; padding: 10px 10px; border-radius: 30px; text-align: left; } .chatbox__send--footer { color: white; } .chatbox__button button, .chatbox__button button:focus, .chatbox__button button:visited { padding: 10px; background: white; border: none; outline: none; border-top-left-radius: 50px; border-top-right-radius: 50px; border-bottom-left-radius: 50px; box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); cursor: pointer; }
问题原因分析
- 事件绑定目标错误:
openButton获取的是.chatbox__button容器div,实际可点击的是内部的<button>元素,点击div时事件未正确触发。 - CSS逻辑不匹配:当前代码给
.chatbox元素添加chatbox--active类,但控制弹窗显示的CSS样式是针对.chatbox__support的,没有关联父元素的激活状态,导致弹窗样式无变化。
解决建议
1. 修正事件绑定的目标元素
修改app.js中constructor里的openButton选择器,直接获取内部按钮:
this.args = { openButton: document.querySelector(".chatbox__button button"), sendButton: document.querySelector(".send__button"), };
2. 调整CSS样式关联父元素激活状态
替换原有的.chatbox--active样式块,改为通过父元素的激活状态控制子元素显示:
/* 当.chatbox激活时,控制内部的chatbox__support显示 */ .chatbox.chatbox--active .chatbox__support { transform: translateY(-40px); z-index: 123456; opacity: 1; }
移除原来独立的.chatbox--active样式,因为不需要给父元素本身设置这些样式。
3. 确保DOM加载完成后执行脚本(可选)
将初始化代码包裹在DOMContentLoaded事件监听中,避免DOM未加载完成时获取元素失败:
document.addEventListener('DOMContentLoaded', () => { const chatbox = new Chatbox(); chatbox.display(); });
内容的提问来源于stack exchange,提问作者user22081405
相关产品推荐
相关产品推荐

