【问题标题】:How to add a spinner icon to button when it's in the Loading state?处于加载状态时如何向按钮添加微调器图标?
【发布时间】:2013-01-25 10:43:00
【问题描述】:

Twitter Bootstrap's buttons 有一个不错的 Loading... 状态可用。

问题是它只是显示了一条像 Loading... 这样通过 data-loading-text 属性传递的消息,如下所示:

<button type="button" class="btn btn-primary start" id="btnStartUploads"
        data-loading-text="@Localization.Uploading">
    <i class="icon-upload icon-large"></i>
    <span>@Localization.StartUpload</span>
</button>

查看 Font Awesome,您会发现现在有一个 animated spinner icon

我尝试在触发 Upload 操作时集成该微调器图标,如下所示:

$("#btnStartUploads").button('loading');
$("#btnStartUploads i").removeAttr('class');
$("#btnStartUploads i").addClass('icon-spinner icon-spin icon-large');

但这根本没有效果,就是我只看到按钮上的Uploading...文字。

是否可以在按钮处于加载状态时添加图标?看起来 Bootstrap 只是在处于加载状态时删除了按钮内的图标 &lt;i class="icon-upload icon-large"&gt;&lt;/i&gt;


这是一个简单的demo,它显示了我上面描述的行为。如您所见,当它进入 Loading 状态时,图标就消失了。它会在时间间隔后立即重新出现。

【问题讨论】:

标签: button twitter-bootstrap icons loading font-awesome


【解决方案1】:

您可以使用 Bootstrap 微调器。使用“位置:绝对”使两个按钮相互重叠。使用 JavaScript 代码,您可以删除前面的按钮,然后将显示后面的按钮。

        button {
            position: absolute;
            top: 50px;
            left: 150px;
            width: 150px;
            font-size: 120%;
            padding: 5px;
            background: #B52519;
            color: #EAEAEA;
            border: none;
            margin: 120px;
            border-radius: 5px;
            display: flex;
            align-content: center;
            justify-content: center;
            transition: all 0.5s;
            height: 40px
        }

        #orderButton:hover {
            color: #c8c8c8;
        }
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<button><div class="spinner-border"></div></button>
<button id="orderButton" onclick="this.style.display= 'none';">Order!</button>

【讨论】:

    【解决方案2】:

    一个懒惰的方法是使用 UTF-8 实体代码半圆\25E0(又名&amp;#x25e0;),它看起来像◠,然后为它设置关键帧动画。很简单:

    .busy
    {
    animation: spin 1s infinite linear;
    display:inline-block;
    font-weight: bold;
    font-family: sans-serif;
    font-size: 35px;
    font-style:normal;
    color:#555;
    }
    
    .busy::before
    {
    content:"\25E0";
    }
    
    @keyframes spin
    {
    0% {transform: rotate(0deg);}
    100% {transform: rotate(359deg);}
    }
    &lt;i class="busy"&gt;&lt;/i&gt;

    【讨论】:

      【解决方案3】:

      我发现唯一有效的是这里的帖子: https://stackoverflow.com/a/44548729/9488229

      我对其进行了改进,现在它提供了所有这些功能:

      • 点击后禁用按钮
      • 使用原生引导显示动画加载图标
      • 页面加载完成后重新启用按钮
      • 页面加载完成后文本恢复原状

      Javascript:

      $(document).ready(function () {
          $('.btn').on('click', function() {
              var e=this;
              setTimeout(function() {
                  e.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Searching...';
                  e.disabled=true;
              },0);
              return true;
          });
      });
      

      【讨论】:

      • 欢迎来到 Stack Overflow。我没有看到您在哪里使用了 Andreas 使用的解决方案,并且我没有在提供的代码中看到按钮重新启用或恢复的位置。
      • 你说得对,这是另一个答案,我已经更新了链接。至于按钮如何重新启用,它可以工作。我认为这与它在 setTimeout() 函数内被禁用的事实有关,即当页面完成加载时,该函数内发生的所有事情都将被撤消。这是一个非常干净的解决方案。
      • 可能是 Bootstrap 正在处理重新启用和文本恢复。尝试在测试页面上不使用 Bootstrap JavaScript 运行此代码。
      • 使用表单提交按钮对我有用。
      【解决方案4】:

      这是一个受 Bulma 启发的成熟 css 解决方案。只需添加

          .button {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            position: relative;
            min-width: 200px;
            max-width: 100%;
            min-height: 40px;
            text-align: center;
            cursor: pointer;
          }
      
          @-webkit-keyframes spinAround {
            from {
              -webkit-transform: rotate(0deg);
              transform: rotate(0deg);
            }
            to {
              -webkit-transform: rotate(359deg);
              transform: rotate(359deg);
            }
          }
          @keyframes spinAround {
            from {
              -webkit-transform: rotate(0deg);
              transform: rotate(0deg);
            }
            to {
              -webkit-transform: rotate(359deg);
              transform: rotate(359deg);
            }
          }
      
          .button.is-loading {
            text-indent: -9999px;
            box-shadow: none;
            font-size: 1rem;
            height: 2.25em;
            line-height: 1.5;
            vertical-align: top;
            padding-bottom: calc(0.375em - 1px);
            padding-left: 0.75em;
            padding-right: 0.75em;
            padding-top: calc(0.375em - 1px);
            white-space: nowrap;
          }
      
          .button.is-loading::after  {
            -webkit-animation: spinAround 500ms infinite linear;
            animation: spinAround 500ms infinite linear;
            border: 2px solid #dbdbdb;
            border-radius: 290486px;
            border-right-color: transparent;
            border-top-color: transparent;
            content: "";
            display: block;
            height: 1em;
            position: relative;
            width: 1em;
          }
      

      【讨论】:

        【解决方案5】:

        这些是我的,基于纯 SVG 和 CSS 动画。不要关注下面sn-p中的JS代码,只是为了演示。随意根据我的情况制作您的自定义,这非常容易。

        var svg = d3.select("svg"),
            columnsCount = 3;
        
        ['basic', 'basic2', 'basic3', 'basic4', 'loading', 'loading2', 'spin', 'chrome', 'chrome2', 'flower', 'flower2', 'backstreet_boys'].forEach(function(animation, i){
          var x = (i%columnsCount+1) * 200-100,
              y = 20 + (Math.floor(i/columnsCount) * 200);
          
          
          svg.append("text")
            .attr('text-anchor', 'middle')
            .attr("x", x)
            .attr("y", y)
            .text((i+1)+". "+animation);
          
          svg.append("circle")
            .attr("class", animation)
            .attr("cx",  x)
            .attr("cy",  y+40)
            .attr("r",  16)
        });
        circle {
          fill: none;
          stroke: #bbb;
          stroke-width: 4
        }
        
        .basic {
          animation: basic 0.5s linear infinite;
          stroke-dasharray: 20 80;
        }
        
        @keyframes basic {
          0%    {stroke-dashoffset: 100;}
          100%  {stroke-dashoffset: 0;}
        }
        
        .basic2 {
          animation: basic2 0.5s linear infinite;
          stroke-dasharray: 80 20;
        }
        
        @keyframes basic2 {
          0%    {stroke-dashoffset: 100;}
          100%  {stroke-dashoffset: 0;}
        }
        
        .basic3 {
          animation: basic3 0.5s linear infinite;
          stroke-dasharray: 20 30;
        }
        
        @keyframes basic3 {
          0%    {stroke-dashoffset: 100;}
          100%  {stroke-dashoffset: 0;}
        }
        
        .basic4 {
          animation: basic4 0.5s linear infinite;
          stroke-dasharray: 10 23.3;
        }
        
        @keyframes basic4 {
          0%    {stroke-dashoffset: 100;}
          100%  {stroke-dashoffset: 0;}
        }
        
        .loading {
          animation: loading 1s linear infinite;
          stroke-dashoffset: 25;
        }
        
        @keyframes loading {
          0%    {stroke-dashoffset: 0;    stroke-dasharray: 50 0; }
          50%   {stroke-dashoffset: -100; stroke-dasharray: 0 50;}
          100%  { stroke-dashoffset: -200;stroke-dasharray: 50 0;}
        }
        
        .loading2 {
          animation: loading2 1s linear infinite;
        }
        
        @keyframes loading2 {
          0% {stroke-dasharray: 5 28.3;   stroke-dashoffset: 75;}
          50% {stroke-dasharray: 45 5;    stroke-dashoffset: -50;}
          100% {stroke-dasharray: 5 28.3; stroke-dashoffset: -125; }
        }
        
        .spin {
          animation: spin 1s linear infinite;
          stroke-dashoffset: 25;
        }
        
        @keyframes spin {
          0%    {stroke-dashoffset: 0;    stroke-dasharray: 33.3 0; }
          50%   {stroke-dashoffset: -100; stroke-dasharray: 0 33.3;}
          100%  { stroke-dashoffset: -200;stroke-dasharray: 33.3 0;}
        }
        
        .chrome {
          animation: chrome 2s linear infinite;
        }
        
        @keyframes chrome {
          0%    {stroke-dasharray: 0 100; stroke-dashoffset: 25;}
          25%   {stroke-dasharray: 75 25; stroke-dashoffset: 0;}
          50%   {stroke-dasharray: 0 100;  stroke-dashoffset: -125;}
          75%    {stroke-dasharray: 75 25; stroke-dashoffset: -150;}
          100%   {stroke-dasharray: 0 100; stroke-dashoffset: -275;}
        }
        
        .chrome2 {
          animation: chrome2 1s linear infinite;
        }
        
        @keyframes chrome2 {
          0%    {stroke-dasharray: 0 100; stroke-dashoffset: 25;}
          25%   {stroke-dasharray: 50 50; stroke-dashoffset: 0;}
          50%   {stroke-dasharray: 0 100;  stroke-dashoffset: -50;}
          75%   {stroke-dasharray: 50 50;  stroke-dashoffset: -125;}
          100%  {stroke-dasharray: 0 100;  stroke-dashoffset: -175;}
        }
        
        .flower {
          animation: flower 1s linear infinite;
        }
        
        @keyframes flower {
          0%    {stroke-dasharray: 0  20; stroke-dashoffset: 25;}
          50%   {stroke-dasharray: 20 0;  stroke-dashoffset: -50;}
          100%  {stroke-dasharray: 0 20;  stroke-dashoffset: -125;}
        }
        
        .flower2 {
          animation: flower2 1s linear infinite;
        }
        
        @keyframes flower2 {
          0%    {stroke-dasharray: 5 20;  stroke-dashoffset: 25;}
          50%   {stroke-dasharray: 20 5;  stroke-dashoffset: -50;}
          100%  {stroke-dasharray: 5 20;  stroke-dashoffset: -125;}
        }
        
        .backstreet_boys {
          animation: backstreet_boys 3s linear infinite;
        }
        
        @keyframes backstreet_boys {
          0%    {stroke-dasharray: 5 28.3;  stroke-dashoffset: -225;}
          15%    {stroke-dasharray: 5 28.3;  stroke-dashoffset: -300;}
          30%   {stroke-dasharray: 5 20;  stroke-dashoffset: -300;}
          45%    {stroke-dasharray: 5 20;  stroke-dashoffset: -375;}
          60%   {stroke-dasharray: 5 15;  stroke-dashoffset: -375;}
          75%    {stroke-dasharray: 5 15;  stroke-dashoffset: -450;}
          90%   {stroke-dasharray: 5 15;  stroke-dashoffset: -525;}
          100%   {stroke-dasharray: 5 28.3;  stroke-dashoffset: -925;}
        }
        <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
        <svg width="600px" height="700px"></svg>

        也可在 CodePen 上使用:https://codepen.io/anon/pen/PeRazr

        【讨论】:

          【解决方案6】:

          这是我的 Bootstrap 4 解决方案:

          <button id="search" class="btn btn-primary" 
          data-loading-text="<i class='fa fa-spinner fa-spin fa-fw' aria-hidden='true'></i>Searching">
            Search
          </button>
          
          var setLoading = function () {
            var search = $('#search');
            if (!search.data('normal-text')) {
              search.data('normal-text', search.html());
            }
            search.html(search.data('loading-text'));
          };
          
          var clearLoading = function () {
            var search = $('#search');
            search.html(search.data('normal-text'));
          };
          
          setInterval(() => {
            setLoading();
            setTimeout(() => {
              clearLoading();
            }, 1000);
          }, 2000);
          

          查看JSFiddle

          【讨论】:

            【解决方案7】:

            如果您查看bootstrap-button.js 源代码,您会看到引导插件在调用$(myElem).button('loading') 时将按钮内部html 替换为data-loading-text 中的任何内容。 p>

            对于你的情况,我认为你应该能够做到这一点:

            <button type="button"
                    class="btn btn-primary start"
                    id="btnStartUploads"
                    data-loading-text="<i class='icon-spinner icon-spin icon-large'></i> @Localization.Uploading">
                <i class="icon-upload icon-large"></i>
                <span>@Localization.StartUpload</span>
            </button>
            

            【讨论】:

            • 很好用 gurch101!我忘记了可以将HTML 与标签属性中的文本混合使用。 :-)
            • Fiddle 在 Mac OS X 上不适用于 Safari 6.0.5 (7536.30.1)、Chrome 31.0.1604.0 canary。
            • 已修复:jsfiddle.net/6U5q2/270 请注意,这是针对 v2.3.2 的。不知道它是否适用于 3.x
            • data-loading-text 自 v3.3.5 起已弃用,将在 v4 中删除。
            • @Jonathan 如果它在 v3.3.5 中被弃用,在 v3.3.5 和 v4 之后的替代品是什么?
            【解决方案8】:

            Bootstrap 3 使用 CSS3 动画的简单解决方案。

            在您的 CSS 中添加以下内容:

            .glyphicon.spinning {
                animation: spin 1s infinite linear;
                -webkit-animation: spin2 1s infinite linear;
            }
            
            @keyframes spin {
                from { transform: scale(1) rotate(0deg); }
                to { transform: scale(1) rotate(360deg); }
            }
            
            @-webkit-keyframes spin2 {
                from { -webkit-transform: rotate(0deg); }
                to { -webkit-transform: rotate(360deg); }
            }
            

            然后只需在加载时将spinning 类添加到glyphicon 即可获得旋转图标:

            <button class="btn btn-lg btn-warning">
                <span class="glyphicon glyphicon-refresh spinning"></span> Loading...    
            </button>
            

            基于http://www.bootply.com/128062#

            • 注意:IE9 及以下不支持 CSS3 动画。

            【讨论】:

            • 不应该是animation而不是-animation吗?
            • 优秀的解决方案。我在桌面和 iPad 上的 Safari 中遇到了这个动画的问题。它显示图标但不为其设置动画。有没有经历过这样的事情?
            • @JayhawksFan93 是的,我最近在 IE 中注意到了同样的情况。很快就会调查一下
            • 答案已更新为animation,而不是-animation。对我来说,FF 和 IE 的变化很好。 Firefox 的动画看起来不是很流畅。
            • +1。找到一个类似的here.... 发帖记录...
            【解决方案9】:

            要使@flion 的解决方案看起来很棒,您可以调整该图标的中心点,使其不会上下晃动。这看起来适合我的小字体:

            .glyphicon-refresh.spinning {
              transform-origin: 48% 50%;
            }
            

            【讨论】:

            • .glyphicon-refresh.spinning { transform-origin: 50% 58%; } 为我工作
            • 嗯,{ transform-origin: 50% 49%; } 在我使用 cog 的情况下解决。
            • 我也注意到了抖动,但更改这些数字的理由是什么?我应该如何调整它们?
            【解决方案10】:

            现在有一个成熟的插件:

            http://msurguy.github.io/ladda-bootstrap/

            【讨论】:

            • 嗨@Eru Penkman。你的和原来的有什么区别?
            • 嘿伊万,排序,但我从来没有时间更新我的 ladda 副本!这只是原版,我删除了我之前的评论。很抱歉!
            猜你喜欢
            • 2023-02-22
            • 2021-07-08
            • 1970-01-01
            • 2023-03-25
            • 2013-09-10
            • 2019-08-09
            • 1970-01-01
            • 2019-01-03
            • 1970-01-01
            相关资源
            最近更新 更多