Javascript-事件单击时在页面上加载/忙碌指示器或透明div

Javascript-事件单击时在页面上加载/忙碌指示器或透明div,javascript,css,Javascript,Css,我得到了一个客户端javascript函数,它在点击按钮时被触发(基本上,它是一个计算器!!)。有时,由于页面上有大量数据,javascript计算器函数会花费很长时间&这会让用户觉得页面不活动。我计划在整个页面上显示一个透明的div,可能在计算器功能结束之前在中间显示一个忙碌的指示器,这样用户就可以等待进程结束 function CalculateAmountOnClick() { // Display transparent div // MY time consuming loo

我得到了一个客户端javascript函数,它在点击按钮时被触发(基本上,它是一个计算器!!)。有时,由于页面上有大量数据,javascript计算器函数会花费很长时间&这会让用户觉得页面不活动。我计划在整个页面上显示一个透明的div,可能在计算器功能结束之前在中间显示一个忙碌的指示器,这样用户就可以等待进程结束

function CalculateAmountOnClick() { // Display transparent div // MY time consuming loop! { } // Remove transparent div } 函数CalculateAmountOnClick(){ //显示透明div //我耗时的循环! { } //删除透明div } 你有什么想法吗?当计算器函数启动时,我是否应该使用javascript将css类分配给div(它包围了我整个页面的内容)?我试过了,但没有得到想要的结果。在IE 6中面临透明度问题。另外,我将如何在这样一个透明的div中显示正在加载的消息+图像


TIA

我会做一些类似的事情:

  • 取消隐藏div(
    display:inline
  • 使
    位置为绝对位置
  • 给它一个
    z-index:99
  • 使高度和宽度
    100%
  • 处理完成后,设置
    显示:无
  • 要使其透明,您必须设置不透明度,这与Firefox、IE等不同


    要显示加载图标,您始终可以创建第二个div,并将其放置在页面上您想要的位置。加载完成后,将其与透明的一起移除。

    除上述所有内容外,不要忘记在垫片后面放置一个不可见的iframe,以便它显示在IE中的选择框上方

    编辑: 这个网站,虽然它提供了一个更复杂问题的解决方案,但确实涵盖了创建一个模态背景。

    对于加载消息,我将使用带有
    位置:绝对
    ,使用
    左侧
    顶部
    将其定位,并将显示设置为

    当您想要显示加载指示器时,必须使用超时,否则在处理完成之前,
    div
    不会显示。因此,您应该将代码修改为:

    function showLoadingIndicator()
    {
        // Display div by setting display to 'inline'
       setTimeout(CalculateAmountOnClick,0);
    }
    
    function CalculateAmountOnClick()
    {
      // MY time consuming loop!
        {
        }
      // Remove transparent div 
    }
    

    由于您设置了超时,因此页面将在耗时的循环发生之前重新绘制。

    Javascript显示窗帘:

    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
    });
    

    如果您使用的是js库,那么您可能需要查看一个现成的用于创建窗帘的解决方案。大多数库都应该有这些功能,它们可以帮助CSS。

    在我的例子中,第4点不起作用。通过jQuery,我将div中的宽度和高度设置为父级,所有这些都很好!。其他点完全可以!
    // 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);