如何向head注入script标签并等待加载完成解决ZenDesk Widget zE未定义问题
解决方案
你遇到的报错是因为动态插入的script标签是异步加载的,插入标签后立刻执行zE相关逻辑时,Zendesk的脚本还没有完成下载、解析和初始化,zE对象还没有挂载到window上。
修复思路
- 新增重复加载判断,避免用户多次点击按钮重复插入脚本
- 监听script的
load事件,等脚本完全加载后再执行zE相关操作 - 兼容Zendesk组件初始化延迟的情况,避免脚本加载完成但组件未就绪的问题
$("#myHelpWidget").click(function () { // 防止重复加载脚本 if (document.getElementById('ze-snippet')) { // 已加载过直接打开组件 zE('webWidget', 'show'); zE('webWidget', 'open'); return; } // 提前配置zESettings,符合官方要求 window.zESettings = { webWidget: { authenticate: { jwtFn: function (callback) { $.ajax({ type: "POST", url: "/myaccount/jwtticket" }).done(function (data, textStatus, jqXHR) { callback(data.Token); }) } }, contactForm: { attachments: true, fields: [ { id: 'name', prefill: { '*': 'foo bar' } }, { id: 'email', prefill: { '*': 'foobar@example.com' } } ] } } }; // 动态创建script标签 var s = document.createElement('script'); s.id = "ze-snippet"; s.type = 'text/javascript'; s.src = "https://static.zdassets.com/ekr/snippet.js?key=xyz"; // 脚本加载完成后执行后续逻辑 s.onload = function () { // 轮询判断zE是否初始化完成,50ms间隔对性能无影响 const checkZeInterval = setInterval(() => { if (window.zE) { clearInterval(checkZeInterval); zE('webWidget', 'show'); zE('webWidget', 'open'); zE('webWidget:on', 'close', function () { zE('webWidget', 'hide'); }); } }, 50); }; var head = document.getElementsByTagName("head")[0]; head.appendChild(s); })
补充说明
上述方案已经覆盖了绝大多数场景,如果你希望去掉轮询逻辑,也可以替换为Zendesk官方提供的就绪事件监听,二者效果完全一致,稳定性没有差异。
内容的提问来源于stack exchange,提问作者LP13
相关产品推荐
相关产品推荐

