我有一个客户端javascript函数,它是一个按钮点击触发(基本上,它是一个计算器!!).有时,由于页面上的大量数据,javascript计算器功能需要很长时间并使页面对用户显示为非活动状态.我打算在整个页面上显示一个透明的div,可能带有一个忙碌的指示器(在中间),直到计算器功能结束,这样用户就会等到过程结束.
function CalculateAmountOnClick() { // Display transparent div // MY time consuming loop! { } // Remove transparent div }
关于如何解决这个问题的任何想法?当我的计算器函数启动时,我应该使用javascript将div类分配给div(它包围我的整个页面的内容)吗?我试过了,但没有得到理想的结果.面对IE 6中的透明度问题.另外,我将如何在这样一个透明的div中显示加载消息+图像?
TIA
Javacript展示了一幕:
function CalculateAmountOnClick () { var curtain = document.body.appendChild( document.createElement('div') ); curtain.id = "curtain"; curtain.onkeypress = curtain.onclick = function(){ return false; } try { // your operations } finally { curtain.parentNode.removeChild( curtain ); } }
你的CSS:
#curtain { position: fixed; _position: absolute; z-index: 99; left: 0; top: 0; width: 100%; height: 100%; _height: expression(document.body.offsetHeight + "px"); background: url(curtain.png); _background: url(curtain.gif); }
(根据需要将MSIE 6下划线黑客移动到有条件包含的文件.)
您可以将其设置为窗帘的添加/删除功能,或者作为包装器:
function modalProcess( callback ) { var ret; var curtain = document.body.appendChild( document.createElement('div') ); curtain.id = "curtain"; curtain.onkeypress = curtain.onclick = function(){ return false; } try { ret = callback(); } finally { curtain.parentNode.removeChild( curtain ); } return ret; }
你可以这样打电话:
var result = modalProcess(function(){ // your operations here });
我将在这里做一些重要的假设,但是听起来我发生的事情是因为你在设置了幕布元素之后立即用强烈的处理直接锁定浏览器,浏览器从来没有机会画出窗帘.
每次更新DOM时,浏览器都不会重绘.看看你是否正在做更多的事情,然后画出所需要的东西(浏览器改变他们的方法)可能会很糟糕.因此,在这种情况下,只有在取下窗帘后才能刷新显示,或者您通过滚动强制重绘.
一个公平的警告:这种强烈的处理对你来说不是很好,因为它不仅会锁定你的页面.因为浏览器通常只为所有选项卡实现一个Javascript线程,所以您的处理将锁定所有打开的选项卡(=浏览器).此外,您冒着执行超时的风险,浏览器只是停止脚本(这可能低至5秒).
这是一种方法.
如果您可以将处理分解为较小的块,则可以使用超时运行它(以允许浏览器呼吸空间).这样的事情应该有效:
function processLoop( actionFunc, numTimes, doneFunc ) { var i = 0; var f = function () { if (i < numTimes) { actionFunc( i++ ); // closure on i setTimeout( f, 10 ) } else if (doneFunc) { doneFunc(); } }; f(); } // add a curtain here processLoop(function (i){ // loop code goes in here console.log('number: ', i); }, 10, // how many times to run loop function (){ // things that happen after the processing is done go here console.log('done!'); // remove curtain here });
这本质上是一个while循环,但是循环的每次迭代都是在一个定时间隔内完成的,因此浏览器有一点时间在两者之间呼吸.它会减慢处理速度,之后完成的任何工作都需要进入回调,因为循环独立于processLoop调用之后的运行.
另一个变化是设置窗帘,使用setTimeout调用处理函数以允许浏览器时间绘制窗帘,然后在完成后将其删除.
// add a curtain var curtain = document.body.appendChild( document.createElement('div') ); curtain.id = "curtain"; curtain.onkeypress = curtain.onclick = function(){ return false; } // delay running processing setTimeout(function(){ try { // here we go... myHeavyProcessingFunction(); } finally { // remove the curtain curtain.parentNode.removeChild( curtain ); } }, 40);
如果您使用的是js-library,您可能需要查看用于创建窗帘的现成解决方案.这些应该存在于大多数库中,这里有一个用于jQuery,它们可以帮助CSS.