【问题标题】:Vanilla Javascript Disable Button After Click With LocalStorage For X Seconds Then Enable Button Again使用 LocalStorage 单击 X 秒后,Vanilla Javascript 禁用按钮,然后再次启用按钮
【发布时间】:2020-11-08 13:35:03
【问题描述】:

你如何在 vanilla javascript 而不是 jQuery 中做这样的事情?

  1. 单击按钮提交刷新/重定向到同一页面的表单
  2. 页面刷新时,按钮被点击后禁用
  3. localStorage 将禁用的按钮存储 X 秒
  4. X 秒过后,再次启用禁用的按钮
  5. 如果用户再次单击按钮,请再次重复此过程

【问题讨论】:

    标签: javascript local-storage spam-prevention


    【解决方案1】:

    无法创建 sn-p,因为 stackoverlow 不允许访问 localStorage,但是:

    <form onsubmit="handleSubmit(event)">
        <input type="text" id="target" />
        <input type="submit" value="submit"/>
    </form>
    <script>
    
      let disable = localStorage.getItem("disable");
    
      if(disable){
        console.log("5 second timeout");
        setTimeout(()=> {
          localStorage.removeItem("disable");
          disable = false;
          console.log("button enabled");
        },5000);
      }
    
      function handleSubmit(e) {
        e.preventDefault();
        if(disable){
          console.log("button is disabled"); 
          return;
        }
        localStorage.setItem("disable",true);
        location.reload();    
      }
    
    </script>
    

    编辑:类似下面的内容会针对特定按钮修改它

    function handlerWrapper(e) {
        e.preventDefault();
        if(disable){
          console.log("button is disabled"); 
          return;
        }
        yourActualHandler(e); 
        localStorage.setItem("disable",true);
        location.reload();    
      }
    

    【讨论】:

    • 感谢您的回复!有没有办法在没有内联 javascript onsubmit="handleSubmit(event)" 的情况下遵循内容安全策略?也许访问特定的按钮 ID? Codepen 和其他 javascript 可共享链接应该可以访问 localStorage。否则我会测试它,让你知道它是怎么回事。
    • 这是一个跨域问题,因为沙盒,所以他们故意不允许这样做
    • 您的代码对于表单中只有一个按钮很有用,因此它可以帮助人们保持它。但它使用不利于内容安全策略的内联 javascript。如果表单中有多个按钮但只想禁用特定的一个怎么办?当我使用多个提交类型的按钮标签(不是输入标签)为我的用例尝试您的代码时,我的表单在第一次点击期间无法提交。但它确实添加到 localStorage 并且按钮无法单击 5 秒,这很好。也许也可以在您的答案中添加这种类型的用例。
    • 不需要内联;这样您就可以更轻松地复制和运行它。要定位单个按钮,您需要向该按钮传递一个执行上述操作的包装函数,然后在条件之后调用您想要的函数。
    • 好的,感谢您的编辑和解释!我会试一试,告诉你进展如何!
    【解决方案2】:

    除了你提到的localStorage API,你只需要按钮上的disabled 属性和窗口对象上的setTimeout 方法。

    请参阅代码内的 cmets 以获得进一步的解释。

    (注意:由于沙盒,使用localStorage 的代码无法在 SO sn-ps 中运行,但如果您想看到它运行,可以在文本编辑器中将其保存为 html 文件。)

    <button id="refresh">Refresh</button>
    <script>
      const refreshBtn = document.getElementById("refresh");
      refreshBtn.addEventListener("click", refresh);
      disable();
    
      function disable() {
        // If `disableRefresh` is truthy...
        if (localStorage.getItem("disableRefresh")) {
          // ...Disables the button and re-enables it after 2 seconds
          refreshBtn.setAttribute("disabled", ""); // Any value makes it true
          setTimeout(enable, 2000); // JavaScript measures times in milliseconds
        }
      }
    
      function enable() {
        // Removes (boolean) `disabled` attribute and (string) `disableRefresh` item
        refreshBtn.removeAttribute("disabled");
        localStorage.removeItem("disableRefresh")
      }
    
      function refresh() {
        // Sets `disableRefresh` to a truthy value, and refreshes the page
        localStorage.setItem("disableRefresh", "yep");
        location = location;
      };
    </script>
    

    【讨论】:

    • 您的代码似乎运行良好!我只是认为它不起作用,因为秒数太低了。增加他们的工作。但是,我遇到的一个问题是,当按钮操作仍在处理时,用户仍然可以在第一次单击按钮期间点击垃圾邮件。有没有办法在第一次点击后立即禁用按钮,同时表单正在处理,同时保留您的其余功能?
    • 当然,您只需将refreshBtn.setAttribute("disabled", ""); 添加为refresh 函数正文中的第一行...所以当单击该按钮时,它会立即变为禁用状态。
    • 虽然这样可行,但按钮并未完成对操作的处理,导致按钮无法发挥其主要用途。
    • 哦,我明白你的意思了。如果你只是把它放在refresh函数的底部呢?
    • 不用担心。我不知道您实际上可以单击编辑代码并查看修订。因此,如果有人需要解决您的解决方案,他们应该单击编辑按钮。感谢您提供的所有帮助!你让我找到了我正在寻找的答案:)
    猜你喜欢
    • 1970-01-01
    • 2021-09-10
    • 2012-06-11
    • 1970-01-01
    • 2016-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多