web开发中,大家有可能经历过下面这种问题:
① 画面上通过setTimeout启动了一个定时器,用以动态更新画面上的某个组件(比如,1 秒刷新一次时间中的秒数)
② 当页面弹出一个模态对话框(通过 showModalDialog打开)时候,你会发现画面上的setTimeout失效了(比如,时间不再是一秒刷新一次了)
发生这个问题的原因大家可能都知道:模态对话框的特性导致了这个问题。在关闭模态对话框之前,用户无法将父窗口进行任何操作。而且Javascript又是单线程的,导致在模态对话框打开之后,被启动的setTimeout定时器,即时到了指定时间之后,也没有机会被执行。
那么,如果解决这个问题呢?
目前,我共找到两个解决方案,本篇blog中先描述方案一。下面开始。
方案一是采用 iframe 来实现的。
该方案的大体思路如下:
① 新建一个主HTML文件,如上面的index.html,该文件仅仅用于存放两个iframe,代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>setTimeout无效的解决方案(一)</title> </head> <body> <!-- 这个iframe用来显示画面内容 --> <div id="frameDiv1"> <iframe id="dlgFrame1" name="dlgFrame1" src="frame1.html" style="width: 100%; height: 100%; border: none;"></iframe> </div> <!-- 这个iframe仅仅用于打开模态对话框,所以将其隐藏 --> <div id="frameDiv2" style="display: none;"> <iframe id="dlgFrame2" name="dlgFrame2" src="frame2.html"></iframe> </div> </body> </html>
② 新建一个iframe,如上面的iframe1.html,此文件用来展示你想在画面上显示的东西,代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script> function start() { (event.target || event.srcElement)["disabled"] = true; setTimeout(function(){ document.querySelector("#txt").innerText = Math.random(); setTimeout(arguments.callee, 1000); }, 1000); } function dlgOpenButton() { // 获取iframe2的window对象,通过此window对象打开模态对话框 document.querySelector("#txt2").innerText = "模态画面打开中。。。"; var win = window.top.document.querySelector("#dlgFrame2").contentWindow; var val = win.showModalDialog("dialog.html",Math.random()); document.querySelector("#txt2").innerText = "模态画面关闭了,返回值为: " + val; // 如果是通过alert来打开的话,仍然是不行的。这个目前还无解。 //var val = win.alert("modal dialog"); //document.querySelector("#txt2").innerText = "模态画面关闭了,返回值为: " + val; } </script> </head> <body> <button type="button" onclick="start()">启动定时器</button> <button type="button" onclick="dlgOpenButton()">打开模态对话框</button> <div> <p style="float: left;">定时更新内容:</p> <p id="txt" style="float: left;"></p> </div> <div style="float: left; clear: left;"> <p style="float: left;">模态对话框状态:</p> <p id="txt2"></p> </div> </body> </html>
③ 新建另一个iframe,如上面的iframe2.html,此文件仅仅用于打开模态对话框,代码如下:
<!DOCTYPE html> <html> <head> </head> <body> </body> </html>
④ 最后,要打开的模态对话框的代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>我是模态对话框</title> <script> window.onload = function() { var para = window.dialogArguments; document.querySelector("#fromParent").innerText = para; }; window.onunload = function() { window.returnValue = Math.random(); }; </script> </head> <body> <div> <p>我是模态对话框,父画面传给我的值是: </p> <p id="fromParent"></p> </div> <br/> </body> </html>
上面将相关代码添完了,下面简单说一下此方案的思路:首先,我们是准备在iframe1里启动定时器的,所以,我们为了不让iframe1中的定时器失效,我们就不能再在iframe1中打开模态对话框,理由在上面已经描述过了。这样一来,我们只能寻找另外一种方案,使得能够打开模态对话框,同时又不阻断iframe1中的定时器。这样想的话,我们只好借用一下其他window对象,并调用其showModalDialog方法来打开模态对话框。所以,iframe2就派上用场了。即,在iframe1中,获取到iframe2的window对象,然后打开模态对话框,这种方式打开的模态对话框是不会阻断iframe1中的setTiemout的。
大家可以打开附件iframe.zip,然后运行其中的 index.html,如下图。然后先点击“启动定时器”按钮,然后再点击“打开模态对话框”按钮,观察一下画面,便可验证。
PS:
① 以上方案仅在IE10中进行过了验证。
② 对于alert之类的对话框上述方案无效。
相关推荐
总之,当模态对话框导致`setTimeout`失效时,理解其工作原理并采取适当的策略是关键。选择合适的解决方案取决于具体的应用场景和需求。通过灵活地应用上述方法,开发者可以确保代码的执行不受模态对话框的影响,从而...
由于非模态对话框不是由`DoModal`函数控制的,因此在对话框创建后,其对象可能会在其创建的函数执行完毕后被销毁,导致对话框消失。为了避免这种情况,非模态对话框对象应作为类成员变量或在堆上分配内存。对于后者...
这种差异导致了它们之间的一个重要区别:如果在对话框中需要较大的内存空间作为成员变量存储数据,那么在栈中创建可能会遇到问题,因为栈的空间是有限的。相比之下,在堆中创建的对话框不受此限制。 解决栈溢出的一...
模态对话框适用于需要用户集中注意力解决单一问题的情况,而非模态对话框则适合于不打断用户工作流程的多任务处理。通过JOptionPane和JDialog类,开发者可以方便地在Java应用程序中实现这两种对话框。在实际项目中,...
非模态对话框则通常需要保持一个对话框对象的指针,以便在需要时显示或更新其内容。 通过理解并掌握上述知识,你就能在ARX2008+VS2005环境中灵活地使用模态和非模态对话框,为CAD应用程序增加丰富的用户交互和控制...
### VC中模态对话框和非模态对话框的编程 #### 一、概述 对话框(Dialog)作为Windows应用程序中频繁使用的元素之一,主要用于接收用户的输入信息。在MFC框架下,对话框的功能被封装在`CDialog`类中,这是一个从`...
在QML(Qt Quick)中,自定义模态对话框是一种常见的需求,它允许开发者创建具有独特设计和功能的交互式界面元素。不同于标准的`Popup`组件,自定义模态对话框通常需要更高的定制性,以满足特定的用户体验或项目需求...
点击运行弹出一个对话框,点击DIALOG1按钮弹出一个模态对话框,在该对话框的编辑框输入文本点击确定该对话框消失且输入的文本被显示到主对话框MainDialog中,点击DAILOG2按钮弹出一个非模态对话框,操作现象和模态...
模态对话框是用户界面设计中的一个重要元素,它在应用程序中起到临时中断主窗口操作,迫使用户必须先处理对话框中的事务,才能继续进行其他操作的功能。这种对话框的特性使得用户不能忽视其存在,因此被称为“模态”...
在Windows应用程序开发中,Microsoft Foundation Class (MFC)库提供了一种高效且便捷的方式来创建用户界面,其中包括模态对话框和非模态对话框。这两种对话框在不同的场景下各有其用途,理解它们的工作原理和使用...
**模态对话框** 是一种阻塞用户界面的对话框,用户必须先关闭模态对话框才能继续与主窗口或其他窗口进行交互。在MFC中,模态对话框通常通过`CDialog`类的派生类创建,并使用`DoModal()`函数显示。例如,创建一个名为...
非模态对话框与模态对话框不同,在非模态对话框活动的同时,用户还可以在应用程序的其他地方工作,而模态对话框在其关闭之前,用户不能在同一个应用程序的其他地方工作。本例将从主框架窗口创建一个简单的非模态...
通常,当在主对话框的单击事件中直接创建并显示一个新的非模态对话框时,由于主线程会立即返回继续处理其他任务,导致新对话框可能在用户看到之前就被销毁,从而出现“一闪而逝”的情况。 为了解决这个问题,我们...
本话题关注的是如何在关闭子模态对话框后刷新其父模态对话框,这是一个典型的前端开发问题,主要涉及到JavaScript和可能的框架如jQuery、React、Vue或Angular等。 首先,我们需要理解模态对话框的工作原理。模态...
在Visual C++中,模态对话框是一种特殊类型的对话框,其消息处理机制与非模态对话框有所区别。模态对话框在被打开后,会暂时挂起其父窗口的消息处理,直至模态对话框被关闭。在模态对话框处于活动状态期间,应用程序...
MFC中经常会用到弹出模态或非模态对话框,模态对话框与非模态对话框容易混淆
模态对话框(Modal Dialog)是一种阻塞用户界面直至用户进行相应操作的对话框。在Android中,常见的模态对话框有AlertDialog、ProgressDialog等。它们会阻止用户与应用程序的其他部分进行交互,直到用户关闭对话框。...
总结来说,非模态对话框为用户提供了一种更加灵活的交互方式,但同时也需要开发者更加细致地处理用户界面的管理和控制。在实际开发过程中,还需要根据具体的应用场景和需求来进一步优化和完善。
首先,模态对话框是一种阻塞用户界面(UI)的对话框,用户必须先关闭它才能继续与应用程序的其他部分进行交互。在MFC中,我们可以使用`CDialog`类的派生类并重载`DoModal()`函数来创建模态对话框。以下是一般步骤: ...