【问题标题】:How could I make this active onclick?我怎样才能使这个活跃的点击?
【发布时间】:2019-06-10 22:56:55
【问题描述】:
var span = document.getElementById('loading_dots');

var int = setInterval(function() {
    if ((span.innerHTML += '●').length == 4) 
        span.innerHTML = '';
}, 400);

(function(){
    var loading_dots = document.getElementById("loading_dots"),

      show = function(){
        loading_dots.style.display = "block";
        setTimeout(hide, 5000); // 5 seconds
      },

      hide = function(){
        loading_dots.style.display = "none";
      };

    show();
})();

如何使 loading_dots 在单击按钮时启动,并在每次单击按钮时重新激活?最底层的功能是5秒后停止,也许可以合并成一个功能?

需要为 3 个单独的按钮工作并在单击每个按钮时重新启动,还需要在 <span class="loading_dots" id="loading_dots"></span> 内显示任何方法都可以,css、jquery 或 javascript

【问题讨论】:

  • 为什么你的大部分代码不使用 CSS?
  • 你有多个按钮吗?你有多个加载元素吗?如果有,它们之间有什么关系? 里面的点是按钮吗?里面有一些共同的父母吗?总体思路是什么?
  • 我有一些模态延迟加载 iframe,它们会在加载时调整模态的大小我想显示加载点,以便人们知道它没有完成加载,有时它需要几秒钟才能调整大小,例如3 个按钮未重新启动 jsfiddle.net/jqt6pugz
  • 啊,所以你有多个 Load 按钮,但只有一个“视觉元素”来描绘正在加载的东西
  • 没错!我将编辑问题以显示我希望它与多个按钮一起使用,我想我可以添加更多按钮 ID,它可以用于更多

标签: javascript html css arrays function


【解决方案1】:

这是一个 jQuery 版本:

(function ( $ ) {
 
    $.fn.loader = function( options ) {
      var settings = $.extend({
            text:"●",
            spn: undefined
        }, options );
        
        
        $.each(this, function(){
        var btn = this;      
        var int;
        var spn;
        if (settings.spn === undefined) {
         spn = $("<span/>" , { "class":"loading_dots" });
         $(btn).append(spn);
        } else {
          spn= $(settings.spn);
         }
         var show = function(){
         btn.setAttribute("disabled", "disabled")
         clearInterval(int);
         spn.show();
         int = setInterval(function() {
         if ((spn[0].innerHTML += settings.text).length == 4) 
           spn.html("");
        }, 400);
         setTimeout(hide, 5000); // 5 seconds
        }
        
        var hide = function (){
        spn.hide();
        btn.removeAttribute("disabled", "disabled")
        clearInterval(int);
        }
        
        btn.addEventListener("click", show);
       });
    };
 
}( jQuery ));

// now bind it by its class, this only need to be run once every time new button is added to the html
$(".btn").loader({spn:".loading_dots"});

// and you could also specify the text by 
// $(".btn").loader({text: "*"});
.loading_dots {
color:red;
display:none;
width:100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div>
<span class="loading_dots"></span>
<button class="btn" type="button" >
submit
</button>


<button class="btn" type="button" >
submit
</button>
</div>

【讨论】:

  • Jquery 很好,这段代码工作得很好,但是当我输入多个按钮 id 来启动它时它就不起作用了,我有 3 个单独的按钮需要激活点
  • cool,现在唯一的问题是它每次都必须显示在 内,是否容易将其移动到按钮上的 span 中显示?
  • 所以您希望所有按钮都只有一个跨度?还是每个按钮一个,但应该在按钮上方?
  • 您的代码运行良好,但不是在 loading_dots span 内显示点,而是在按钮中显示它们,每个按钮应仅在 loading_dots span 中显示点,span 是我网站中的 php 包含当每个模态打开时显示,但每个模态都是由不同的按钮单击触发的,您之前的代码显示跨度中的点很好,但新的加载点跨度丢失
  • 前面的代码很棒,只是对其他 2 个按钮不起作用,而这个对其他 2 个按钮起作用,但在 span 中不显示
【解决方案2】:

纯 JavaScript 版本,可选择以编程方式/手动停止显示加载点。只需传递您希望加载附加到的父元素的 id。默认情况下,加载将附加到父级,但您可以选择将对象作为带有position 属性的最后一个参数传递。

function removeLoading(id) {
  var parent = document.getElementById(id);
  var spans = parent.getElementsByClassName("loading_dots");
  while (spans.length > 0) {
    var span = spans[0];
    if (span.dataset.timerId) {
      clearTimeout(span.dataset.timerId);
    }
    span.remove();
  }
}

function addLoading(id, options) {
  options = options || {};
  var parent = document.getElementById(id);
  var existingSpans = parent.getElementsByClassName("loading_dots");
  if (existingSpans.length > 0) {
    removeLoading(id);
  }
  var span = document.createElement("span");
  span.setAttribute("class", "loading_dots");
  if (options.timerId) {
    span.dataset.timerId = options.timerId;
  }
  parent.insertAdjacentElement(options.position || "beforeend", span);
  setInterval(function () {
    if ((span.innerHTML += '●').length == 4)
      span.innerHTML = '';
  }, 400)
}

function addLoadingWithTimeout(id, ms, options) {
  options = options || {};
  var timerId = setTimeout(function () { removeLoading(id) }, ms);
  options.timerId = timerId;
  addLoading(id, options);
}
<p id="load1">Load 1 - Will stop automatically in 3 seconds after starting. </p>
<button onclick="addLoadingWithTimeout('load1', 3000)">Start Load 1</button>
<button onclick="removeLoading('load1')">Stop Load 1</button>

<p id="load2">Load 2 - Only manual Stop </p>
<button onclick="addLoading('load2')">Start Load 2</button>
<button onclick="removeLoading('load2')">Stop Load 2</button>

【讨论】:

    【解决方案3】:

    给你。在 HTML 方面,您只需将事件传递给您想要的按钮,然后将 id 作为字符串传递给您希望加载图标出现的 span/div。

    HTML:

      <button id="btn" onclick="load(event, 'loadDiv')">Load</button>
      <div>
        <span id="loadDiv"></span>    
      </div>
    

    下面,我们从事件中获取 btn id,因此您不必每次都手动传递它。然后我们为 innerhtml 图标定义函数。最后,我们每隔 0.4 秒运行一次 showIcon 函数,然后在 5 秒后清除间隔。

    JS:

    function load(e, location) {
      var btn = document.getElementById(e.srcElement.id)
      var loadDiv = document.getElementById(location)
    
      function showLoad() {
        if (loadDiv.innerHTML.length < 3) {
          return loadDiv.innerHTML += '●'
        }
        loadDiv.innerHTML = ''
      }
    
      (function() {
        var loadIcons = setInterval(function() {
          showLoad()
        }, 400)
    
        var clear = setTimeout(function() {
          clearInterval(loadIcons)
        }, 5000)
      })()
    }
    

    希望这会有所帮助!

    【讨论】:

      【解决方案4】:

      您可以在大部分代码中使用 CSS,而不是简单地在父 #loading 元素上切换 show 类:

      const Loading = () => {
        let tOut = null;
        const el = document.querySelector("#loading");
        const show = () => {
          el.classList.add('show');
          tOut = setTimeout(hide, 5000);
        };  
        const hide = () => {
          el.classList.remove('show');
          clearTimeout(tOut);
        };
        return {
          show,
          hide
        };
      };
      
      
      const loadingDots = Loading();
      const loadBtns = document.querySelectorAll('.load');
      
      [...loadBtns].forEach(el => el.addEventListener('click', loadingDots.show));
      // you can always use loadingDots.hide() to hide when needed (before the 5sec ticks out)
      #loading {
        position: fixed;
        z-index: 100;
        top:0;
        left: 0;
        width:100vw;
        height:100vh;
        display:flex;
        background: rgba(0,0,0,0.5);
        color: #fff;
        font-size: 3em;
        align-items: center;
        justify-content:center;
        visibility: hidden;
        opacity: 0;
        transition: 0.4s;
      }
      #loading.show {
        opacity: 1;
        visibility: visible;
      }
      @keyframes blink {
        50% {opacity: 1;}
      }
      #loading i:after {content: "\25cf";}
      #loading i { opacity: 0; animation: blink 1.2s infinite; }
      #loading i:nth-child(2) { animation-delay: .2s; }
      #loading i:nth-child(3) { animation-delay: .4s; }
      <div id="loading"><i></i><i></i><i></i></div>
      
      <button class="load">LOAD</button>
      <button class="load">LOAD</button>
      <button class="load">LOAD</button>

      【讨论】:

      • 如果这可以显示在 iframe 上而不是整个页面上,那将非常适合我正在尝试做的事情,这是一个简单的更改吗?
      • 试图应用它来查看它在 div 内部的样子,看起来不错,但只适用于一种模式,有什么线索吗?还注意到其他答案也仅适用于最接近页面顶部的模态,它会为该 1 个模态重新启动,但其他 2 个则没有
      • 可能需要找到最近的
        并激活?
      【解决方案5】:

      如果要为按钮单击添加事件监听器,只需选择按钮,然后循环添加监听器:

      document.querySelectorAll("button").forEach(e => e.addEventListener("click", myFunc));
      

      或者,监听任何点击,然后检查事件的目标是否是按钮:

      document.addEventListener("click", (e) => if (e.target.tagName == "BUTTON") myFunc());
      

      【讨论】:

        【解决方案6】:

        您可以在函数中定义代码并将点击处理程序添加到按钮。

        function myFunc() {
         var span = document.getElementById('loading_dots');
        
         var int = setInterval(function() {
             if ((span.innerHTML += '●').length == 4) 
                 span.innerHTML = '';
         }, 400);
        
         (function(){
             var loading_dots = document.getElementById("loading_dots"),
        
               show = function(){
                 loading_dots.style.display = "block";
                 setTimeout(hide, 5000); // 5 seconds
               },
        
               hide = function(){
                 loading_dots.style.display = "none";
               };
        
             show();
         })();
        }
        
        document.getElementById("myBtn1").addEventListener("click", myFunc); 
        document.getElementById("myBtn2").addEventListener("click", myFunc); 
        

        【讨论】:

        • 它的工作原理很棒,但你知道我怎样才能让它为超过 1 个按钮工作吗?所以当我点击另一个链接到 myFunc 的按钮时,它会重新启动?
        • 可以通过为每个按钮添加点击处理程序来添加多个按钮。试试看。我刚刚编辑了上面的答案。
        • 效果很好,但点击几次后点开始加速? jsfiddle.net/jqt6pugz/1
        • 您是否可以在单击一个按钮时禁用其他按钮。 jsfiddle.net/snehansh/9t1r5fev/4 。如果不是,我建议将超时逻辑放在单独的函数中,并在单击按钮后执行它,并使用标志来跟踪超时是否已过期。基本上我们不希望 timeout 运行不止一次,即使之前的 timeout 没有过期。
        猜你喜欢
        • 2020-05-18
        • 2020-10-04
        • 2017-08-20
        • 2021-02-02
        • 2023-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-14
        相关资源
        最近更新 更多