Outlook 发送时弹窗加载项在调整浏览器窗口大小时功能失效
浏览器调整窗口大小后脚本重新执行的原因
Outlook网页版的加载项运行在独立的iframe容器中,当浏览器窗口尺寸调整时,Outlook会触发整体布局重绘,直接销毁原有加载项iframe并重新创建加载,导致整个JS运行上下文被重置,所有内存中的全局变量(包括你定义的dialog)都会被清空,脚本重新从头执行。而你通过displayDialogAsync打开的对话框是独立于加载项iframe的顶层窗口/独立iframe,不会随加载项iframe销毁,因此会出现对话框残留、原有变量丢失无法操作的问题。
解决方案
- 优先做状态持久化处理
将对话框的关联状态存储在sessionStorage或localStorage中,每次脚本初始化(包括窗口调整后的重加载)时,先读取存储的状态,主动和已打开的对话框建立通信绑定,恢复dialog变量的操作能力。 - 增加对话框自清理逻辑
在对话框侧增加心跳检测机制,定期向父级加载项发送心跳消息,若多次未收到父级响应则判定父级已重置,主动执行关闭逻辑,避免出现无法操作的僵尸对话框。 - 增加代码容错处理
所有调用dialog变量的位置都先做非空判断,如果dialog为undefined,可以通过同域跨窗口广播(比如Broadcast Channel API)的方式通知所有已打开的对话框执行关闭操作,替代原有直接调用dialog.close()的逻辑。 - 修正现有代码的语法问题
你提供的示例代码存在参数顺序错误、括号不匹配的问题,先修正基础语法错误再做状态兼容处理,核心逻辑参考:Office.onReady(() => {}); let dialog = null; // 初始化时先检查是否有残留对话框 if (sessionStorage.getItem('dialogOpened') === 'true') { // 此处可发广播通知已有对话框重新绑定事件 } function openDialog(event) { Office.context.ui.displayDialogAsync(url, {height: 50, width: 50, displayInIframe: true}, function(asyncResult){ if (asyncResult.status === Office.AsyncResultStatus.Failed) { if (asyncResult.error.code == 12007) { // 先判断dialog是否存在,不存在就走广播关闭逻辑 if (dialog) { dialog.close(); } else { // 发送广播通知所有同域对话框关闭 } event.completed({allowEvent: false}); } } else { dialog = asyncResult.value; sessionStorage.setItem('dialogOpened', 'true'); dialog.addEventHandler(Office.EventType.DialogMessageReceived, doSomething); // 监听对话框关闭事件,清除存储状态 dialog.addEventHandler(Office.EventType.DialogEventReceived, () => { dialog = null; sessionStorage.removeItem('dialogOpened'); }); } } ); }
内容的提问来源于stack exchange,提问作者HA62481793
相关产品推荐
相关产品推荐

