【问题标题】:Round Progress Bar - CSS/JS圆形进度条 - CSS/JS
【发布时间】:2021-07-05 12:37:23
【问题描述】:

我有这个圆形进度条,显示已完成任务的进度。在进度更改时,条形图会在 0.5 秒内增加/减少。条形图本身由两半组成,因此在我的 JS 中,我必须添加一些额外的函数来延迟和更改转换时间,例如,如果总任务数不均匀。

现在,这一切都很好,直到我“重建”进度条(单击“重新加载”按钮),只需清空条形包装器并附加所有 div 和必要的数据以重新显示条形及其当前进步。此时,每当进度条到达中点时,由于某种原因,过渡并不像“重新加载”之前那样平滑,但是如果再次刷新页面,则过渡(在中点)一切正常。我不知道为什么会这样......

这是JSFiddle

更新 在JS的“on reload”中,忘记重新初始化“bar_transition = $('.circle .bar_transition .sub-progress')”

function updateSubtaskProgressBar(subs_completed, total_subs, progress_bar_transition, toggle, mod, reload_btn) {
  var left_side = $(".sub-progress-bar_transition .circle .left .sub-progress");
  var right_side = $(".sub-progress-bar_transition .circle .right .sub-progress");

  progress = subs_completed / total_subs * 360;
  transition = 500;
  delay = transition / 2;
  rot_reminder = 0;

  if (progress < 180) {
    
    rot_right = 0;

    right_side.css({
      'transform': 'rotate(' + rot_right + 'deg)'
    });

    rot_left = progress

    rot_reminder = 180 - rot_left
  
    if (rot_reminder != 0 && mod != 0 && toggle == 0) {

      progress_bar_transition.css({
        'transition': 'all ' + delay / 1000 + 's ease-in'
      });

      setTimeout(function () {
        progress_bar_transition.css({
          'transition': 'all ' + delay / 1000 + 's ease-out'
        });
        left_side.css({

          'transform': 'rotate(' + rot_left + 'deg)'
        });
      }, delay);

      toggle = 1 - toggle
      reload_btn.data('toggle', toggle)

    } else {
      progress_bar_transition.css({
        'transition': 'all ' + transition / 1000 + 's ease-in-out'
      });
      left_side.css({
        'transform': 'rotate(' + rot_left + 'deg)'
      });

    }

  } else {

    rot_left = 180;

    left_side.css({
      'transform': 'rotate(' + rot_left + 'deg)'
    });

    rot_right = progress - 180;

    rot_reminder = rot_right

    if (rot_reminder != 0 && mod != 0 && toggle == 1) {
      
      progress_bar_transition.css({
        'transition': 'all ' + delay / 1000 + 's ease-in'
      });

      setTimeout(function () {
        progress_bar_transition.css({
          'transition': 'all ' + delay / 1000 + 's ease-out'
        });
        right_side.css({

          'transform': 'rotate(' + rot_right + 'deg)'
        });
      }, delay);

      toggle = 1 - toggle
      reload_btn.data('toggle', toggle)

    } else {
      progress_bar_transition.css({
        'transition': 'all ' + transition / 1000 + 's ease-in-out'
      });
      right_side.css({
        'transform': 'rotate(' + rot_right + 'deg)'
      });
    }
  }
}

function setSubtaskProgressBar(subs_completed, total_subs, bar_transition) {

  modulo = 0;
  current_progress = 0;
  
  var left_side = $(".sub-progress-bar_transition .circle .left .sub-progress");
  var right_side = $(".sub-progress-bar_transition .circle .right .sub-progress");

  modulo = total_subs%2
  current_progress = subs_completed / total_subs * 360;

  var reload = $('.reload')
  reload.data('completed', subs_completed)
  reload.data('total', total_subs)
  reload.data('modulo', modulo)


  if (current_progress < 180) {

    rot_left = current_progress
    rot_right = 0

    left_side.css({
      'transform': 'rotate(' + rot_left + 'deg)'
    });

    reload.data('toggle', 1)

  } else {

    rot_left = 180
    rot_right = current_progress - 180

    left_side.css({
      'transform': 'rotate(' + rot_left + 'deg)'
    });

    right_side.css({
      'transform': 'rotate(' + rot_right + 'deg)'
    });

    reload.data('toggle', 0)

  }

  bar_transition.css({
    'transition': 'none'
  });
}


$(document).ready(function () {

  subs_completed = 3;
  total_subs = 5;

  bar_transition = $('.circle .bar_transition .sub-progress')
  
  number = $('.number')
  number.html(subs_completed + '/' + total_subs)

  setSubtaskProgressBar(subs_completed, total_subs, bar_transition)


  $(document).on('click', '.add', function () {
    subs_completed += 1
    $('.number').html(subs_completed + '/' + total_subs)

    reload = $('.reload')
    reload.data('completed', subs_completed)
    modulo = reload.data('modulo')
    toggle = reload.data('toggle')
    total = reload.data('total')

    updateSubtaskProgressBar(subs_completed, total, bar_transition, toggle, modulo, reload)
  })

  $(document).on('click', '.remove', function () {
    subs_completed -= 1;
    $('.number').html(subs_completed + '/' + total_subs)

    reload = $('.reload')
    reload.data('completed', subs_completed)
    modulo = reload.data('modulo')
    toggle = reload.data('toggle')
    total = reload.data('total')

    updateSubtaskProgressBar(subs_completed, total, bar_transition, toggle, modulo, reload)
  })


  $(document).on('click', '.reload', function () {

    num = $(this).data('completed') + '/' + $(this).data('total')

    data = '<div class="subtask-circular-progress sub-progress-bar_transition" data-completed="'+$(this).data('completed')+'" data-total="'+$(this).data('total')+'" data-modulo="'+$(this).data('modulo')+'" data-toggle="'+$(this).data('toggle')+'"><div class="inner"></div><div class="number">'+num+'</div><div class="circle"><div class="bar_transition left"><div class="sub-progress"></div></div><div class="bar_transition right"><div class="sub-progress"></div></div></div></div>'

    wrapper = $('.wrapper').empty();
    wrapper.append(data)


    setSubtaskProgressBar(subs_completed, total_subs, bar_transition) 

    console.log('reload')

  })

});
body{
    background-color: #333;
}

.subtask-circular-progress {
    position: absolute;
    left: 50%;
    top: 40%;
    height: 100px;
    width: 100px;
    background-color: red;
}

.subtask-circular-progress .inner {
    position: absolute;
    z-index: 6;
    top: 50%;
    left: 50%;
    height: 80px;
    width: 80px;
    margin: -40px 0 0 -40px;
    border-radius: 100%;
    background: #454545;
}

.subtask-circular-progress .number {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 10;
    font-size: 15px;
    font-weight: 500;
    color: white;
}

.subtask-circular-progress .bar_transition {
    position: absolute;
    height: 100%;
    width: 100%;
    background: #fff;
    -webkit-border-radius: 100%;
    border-radius: 100%;
    clip: rect(0px, 100px, 100px, 50px);
}

.circle .bar_transition .sub-progress {
    position: absolute;
    height: 100%;
    width: 100%;
    -webkit-border-radius: 100%;
    border-radius: 100%;
    clip: rect(0px, 50px, 100px, 0px);
    background: #4158d0;
    transition: all 0.5s ease-in-out;
}

.circle .left .sub-progress {
    transform: rotate(0deg);
}


.circle .right {
    transform: rotate(180deg);
    z-index: 3;

}

.circle .right .sub-progress {
    transform: rotate(0deg);
}

.buttons{
    position: absolute;
    left: 50%;
    top: 60%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="subtask-circular-progress sub-progress-bar_transition">
    <div class="inner"></div>
    <div class="number">100%</div>
    <div class="circle">
      <div class="bar_transition left">
        <div class="sub-progress"></div>
      </div>
      <div class="bar_transition right">
        <div class="sub-progress"></div>
      </div>
    </div>
  </div>
</div>
<div class="d-flex buttons">
  <button type="button" class="btn btn-success add">+</button>
  <button type="button" class="btn btn-success remove ms-4">-</button>
  <button type="button" class="btn btn-success reload ms-4" data-completed="" data-total="" data-modulo="" data-toggle="">reload</button>
</div>

【问题讨论】:

    标签: javascript html css progress-bar


    【解决方案1】:

    这个问题很难找到,但你指的是bar_transition全局变量,之后DOM的相关内容被删除了。

    替换DOM后,bar_transition的内容不再反映DOM,丢失了。

    需要手动更新变量的内容是reload回调:

    bar_transition = $('.circle .bar_transition .sub-progress');
    

    function updateSubtaskProgressBar(subs_completed, total_subs, progress_bar_transition, toggle, mod, reload_btn) {
      var left_side = $(".sub-progress-bar_transition .circle .left .sub-progress");
      var right_side = $(".sub-progress-bar_transition .circle .right .sub-progress");
    
      progress = subs_completed / total_subs * 360;
      transition = 500;
      delay = transition / 2;
      rot_reminder = 0;
    
      if (progress < 180) {
        
        rot_right = 0;
    
        right_side.css({
          'transform': 'rotate(' + rot_right + 'deg)'
        });
    
        rot_left = progress
    
        rot_reminder = 180 - rot_left
      
        if (rot_reminder != 0 && mod != 0 && toggle == 0) {
    
          progress_bar_transition.css({
            'transition': 'all ' + delay / 1000 + 's ease-in'
          });
    
          setTimeout(function () {
            progress_bar_transition.css({
              'transition': 'all ' + delay / 1000 + 's ease-out'
            });
            left_side.css({
    
              'transform': 'rotate(' + rot_left + 'deg)'
            });
          }, delay);
    
          toggle = 1 - toggle
          reload_btn.data('toggle', toggle)
    
        } else {
          progress_bar_transition.css({
            'transition': 'all ' + transition / 1000 + 's ease-in-out'
          });
          left_side.css({
            'transform': 'rotate(' + rot_left + 'deg)'
          });
    
        }
    
      } else {
    
        rot_left = 180;
    
        left_side.css({
          'transform': 'rotate(' + rot_left + 'deg)'
        });
    
        rot_right = progress - 180;
    
        rot_reminder = rot_right
    
        if (rot_reminder != 0 && mod != 0 && toggle == 1) {
          
          progress_bar_transition.css({
            'transition': 'all ' + delay / 1000 + 's ease-in'
          });
    
          setTimeout(function () {
            progress_bar_transition.css({
              'transition': 'all ' + delay / 1000 + 's ease-out'
            });
            right_side.css({
    
              'transform': 'rotate(' + rot_right + 'deg)'
            });
          }, delay);
    
          toggle = 1 - toggle
          reload_btn.data('toggle', toggle)
    
        } else {
          progress_bar_transition.css({
            'transition': 'all ' + transition / 1000 + 's ease-in-out'
          });
          right_side.css({
            'transform': 'rotate(' + rot_right + 'deg)'
          });
        }
      }
    }
    
    function setSubtaskProgressBar(subs_completed, total_subs, bar_transition) {
    
      modulo = 0;
      current_progress = 0;
      
      var left_side = $(".sub-progress-bar_transition .circle .left .sub-progress");
      var right_side = $(".sub-progress-bar_transition .circle .right .sub-progress");
    
      modulo = total_subs%2
      current_progress = subs_completed / total_subs * 360;
    
      var reload = $('.reload')
      reload.data('completed', subs_completed)
      reload.data('total', total_subs)
      reload.data('modulo', modulo)
    
    
      if (current_progress < 180) {
    
        rot_left = current_progress
        rot_right = 0
    
        left_side.css({
          'transform': 'rotate(' + rot_left + 'deg)'
        });
    
        reload.data('toggle', 1)
    
      } else {
    
        rot_left = 180
        rot_right = current_progress - 180
    
        left_side.css({
          'transform': 'rotate(' + rot_left + 'deg)'
        });
    
        right_side.css({
          'transform': 'rotate(' + rot_right + 'deg)'
        });
    
        reload.data('toggle', 0)
    
      }
    
      bar_transition.css({
        'transition': 'none'
      });
    }
    
    
    $(document).ready(function () {
    
      subs_completed = 3;
      total_subs = 5;
    
      bar_transition = $('.circle .bar_transition .sub-progress')
      
      number = $('.number')
      number.html(subs_completed + '/' + total_subs)
    
      setSubtaskProgressBar(subs_completed, total_subs, bar_transition)
    
    
      $(document).on('click', '.add', function () {
        subs_completed += 1
        $('.number').html(subs_completed + '/' + total_subs)
    
        reload = $('.reload')
        reload.data('completed', subs_completed)
        modulo = reload.data('modulo')
        toggle = reload.data('toggle')
        total = reload.data('total')
    
        updateSubtaskProgressBar(subs_completed, total, bar_transition, toggle, modulo, reload)
      })
    
      $(document).on('click', '.remove', function () {
        subs_completed -= 1;
        $('.number').html(subs_completed + '/' + total_subs)
    
        reload = $('.reload')
        reload.data('completed', subs_completed)
        modulo = reload.data('modulo')
        toggle = reload.data('toggle')
        total = reload.data('total')
    
        updateSubtaskProgressBar(subs_completed, total, bar_transition, toggle, modulo, reload)
      })
    
    
      $(document).on('click', '.reload', function () {
    
        num = $(this).data('completed') + '/' + $(this).data('total')
    
        data = '<div class="subtask-circular-progress sub-progress-bar_transition" data-completed="'+$(this).data('completed')+'" data-total="'+$(this).data('total')+'" data-modulo="'+$(this).data('modulo')+'" data-toggle="'+$(this).data('toggle')+'"><div class="inner"></div><div class="number">'+num+'</div><div class="circle"><div class="bar_transition left"><div class="sub-progress"></div></div><div class="bar_transition right"><div class="sub-progress"></div></div></div></div>'
    
        wrapper = $('.wrapper').empty();
        wrapper.append(data)
        
        // Fix is here!
        bar_transition = $('.circle .bar_transition .sub-progress');
    
        setSubtaskProgressBar(subs_completed, total_subs, bar_transition) 
    
        console.log('reload')
    
      })
    
    });
    body{
        background-color: #333;
    }
    
    .subtask-circular-progress {
        position: absolute;
        left: 50%;
        top: 40%;
        height: 100px;
        width: 100px;
        background-color: red;
    }
    
    .subtask-circular-progress .inner {
        position: absolute;
        z-index: 6;
        top: 50%;
        left: 50%;
        height: 80px;
        width: 80px;
        margin: -40px 0 0 -40px;
        border-radius: 100%;
        background: #454545;
    }
    
    .subtask-circular-progress .number {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        z-index: 10;
        font-size: 15px;
        font-weight: 500;
        color: white;
    }
    
    .subtask-circular-progress .bar_transition {
        position: absolute;
        height: 100%;
        width: 100%;
        background: #fff;
        -webkit-border-radius: 100%;
        border-radius: 100%;
        clip: rect(0px, 100px, 100px, 50px);
    }
    
    .circle .bar_transition .sub-progress {
        position: absolute;
        height: 100%;
        width: 100%;
        -webkit-border-radius: 100%;
        border-radius: 100%;
        clip: rect(0px, 50px, 100px, 0px);
        background: #4158d0;
        transition: all 0.5s ease-in-out;
    }
    
    .circle .left .sub-progress {
        transform: rotate(0deg);
    }
    
    
    .circle .right {
        transform: rotate(180deg);
        z-index: 3;
    
    }
    
    .circle .right .sub-progress {
        transform: rotate(0deg);
    }
    
    .buttons{
        position: absolute;
        left: 50%;
        top: 60%;
    }
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="wrapper">
      <div class="subtask-circular-progress sub-progress-bar_transition">
        <div class="inner"></div>
        <div class="number">100%</div>
        <div class="circle">
          <div class="bar_transition left">
            <div class="sub-progress"></div>
          </div>
          <div class="bar_transition right">
            <div class="sub-progress"></div>
          </div>
        </div>
      </div>
    </div>
    <div class="d-flex buttons">
      <button type="button" class="btn btn-success add">+</button>
      <button type="button" class="btn btn-success remove ms-4">-</button>
      <button type="button" class="btn btn-success reload ms-4" data-completed="" data-total="" data-modulo="" data-toggle="">reload</button>
    </div>

    【讨论】:

    • 是的,我正在查看 Js 代码并思考“就绪”函数中正在初始化的内容以及“重新加载”中的内容,然后我注意到“bar_transition”丢失了......无论如何感谢您的解决方案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-13
    • 2022-01-17
    • 2023-04-08
    相关资源
    最近更新 更多