BotFramework-WebChat在Shadow DOM中渲染时样式失效的问题排查与求助
BotFramework-WebChat在Shadow DOM中渲染时样式失效的问题排查与求助
我最近需要把BotFramework-WebChat嵌入到现有网站中,但为了避免WebChat的CSS样式泄露到主网站,或者主网站的样式影响WebChat,打算把它渲染到Shadow DOM里。
我查了相关的资料,GitHub上的Issue #5194提到了这个需求,而且PR #5196已经实现了Shadow DOM的支持,但官方并没有给出具体的使用教程。我尝试从PR里的单元测试代码去推断实现方式,但折腾了很久,WebChat始终没法正确渲染——组件能出来,但所有BotFramework自带的样式都不生效,完全是裸的HTML结构。
以下是我尝试实现的TypeScript核心代码:
export const startChat = async (serviceName: string, clientId?: string): Promise<void> => { const user = await requestToken(serviceName); if (user === null) return; webchatState.user = user; initializeDirectLine(); const shadowRoot = document.body.attachShadow({ mode: "open" }); const container = document.createElement("div"); container.id = "webchat"; shadowRoot.appendChild(container); const styleOptions: WebChat.IStyleOptions = { avatarBorderRadius: "50%", avatarSize: 40, botAvatarBackground: getCssVariableValue("--secondary"), botAvatarBackgroundColor: getCssVariableValue("--secondary"), botAvatarImage: chatbotAvatarImg, botAvatarInitials: "", bubbleBackground: getCssVariableValue("--primary"), bubbleBorderRadius: "15px", bubbleBorderStyle: "solid", bubbleBorderWidth: 1, bubbleFromUserBackground: getCssVariableValue("--secondary"), bubbleFromUserBorderColor: getCssVariableValue("--primary"), bubbleFromUserBorderRadius: "15px", bubbleFromUserBorderStyle: "solid", bubbleFromUserBorderWidth: 1, bubbleFromUserTextColor: getCssVariableValue("--text-secondary"), bubbleTextColor: getCssVariableValue("--secondary"), hideUploadButton: true, sendBoxBackground: "White", sendBoxBorderBottom: "", sendBoxBorderLeft: "", sendBoxBorderRight: "", sendBoxBorderTop: `solid 1px ${getCssVariableValue("--primary")}`, sendBoxButtonColor: getCssVariableValue("--primary"), sendBoxHeight: 40, sendBoxTextColor: "Black", stylesRoot: shadowRoot, userAvatarBackgroundColor: getCssVariableValue("--secondary"), userAvatarImage: userAvatarImg, userAvatarInitials: "", }; if (container !== null) { window.WebChat.renderWebChat( { directLine: webchatState.directLine, userID: webchatState.user.id, styleOptions, }, container ); } await sendClientIdActivity(clientId); await sendRequestWelcomeMessage(); await sendStartBot(); };
后来我调整了Shadow DOM容器的创建方式,改成这样:
const webchatHost = document.createElement("div"); webchatHost.id = "webchat-host"; const shadowRoot = webchatHost.attachShadow({ mode: "open" }); const webChatContainer = document.createElement("div"); webChatContainer.id = "webchat-container"; webChatContainer.style.height = "200px"; webChatContainer.style.width = "100%"; shadowRoot.appendChild(webChatContainer); document.body.appendChild(webchatHost);
调整后,WebChat的容器有了高度和宽度,但样式还是没生效——界面就是一堆无样式的文本和输入框,完全没有BotFramework默认的聊天窗口样式。而如果我不使用Shadow DOM,直接渲染到普通div里,WebChat就能正常显示所有样式,完全没问题。
我已经排查了这些点:
- 获取用户令牌、初始化DirectLine的流程都正常,能成功和Bot建立连接
- 引用的BotFramework-WebChat CDN是最新版本
- StyleOptions里的
stylesRoot参数已经正确传入了Shadow DOM的根节点,类型也符合定义 - 参考了GitHub Issue #5315里的实现方式,但还是同样的问题
- 确认不是DirectLine的问题,因为非Shadow DOM环境下完全正常
附我定义的IStyleOptions类型(和BotFramework仓库里的类型一致):
interface IStyleOptions { [index: string]: number | string | boolean | Node; avatarBorderRadius: string; avatarSize: number; botAvatarBackground: string; botAvatarBackgroundColor: string; botAvatarImage: string; botAvatarInitials: string; bubbleBackground: string; bubbleBorderRadius: string; bubbleBorderStyle: string; bubbleBorderWidth: number; bubbleFromUserBackground: string; bubbleFromUserBorderColor: string; bubbleFromUserBorderRadius: string; bubbleFromUserBorderStyle: string; bubbleFromUserBorderWidth: number; bubbleFromUserTextColor: string; bubbleTextColor: string; hideUploadButton: boolean; sendBoxBackground: string; sendBoxBorderBottom: string; sendBoxBorderLeft: string; sendBoxBorderRight: string; sendBoxBorderTop: string; sendBoxButtonColor: string; sendBoxHeight: number; sendBoxTextColor: string; stylesRoot: Node; userAvatarBackgroundColor: string; userAvatarImage: string; userAvatarInitials: string; }
有没有大佬成功在Shadow DOM里渲染过BotFramework-WebChat并且样式正常的?麻烦帮忙看看我的代码哪里有问题,或者有没有正确的实现步骤可以参考?
备注:内容来源于stack exchange,提问作者Dirk Odendaal
相关产品推荐
相关产品推荐

