【问题标题】:Jquery disable button on a synchronous call同步调用上的 Jquery 禁用按钮
【发布时间】:2017-07-13 02:34:00
【问题描述】:

我正在尝试禁用按钮以防止在同步 ajax 调用中多次单击。我的代码如下。

<!DOCTYPE html>
<html>
	<head>
	 <meta charset="UTF-8"> 
		<link type="text/css" rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700"> <!-- optional font -->
		<script  src="https://code.jquery.com/jquery-3.2.1.min.js"  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="  crossorigin="anonymous"></script>
   		<script type="text/javascript">
        $(document).ready(function(){
        	var test = false;
            $(document).on('click', '#test', function(e){
            	console.log(test);
            	if (test) {
            		return;
            	}
            	test = true;
                ajax_call();
  
            });

            function ajax_call() {
            	$.ajax({
                    contentType: 'application/json;charset=utf-8',
                    type: 'POST',
                    url: 'https://validdomain',
                    dataType: 'json',
                    xhrFields: {
                      withCredentials: true
                    },
                    crossDomain: true,
                    data: JSON.stringify({'test' : 'test'}),
                    success: function(data, textStatus, jqXHR) {
                        console.log(data);test =false;
                        copypaste();
                        test = false;
                    },
                    error: function(jqXHR, textStatus, errorThrown) { 
                        console.log(textStatus);
                        
                        test = false;
                    },
                    async: false,
                });
            }

            function copypaste() {
            	var tempInput = document.createElement("textarea");
                tempInput.setAttribute('id', 'copyid');
                tempInput.style = "position: absolute; left: -1000px; top: -1000px";
                tempInput.value = 'Text Copied';
                console.log(tempInput);
                document.body.appendChild(tempInput);
                tempInput.select();
                var result = document.execCommand('copy');
               	document.body.removeChild(tempInput);
                if (result) {
                    alert('copied');
                }
                else {
                	alert('not copied');
                }

                return result;
            }

        });
    </script>
	</head>
	<body>
		<input type="submit" id="test"/>
	</body>
</html>

但是我的按钮在第二次点击时没有被禁用(我得到了两次警报。)。如果我将 ajax 请求作为异步调用,则按钮被禁用。有什么方法可以在同步调用期间禁用我的按钮?

提前致谢!

【问题讨论】:

  • 永远不要使用async: false。这是一种糟糕的做法,并且已被浏览器供应商弃用。查看浏览器控制台中的警告
  • 另外,如果你使用同步 ajax,你就不必禁用按钮
  • 我知道这是一个糟糕的选择。但我使用它是因为 document.execCommand 如果它是从 ajax 回调函数触发的,它就不起作用。所以我必须使用 async:false 以便将我的 copypaste() 函数移到 ajax 之外。
  • @Musa '不必禁用按钮是什么意思?'。如果我不禁用它,那么如果任何用户单击该按钮两次,那么 Web 服务将被调用两次,这很糟糕。
  • 因为同步 ajax 锁定了 UI。

标签: javascript jquery ajax


【解决方案1】:

我添加了必要的语句,但您可以将它放在另一个地方,例如在 ajax 回调函数中。我也改了async: false

<!DOCTYPE html>
<html>
	<head>
	 <meta charset="UTF-8"> 
		<link type="text/css" rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700"> <!-- optional font -->
		<script  src="https://code.jquery.com/jquery-3.2.1.min.js"  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="  crossorigin="anonymous"></script>
   		<script type="text/javascript">
        $(document).ready(function(){
        	var test = false;
            $(document).on('click', '#test', function(e){
            	console.log(test);
            	if (test) {
            		return;
            	}
            	test = true;
                ajax_call();
                //Try adding this statement you can add wherever you want
                $(document).off('click', '#test');
  
            });

            function ajax_call() {
            	$.ajax({
                    contentType: 'application/json;charset=utf-8',
                    type: 'POST',
                    url: 'https://validdomain',
                    dataType: 'json',
                    xhrFields: {
                      withCredentials: true
                    },
                    crossDomain: true,
                    data: JSON.stringify({'test' : 'test'}),
                    success: function(data, textStatus, jqXHR) {
                        console.log(data);test =false;
                        copypaste();
                        test = false;
                    },
                    error: function(jqXHR, textStatus, errorThrown) { 
                        console.log(textStatus);
                        
                        test = false;
                    },
                    async: true,
                });
            }

            function copypaste() {
            	var tempInput = document.createElement("textarea");
                tempInput.setAttribute('id', 'copyid');
                tempInput.style = "position: absolute; left: -1000px; top: -1000px";
                tempInput.value = 'Text Copied';
                console.log(tempInput);
                document.body.appendChild(tempInput);
                tempInput.select();
                var result = document.execCommand('copy');
               	document.body.removeChild(tempInput);
                if (result) {
                    alert('copied');
                }
                else {
                	alert('not copied');
                }

                return result;
            }

        });
    </script>
	</head>
	<body>
		<input type="submit" id="test"/>
	</body>
</html>

【讨论】:

  • 正如我在我的问题中提到的,如果我使用异步调用,这非常好。但是如果从 ajax(成功/错误)回调函数触发 document.execCommand 则不起作用。所以我必须使用 async:false 以便将我的 copypaste() 函数移到 ajax 之外。
  • 是的,但我不喜欢这种方法,因为用户必须等到超时时间才能得到响应。另一个缺点是如果服务花费的时间比我们的超时时间长,那么逻辑就会出错。
  • 但是当他/她等待几秒钟时用户不会被冒犯,不用担心。您基本上可以添加加载屏幕
【解决方案2】:

为什么不简单地禁用按钮并重新启用它,而不是声明像 $("#test").attr('disabled','disabled') 这样的全局变量?变量范围在 javascript 中可能会变得棘手。

【讨论】:

  • 是的,我们可以做到。但这在同步调用中仍然不起作用。
【解决方案3】:

您碰巧在寻找像这样简单的东西吗?

PS:您必须自己输入ajax调用的详细信息。

html

<button id="button">Button</button>

jQuery/js

$("#button").click(function(){
   console.log("clicked");
   // deactivate button
   $("#button").attr("disabled", true);
   ajaxCall();

});

function ajaxCall(){
    $.ajax({
    //...ajax call here,
    complete: function(){
      // reactivate button after you receive any reply from ajax
      $("#button").attr("disabled", false);
    }
    })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多