ShowModalDialog兼容Edge/Chrome故障:列表框选择弹窗修复求助
解决方案:替代废弃的showModalDialog,兼容Edge/Chrome
问题根源
现代浏览器(Edge、Chrome)已彻底移除原生showModalDialog API,第三方polyfill也未正确实现dialogArguments的双向数据传递,导致子页面中window.dialogArguments为undefined,触发Cannot set properties of undefined错误。
方案一:使用原生<dialog>元素(推荐)
原生<dialog>是现代浏览器支持的标准模态窗口方案,配合iframe加载Lookup页面,通过postMessage实现父子页面安全的数据传递。
1. 修改Select.aspx代码
添加模态对话框容器和调整点击事件逻辑:
<!-- 在页面任意位置添加dialog元素 --> <dialog id="lookupDialog" style="width:80em; height:50em; padding:0; border:none;"> <iframe id="lookupFrame" width="100%" height="100%" frameborder="0"></iframe> </dialog> <!-- 修改点击事件函数 --> <script> function btnSelectUniqueCondition_Click() { const dialog = document.getElementById('lookupDialog'); const frame = document.getElementById('lookupFrame'); // 监听子页面发来的选中数据 const handleMessage = (event) => { if (event.data.type === 'lookupSelected') { // 填充选中值到目标控件 document.getElementById('SelectItem_UniqueConditionPKId').value = event.data.selectedCode; document.getElementById('SelectItem_UniqueConditionSelect').click(); // 关闭对话框并清理监听 dialog.close(); window.removeEventListener('message', handleMessage); } }; window.addEventListener('message', handleMessage); // 加载Lookup页面并显示模态对话框 frame.src = 'LookupValue.aspx?Domain=7&Type=Unique'; dialog.showModal(); } </script>
2. 修改LookupValue.aspx.vb代码
将原dialogArguments传递逻辑替换为postMessage:
Private Sub grdLookupSelect_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles grdLookupSelect.ItemCommand Select Case (CType(e.CommandSource, LinkButton)).CommandName Case "Select" Dim selectedCode As String = HttpUtility.HtmlDecode(e.Item.Cells(0).Text) Dim selectedValue As String = HttpUtility.HtmlDecode(e.Item.Cells(1).Text) ' 向父页面发送选中数据(建议将*替换为你的应用实际域名,提升安全性) divScripts.InnerHtml = $"<script language=javascript> window.parent.postMessage({{ type: 'lookupSelected', selectedCode: '{HttpUtility.JavaScriptStringEncode(selectedCode)}', selectedValue: '{HttpUtility.JavaScriptStringEncode(selectedValue)}' }}, '*'); window.close(); </script>" Case Else ' Do nothing. End Select End Sub
方案二:使用window.open + postMessage
若无法使用<dialog>,可通过window.open打开子窗口,配合postMessage完成数据回传:
修改Select.aspx的点击事件函数
function btnSelectUniqueCondition_Click() { // 计算窗口居中位置 const width = 1280; // 对应80em的近似像素值 const height = 800; // 对应50em的近似像素值 const left = (window.screen.width - width) / 2; const top = (window.screen.height - height) / 2; // 打开子窗口 const lookupWindow = window.open( 'LookupValue.aspx?Domain=7&Type=Unique', 'LookupWindow', `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes` ); // 监听子页面消息 const handleMessage = (event) => { if (event.data.type === 'lookupSelected') { document.getElementById('SelectItem_UniqueConditionPKId').value = event.data.selectedCode; document.getElementById('SelectItem_UniqueConditionSelect').click(); lookupWindow.close(); window.removeEventListener('message', handleMessage); } }; window.addEventListener('message', handleMessage); }
LookupValue.aspx.vb的代码与方案一完全一致。
安全提示
postMessage的第二个参数(目标域名)建议替换为你的应用实际域名(如'https://your-app-domain.com'),避免任意域名接收消息带来的安全风险。
内容的提问来源于stack exchange,提问作者Sheik Umair
相关产品推荐
相关产品推荐

